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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-08-07 14:04:31 +0300
committerJulian Eisel <julian@blender.org>2020-08-07 14:04:31 +0300
commit0d2d4a6d4a75ac38c41f872c88255eab70e88ab7 (patch)
treeb7a7518af86dddba48e05a98b3c2be55e8804721 /source/blender
parent9b416c66fb714bdfd15a481489dbf650d0f389ea (diff)
parentcfc6f9eb18e701f5be601b95c45004e8cf7fbc81 (diff)
Merge branch 'master' into temp-ui-button-type-refactortemp-ui-button-type-refactor
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/CMakeLists.txt7
-rw-r--r--source/blender/blenfont/BLF_api.h5
-rw-r--r--source/blender/blenfont/intern/blf_font.c4
-rw-r--r--source/blender/blenfont/intern/blf_internal.h5
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h5
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h6
-rw-r--r--source/blender/blenkernel/BKE_action.h17
-rw-r--r--source/blender/blenkernel/BKE_addon.h5
-rw-r--r--source/blender/blenkernel/BKE_anim_data.h11
-rw-r--r--source/blender/blenkernel/BKE_anim_path.h5
-rw-r--r--source/blender/blenkernel/BKE_anim_visualization.h5
-rw-r--r--source/blender/blenkernel/BKE_animsys.h52
-rw-r--r--source/blender/blenkernel/BKE_appdir.h5
-rw-r--r--source/blender/blenkernel/BKE_armature.h27
-rw-r--r--source/blender/blenkernel/BKE_autoexec.h5
-rw-r--r--source/blender/blenkernel/BKE_blender.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_copybuffer.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_undo.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_user_menu.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h9
-rw-r--r--source/blender/blenkernel/BKE_blendfile.h5
-rw-r--r--source/blender/blenkernel/BKE_boids.h5
-rw-r--r--source/blender/blenkernel/BKE_bpath.h5
-rw-r--r--source/blender/blenkernel/BKE_brush.h5
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h5
-rw-r--r--source/blender/blenkernel/BKE_cachefile.h5
-rw-r--r--source/blender/blenkernel/BKE_callbacks.h5
-rw-r--r--source/blender/blenkernel/BKE_camera.h5
-rw-r--r--source/blender/blenkernel/BKE_ccg.h5
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h5
-rw-r--r--source/blender/blenkernel/BKE_cloth.h13
-rw-r--r--source/blender/blenkernel/BKE_collection.h12
-rw-r--r--source/blender/blenkernel/BKE_collision.h5
-rw-r--r--source/blender/blenkernel/BKE_colorband.h5
-rw-r--r--source/blender/blenkernel/BKE_colortools.h7
-rw-r--r--source/blender/blenkernel/BKE_constraint.h5
-rw-r--r--source/blender/blenkernel/BKE_context.h7
-rw-r--r--source/blender/blenkernel/BKE_crazyspace.h5
-rw-r--r--source/blender/blenkernel/BKE_curve.h13
-rw-r--r--source/blender/blenkernel/BKE_curveprofile.h7
-rw-r--r--source/blender/blenkernel/BKE_customdata.h6
-rw-r--r--source/blender/blenkernel/BKE_customdata_file.h5
-rw-r--r--source/blender/blenkernel/BKE_data_transfer.h5
-rw-r--r--source/blender/blenkernel/BKE_deform.h7
-rw-r--r--source/blender/blenkernel/BKE_displist.h5
-rw-r--r--source/blender/blenkernel/BKE_displist_tangent.h5
-rw-r--r--source/blender/blenkernel/BKE_duplilist.h7
-rw-r--r--source/blender/blenkernel/BKE_dynamicpaint.h5
-rw-r--r--source/blender/blenkernel/BKE_editlattice.h5
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h5
-rw-r--r--source/blender/blenkernel/BKE_editmesh_bvh.h5
-rw-r--r--source/blender/blenkernel/BKE_editmesh_cache.h5
-rw-r--r--source/blender/blenkernel/BKE_editmesh_tangent.h5
-rw-r--r--source/blender/blenkernel/BKE_effect.h5
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h14
-rw-r--r--source/blender/blenkernel/BKE_fcurve_driver.h8
-rw-r--r--source/blender/blenkernel/BKE_fluid.h13
-rw-r--r--source/blender/blenkernel/BKE_font.h5
-rw-r--r--source/blender/blenkernel/BKE_freestyle.h5
-rw-r--r--source/blender/blenkernel/BKE_global.h28
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h5
-rw-r--r--source/blender/blenkernel/BKE_gpencil_curve.h5
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h26
-rw-r--r--source/blender/blenkernel/BKE_gpencil_modifier.h5
-rw-r--r--source/blender/blenkernel/BKE_hair.h5
-rw-r--r--source/blender/blenkernel/BKE_icons.h5
-rw-r--r--source/blender/blenkernel/BKE_idprop.h5
-rw-r--r--source/blender/blenkernel/BKE_idtype.h25
-rw-r--r--source/blender/blenkernel/BKE_image.h34
-rw-r--r--source/blender/blenkernel/BKE_image_save.h5
-rw-r--r--source/blender/blenkernel/BKE_ipo.h5
-rw-r--r--source/blender/blenkernel/BKE_kelvinlet.h5
-rw-r--r--source/blender/blenkernel/BKE_key.h37
-rw-r--r--source/blender/blenkernel/BKE_keyconfig.h5
-rw-r--r--source/blender/blenkernel/BKE_lattice.h9
-rw-r--r--source/blender/blenkernel/BKE_layer.h5
-rw-r--r--source/blender/blenkernel/BKE_lib_id.h9
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h24
-rw-r--r--source/blender/blenkernel/BKE_lib_query.h5
-rw-r--r--source/blender/blenkernel/BKE_lib_remap.h5
-rw-r--r--source/blender/blenkernel/BKE_library.h5
-rw-r--r--source/blender/blenkernel/BKE_light.h5
-rw-r--r--source/blender/blenkernel/BKE_lightprobe.h5
-rw-r--r--source/blender/blenkernel/BKE_linestyle.h5
-rw-r--r--source/blender/blenkernel/BKE_main.h5
-rw-r--r--source/blender/blenkernel/BKE_main_idmap.h5
-rw-r--r--source/blender/blenkernel/BKE_mask.h5
-rw-r--r--source/blender/blenkernel/BKE_material.h8
-rw-r--r--source/blender/blenkernel/BKE_mball.h5
-rw-r--r--source/blender/blenkernel/BKE_mball_tessellate.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh.h11
-rw-r--r--source/blender/blenkernel/BKE_mesh_iterators.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_mapping.h7
-rw-r--r--source/blender/blenkernel/BKE_mesh_mirror.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_remap.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_remesh_voxel.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_runtime.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_tangent.h5
-rw-r--r--source/blender/blenkernel/BKE_mesh_wrapper.h5
-rw-r--r--source/blender/blenkernel/BKE_modifier.h5
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h10
-rw-r--r--source/blender/blenkernel/BKE_multires.h5
-rw-r--r--source/blender/blenkernel/BKE_nla.h5
-rw-r--r--source/blender/blenkernel/BKE_node.h41
-rw-r--r--source/blender/blenkernel/BKE_object.h35
-rw-r--r--source/blender/blenkernel/BKE_object_deform.h7
-rw-r--r--source/blender/blenkernel/BKE_object_facemap.h5
-rw-r--r--source/blender/blenkernel/BKE_ocean.h11
-rw-r--r--source/blender/blenkernel/BKE_outliner_treehash.h5
-rw-r--r--source/blender/blenkernel/BKE_packedFile.h5
-rw-r--r--source/blender/blenkernel/BKE_paint.h42
-rw-r--r--source/blender/blenkernel/BKE_particle.h13
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h8
-rw-r--r--source/blender/blenkernel/BKE_persistent_data_handle.hh129
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h12
-rw-r--r--source/blender/blenkernel/BKE_pointcloud.h5
-rw-r--r--source/blender/blenkernel/BKE_report.h5
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h5
-rw-r--r--source/blender/blenkernel/BKE_scene.h5
-rw-r--r--source/blender/blenkernel/BKE_screen.h15
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h22
-rw-r--r--source/blender/blenkernel/BKE_sequencer_offscreen.h5
-rw-r--r--source/blender/blenkernel/BKE_shader_fx.h5
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h5
-rw-r--r--source/blender/blenkernel/BKE_simulation.h27
-rw-r--r--source/blender/blenkernel/BKE_softbody.h5
-rw-r--r--source/blender/blenkernel/BKE_sound.h5
-rw-r--r--source/blender/blenkernel/BKE_speaker.h5
-rw-r--r--source/blender/blenkernel/BKE_studiolight.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_ccg.h23
-rw-r--r--source/blender/blenkernel/BKE_subdiv_deform.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_eval.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_foreach.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_mesh.h5
-rw-r--r--source/blender/blenkernel/BKE_subdiv_topology.h5
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h5
-rw-r--r--source/blender/blenkernel/BKE_text.h5
-rw-r--r--source/blender/blenkernel/BKE_text_suggestions.h5
-rw-r--r--source/blender/blenkernel/BKE_texture.h5
-rw-r--r--source/blender/blenkernel/BKE_tracking.h5
-rw-r--r--source/blender/blenkernel/BKE_undo_system.h5
-rw-r--r--source/blender/blenkernel/BKE_unit.h5
-rw-r--r--source/blender/blenkernel/BKE_volume.h5
-rw-r--r--source/blender/blenkernel/BKE_volume_render.h5
-rw-r--r--source/blender/blenkernel/BKE_workspace.h5
-rw-r--r--source/blender/blenkernel/BKE_world.h5
-rw-r--r--source/blender/blenkernel/BKE_writeavi.h5
-rw-r--r--source/blender/blenkernel/BKE_writeffmpeg.h5
-rw-r--r--source/blender/blenkernel/CMakeLists.txt29
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c181
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h5
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_inline.h5
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_intern.h5
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_legacy.c17
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_util.c2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c53
-rw-r--r--source/blender/blenkernel/intern/action.c70
-rw-r--r--source/blender/blenkernel/intern/anim_data.c128
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c198
-rw-r--r--source/blender/blenkernel/intern/anim_visualization.c6
-rw-r--r--source/blender/blenkernel/intern/appdir.c68
-rw-r--r--source/blender/blenkernel/intern/armature.c59
-rw-r--r--source/blender/blenkernel/intern/armature_deform.c18
-rw-r--r--source/blender/blenkernel/intern/armature_test.cc93
-rw-r--r--source/blender/blenkernel/intern/armature_update.c9
-rw-r--r--source/blender/blenkernel/intern/boids.c159
-rw-r--r--source/blender/blenkernel/intern/bpath.c96
-rw-r--r--source/blender/blenkernel/intern/brush.c67
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c22
-rw-r--r--source/blender/blenkernel/intern/cachefile.c2
-rw-r--r--source/blender/blenkernel/intern/cloth.c52
-rw-r--r--source/blender/blenkernel/intern/collection.c144
-rw-r--r--source/blender/blenkernel/intern/collision.c14
-rw-r--r--source/blender/blenkernel/intern/colortools.c2
-rw-r--r--source/blender/blenkernel/intern/constraint.c9
-rw-r--r--source/blender/blenkernel/intern/context.c5
-rw-r--r--source/blender/blenkernel/intern/curve.c334
-rw-r--r--source/blender/blenkernel/intern/curve_bevel.c272
-rw-r--r--source/blender/blenkernel/intern/curveprofile.c18
-rw-r--r--source/blender/blenkernel/intern/customdata.c171
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c4
-rw-r--r--source/blender/blenkernel/intern/data_transfer_intern.h5
-rw-r--r--source/blender/blenkernel/intern/deform.c4
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c38
-rw-r--r--source/blender/blenkernel/intern/editmesh_tangent.c4
-rw-r--r--source/blender/blenkernel/intern/effect.c4
-rw-r--r--source/blender/blenkernel/intern/fcurve.c15
-rw-r--r--source/blender/blenkernel/intern/fcurve_driver.c378
-rw-r--r--source/blender/blenkernel/intern/fcurve_test.cc213
-rw-r--r--source/blender/blenkernel/intern/fluid.c458
-rw-r--r--source/blender/blenkernel/intern/font.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil.c26
-rw-r--r--source/blender/blenkernel/intern/gpencil_curve.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c219
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c10
-rw-r--r--source/blender/blenkernel/intern/idtype.c33
-rw-r--r--source/blender/blenkernel/intern/image.c77
-rw-r--r--source/blender/blenkernel/intern/image_gpu.c774
-rw-r--r--source/blender/blenkernel/intern/key.c169
-rw-r--r--source/blender/blenkernel/intern/lattice.c4
-rw-r--r--source/blender/blenkernel/intern/lattice_deform.c4
-rw-r--r--source/blender/blenkernel/intern/layer.c34
-rw-r--r--source/blender/blenkernel/intern/lib_id.c64
-rw-r--r--source/blender/blenkernel/intern/lib_id_delete.c9
-rw-r--r--source/blender/blenkernel/intern/lib_intern.h5
-rw-r--r--source/blender/blenkernel/intern/lib_override.c471
-rw-r--r--source/blender/blenkernel/intern/lib_query.c3
-rw-r--r--source/blender/blenkernel/intern/light.c2
-rw-r--r--source/blender/blenkernel/intern/mask.c2
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c8
-rw-r--r--source/blender/blenkernel/intern/material.c42
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c14
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c4
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.c18
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c15
-rw-r--r--source/blender/blenkernel/intern/mesh_wrapper.c8
-rw-r--r--source/blender/blenkernel/intern/movieclip.c103
-rw-r--r--source/blender/blenkernel/intern/multires.c6
-rw-r--r--source/blender/blenkernel/intern/multires_inline.h5
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.h4
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_smooth.c2
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.c2
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.h5
-rw-r--r--source/blender/blenkernel/intern/node.c54
-rw-r--r--source/blender/blenkernel/intern/object.c201
-rw-r--r--source/blender/blenkernel/intern/object_deform.c2
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c79
-rw-r--r--source/blender/blenkernel/intern/ocean.c36
-rw-r--r--source/blender/blenkernel/intern/ocean_intern.h5
-rw-r--r--source/blender/blenkernel/intern/paint.c107
-rw-r--r--source/blender/blenkernel/intern/particle.c44
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c21
-rw-r--r--source/blender/blenkernel/intern/pbvh.c13
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h5
-rw-r--r--source/blender/blenkernel/intern/pointcache.c147
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c123
-rw-r--r--source/blender/blenkernel/intern/scene.c44
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c6
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c20
-rw-r--r--source/blender/blenkernel/intern/seqprefetch.c7
-rw-r--r--source/blender/blenkernel/intern/sequencer.c325
-rw-r--r--source/blender/blenkernel/intern/simulation.cc305
-rw-r--r--source/blender/blenkernel/intern/softbody.c19
-rw-r--r--source/blender/blenkernel/intern/sound.c2
-rw-r--r--source/blender/blenkernel/intern/studiolight.c1
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.c105
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter.h5
-rw-r--r--source/blender/blenkernel/intern/subdiv_inline.h5
-rw-r--r--source/blender/blenkernel/intern/tracking.c2
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c40
-rw-r--r--source/blender/blenkernel/intern/undo_system.c4
-rw-r--r--source/blender/blenkernel/intern/unit.c1
-rw-r--r--source/blender/blenkernel/intern/volume.cc49
-rw-r--r--source/blender/blenkernel/nla_private.h15
-rw-r--r--source/blender/blenkernel/particle_private.h5
-rw-r--r--source/blender/blenkernel/tracking_private.h5
-rw-r--r--source/blender/blenlib/BLI_alloca.h7
-rw-r--r--source/blender/blenlib/BLI_allocator.hh9
-rw-r--r--source/blender/blenlib/BLI_args.h5
-rw-r--r--source/blender/blenlib/BLI_array.h5
-rw-r--r--source/blender/blenlib/BLI_array.hh99
-rw-r--r--source/blender/blenlib/BLI_array_store.h5
-rw-r--r--source/blender/blenlib/BLI_array_store_utils.h5
-rw-r--r--source/blender/blenlib/BLI_array_utils.h5
-rw-r--r--source/blender/blenlib/BLI_asan.h5
-rw-r--r--source/blender/blenlib/BLI_assert.h48
-rw-r--r--source/blender/blenlib/BLI_astar.h5
-rw-r--r--source/blender/blenlib/BLI_bitmap.h5
-rw-r--r--source/blender/blenlib/BLI_bitmap_draw_2d.h5
-rw-r--r--source/blender/blenlib/BLI_blenlib.h7
-rw-r--r--source/blender/blenlib/BLI_boxpack_2d.h5
-rw-r--r--source/blender/blenlib/BLI_buffer.h5
-rw-r--r--source/blender/blenlib/BLI_color.hh40
-rw-r--r--source/blender/blenlib/BLI_compiler_attrs.h5
-rw-r--r--source/blender/blenlib/BLI_compiler_compat.h5
-rw-r--r--source/blender/blenlib/BLI_compiler_typecheck.h5
-rw-r--r--source/blender/blenlib/BLI_console.h5
-rw-r--r--source/blender/blenlib/BLI_convexhull_2d.h5
-rw-r--r--source/blender/blenlib/BLI_delaunay_2d.h5
-rw-r--r--source/blender/blenlib/BLI_dial_2d.h9
-rw-r--r--source/blender/blenlib/BLI_disjoint_set.hh103
-rw-r--r--source/blender/blenlib/BLI_dlrbTree.h5
-rw-r--r--source/blender/blenlib/BLI_dot_export.hh92
-rw-r--r--source/blender/blenlib/BLI_dot_export_attribute_enums.hh5
-rw-r--r--source/blender/blenlib/BLI_dynlib.h5
-rw-r--r--source/blender/blenlib/BLI_dynstr.h5
-rw-r--r--source/blender/blenlib/BLI_easing.h5
-rw-r--r--source/blender/blenlib/BLI_edgehash.h5
-rw-r--r--source/blender/blenlib/BLI_endian_switch_inline.h5
-rw-r--r--source/blender/blenlib/BLI_expr_pylike_eval.h5
-rw-r--r--source/blender/blenlib/BLI_fileops.h5
-rw-r--r--source/blender/blenlib/BLI_fileops_types.h5
-rw-r--r--source/blender/blenlib/BLI_float2.hh43
-rw-r--r--source/blender/blenlib/BLI_float3.hh46
-rw-r--r--source/blender/blenlib/BLI_float4x4.hh31
-rw-r--r--source/blender/blenlib/BLI_fnmatch.h5
-rw-r--r--source/blender/blenlib/BLI_ghash.h19
-rw-r--r--source/blender/blenlib/BLI_gsqueue.h5
-rw-r--r--source/blender/blenlib/BLI_hash.h5
-rw-r--r--source/blender/blenlib/BLI_hash.hh70
-rw-r--r--source/blender/blenlib/BLI_hash_md5.h5
-rw-r--r--source/blender/blenlib/BLI_hash_mm2a.h5
-rw-r--r--source/blender/blenlib/BLI_hash_mm3.h5
-rw-r--r--source/blender/blenlib/BLI_hash_tables.hh106
-rw-r--r--source/blender/blenlib/BLI_heap.h5
-rw-r--r--source/blender/blenlib/BLI_heap_simple.h5
-rw-r--r--source/blender/blenlib/BLI_index_mask.hh35
-rw-r--r--source/blender/blenlib/BLI_index_range.hh69
-rw-r--r--source/blender/blenlib/BLI_iterator.h5
-rw-r--r--source/blender/blenlib/BLI_jitter_2d.h5
-rw-r--r--source/blender/blenlib/BLI_kdopbvh.h7
-rw-r--r--source/blender/blenlib/BLI_kdtree.h5
-rw-r--r--source/blender/blenlib/BLI_lasso_2d.h5
-rw-r--r--source/blender/blenlib/BLI_linear_allocator.hh34
-rw-r--r--source/blender/blenlib/BLI_link_utils.h5
-rw-r--r--source/blender/blenlib/BLI_linklist.h6
-rw-r--r--source/blender/blenlib/BLI_linklist_lockfree.h5
-rw-r--r--source/blender/blenlib/BLI_linklist_stack.h5
-rw-r--r--source/blender/blenlib/BLI_listbase.h5
-rw-r--r--source/blender/blenlib/BLI_listbase_wrapper.hh11
-rw-r--r--source/blender/blenlib/BLI_map.hh184
-rw-r--r--source/blender/blenlib/BLI_map_slots.hh91
-rw-r--r--source/blender/blenlib/BLI_math.h5
-rw-r--r--source/blender/blenlib/BLI_math_base.h5
-rw-r--r--source/blender/blenlib/BLI_math_base_safe.h47
-rw-r--r--source/blender/blenlib/BLI_math_bits.h5
-rw-r--r--source/blender/blenlib/BLI_math_color.h13
-rw-r--r--source/blender/blenlib/BLI_math_color_blend.h5
-rw-r--r--source/blender/blenlib/BLI_math_geom.h22
-rw-r--r--source/blender/blenlib/BLI_math_inline.h5
-rw-r--r--source/blender/blenlib/BLI_math_interp.h5
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h7
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h5
-rw-r--r--source/blender/blenlib/BLI_math_solvers.h5
-rw-r--r--source/blender/blenlib/BLI_math_statistics.h5
-rw-r--r--source/blender/blenlib/BLI_math_vector.h8
-rw-r--r--source/blender/blenlib/BLI_memarena.h5
-rw-r--r--source/blender/blenlib/BLI_memblock.h5
-rw-r--r--source/blender/blenlib/BLI_memiter.h5
-rw-r--r--source/blender/blenlib/BLI_memory_utils.hh260
-rw-r--r--source/blender/blenlib/BLI_mempool.h5
-rw-r--r--source/blender/blenlib/BLI_multi_value_map.hh131
-rw-r--r--source/blender/blenlib/BLI_noise.h5
-rw-r--r--source/blender/blenlib/BLI_path_util.h5
-rw-r--r--source/blender/blenlib/BLI_polyfill_2d.h5
-rw-r--r--source/blender/blenlib/BLI_polyfill_2d_beautify.h5
-rw-r--r--source/blender/blenlib/BLI_probing_strategies.hh63
-rw-r--r--source/blender/blenlib/BLI_quadric.h5
-rw-r--r--source/blender/blenlib/BLI_rand.h11
-rw-r--r--source/blender/blenlib/BLI_rand.hh144
-rw-r--r--source/blender/blenlib/BLI_rect.h6
-rw-r--r--source/blender/blenlib/BLI_resource_collector.hh148
-rw-r--r--source/blender/blenlib/BLI_scanfill.h5
-rw-r--r--source/blender/blenlib/BLI_session_uuid.h68
-rw-r--r--source/blender/blenlib/BLI_set.hh169
-rw-r--r--source/blender/blenlib/BLI_set_slots.hh77
-rw-r--r--source/blender/blenlib/BLI_smallhash.h5
-rw-r--r--source/blender/blenlib/BLI_sort.h5
-rw-r--r--source/blender/blenlib/BLI_sort_utils.h5
-rw-r--r--source/blender/blenlib/BLI_span.hh203
-rw-r--r--source/blender/blenlib/BLI_stack.h5
-rw-r--r--source/blender/blenlib/BLI_stack.hh56
-rw-r--r--source/blender/blenlib/BLI_strict_flags.h5
-rw-r--r--source/blender/blenlib/BLI_string.h5
-rw-r--r--source/blender/blenlib/BLI_string_cursor_utf8.h5
-rw-r--r--source/blender/blenlib/BLI_string_ref.hh70
-rw-r--r--source/blender/blenlib/BLI_string_utf8.h5
-rw-r--r--source/blender/blenlib/BLI_string_utils.h5
-rw-r--r--source/blender/blenlib/BLI_sys_types.h5
-rw-r--r--source/blender/blenlib/BLI_system.h5
-rw-r--r--source/blender/blenlib/BLI_threads.h7
-rw-r--r--source/blender/blenlib/BLI_timecode.h5
-rw-r--r--source/blender/blenlib/BLI_timeit.hh13
-rw-r--r--source/blender/blenlib/BLI_timer.h5
-rw-r--r--source/blender/blenlib/BLI_utildefines.h47
-rw-r--r--source/blender/blenlib/BLI_utildefines_iter.h5
-rw-r--r--source/blender/blenlib/BLI_utildefines_stack.h5
-rw-r--r--source/blender/blenlib/BLI_utildefines_variadic.h5
-rw-r--r--source/blender/blenlib/BLI_utility_mixins.hh5
-rw-r--r--source/blender/blenlib/BLI_uvproject.h7
-rw-r--r--source/blender/blenlib/BLI_vector.hh236
-rw-r--r--source/blender/blenlib/BLI_vector_adaptor.hh102
-rw-r--r--source/blender/blenlib/BLI_vector_set.hh131
-rw-r--r--source/blender/blenlib/BLI_vector_set_slots.hh29
-rw-r--r--source/blender/blenlib/BLI_vfontdata.h5
-rw-r--r--source/blender/blenlib/BLI_voronoi_2d.h5
-rw-r--r--source/blender/blenlib/BLI_voxel.h16
-rw-r--r--source/blender/blenlib/BLI_winstuff.h5
-rw-r--r--source/blender/blenlib/CMakeLists.txt39
-rw-r--r--source/blender/blenlib/PIL_time.h5
-rw-r--r--source/blender/blenlib/PIL_time_utildefines.h5
-rw-r--r--source/blender/blenlib/intern/BLI_args.c8
-rw-r--r--source/blender/blenlib/intern/BLI_assert.c51
-rw-r--r--source/blender/blenlib/intern/BLI_dial_2d.c2
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c42
-rw-r--r--source/blender/blenlib/intern/BLI_ghash_utils.c19
-rw-r--r--source/blender/blenlib/intern/BLI_index_range.cc22
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c161
-rw-r--r--source/blender/blenlib/intern/BLI_linklist.c12
-rw-r--r--source/blender/blenlib/intern/BLI_memiter.c16
-rw-r--r--source/blender/blenlib/intern/DLRB_tree.c8
-rw-r--r--source/blender/blenlib/intern/array_store.c26
-rw-r--r--source/blender/blenlib/intern/array_utils.c2
-rw-r--r--source/blender/blenlib/intern/bitmap_draw_2d.c28
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c8
-rw-r--r--source/blender/blenlib/intern/convexhull_2d.c17
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.c56
-rw-r--r--source/blender/blenlib/intern/dot_export.cc42
-rw-r--r--source/blender/blenlib/intern/easing.c35
-rw-r--r--source/blender/blenlib/intern/edgehash.c14
-rw-r--r--source/blender/blenlib/intern/expr_pylike_eval.c92
-rw-r--r--source/blender/blenlib/intern/fileops.c23
-rw-r--r--source/blender/blenlib/intern/lasso_2d.c7
-rw-r--r--source/blender/blenlib/intern/listbase.c5
-rw-r--r--source/blender/blenlib/intern/math_base_safe_inline.c79
-rw-r--r--source/blender/blenlib/intern/math_color.c18
-rw-r--r--source/blender/blenlib/intern/math_geom.c676
-rw-r--r--source/blender/blenlib/intern/math_matrix.c2
-rw-r--r--source/blender/blenlib/intern/math_rotation.c30
-rw-r--r--source/blender/blenlib/intern/math_vector.c20
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c16
-rw-r--r--source/blender/blenlib/intern/noise.c4
-rw-r--r--source/blender/blenlib/intern/path_util.c75
-rw-r--r--source/blender/blenlib/intern/polyfill_2d.c14
-rw-r--r--source/blender/blenlib/intern/polyfill_2d_beautify.c15
-rw-r--r--source/blender/blenlib/intern/quadric.c10
-rw-r--r--source/blender/blenlib/intern/rand.cc (renamed from source/blender/blenlib/intern/rand.c)235
-rw-r--r--source/blender/blenlib/intern/rct.c202
-rw-r--r--source/blender/blenlib/intern/scanfill.c96
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c5
-rw-r--r--source/blender/blenlib/intern/session_uuid.c78
-rw-r--r--source/blender/blenlib/intern/smallhash.c7
-rw-r--r--source/blender/blenlib/intern/sort_utils.c42
-rw-r--r--source/blender/blenlib/intern/storage.c21
-rw-r--r--source/blender/blenlib/intern/string.c32
-rw-r--r--source/blender/blenlib/intern/string_utf8.c8
-rw-r--r--source/blender/blenlib/intern/string_utils.c2
-rw-r--r--source/blender/blenlib/intern/system.c6
-rw-r--r--source/blender/blenlib/intern/task_range.cc2
-rw-r--r--source/blender/blenlib/intern/threads.cc18
-rw-r--r--source/blender/blenlib/intern/timecode.c4
-rw-r--r--source/blender/blenlib/intern/timeit.cc6
-rw-r--r--source/blender/blenlib/intern/uvproject.c2
-rw-r--r--source/blender/blenlib/intern/voronoi_2d.c2
-rw-r--r--source/blender/blenlib/intern/voxel.c13
-rw-r--r--source/blender/blenlib/tests/BLI_array_test.cc176
-rw-r--r--source/blender/blenlib/tests/BLI_disjoint_set_test.cc36
-rw-r--r--source/blender/blenlib/tests/BLI_edgehash_test.cc408
-rw-r--r--source/blender/blenlib/tests/BLI_index_mask_test.cc43
-rw-r--r--source/blender/blenlib/tests/BLI_index_range_test.cc143
-rw-r--r--source/blender/blenlib/tests/BLI_linear_allocator_test.cc118
-rw-r--r--source/blender/blenlib/tests/BLI_map_test.cc590
-rw-r--r--source/blender/blenlib/tests/BLI_math_base_safe_test.cc37
-rw-r--r--source/blender/blenlib/tests/BLI_memory_utils_test.cc159
-rw-r--r--source/blender/blenlib/tests/BLI_multi_value_map_test.cc109
-rw-r--r--source/blender/blenlib/tests/BLI_set_test.cc565
-rw-r--r--source/blender/blenlib/tests/BLI_span_test.cc311
-rw-r--r--source/blender/blenlib/tests/BLI_stack_cxx_test.cc188
-rw-r--r--source/blender/blenlib/tests/BLI_string_ref_test.cc277
-rw-r--r--source/blender/blenlib/tests/BLI_vector_set_test.cc164
-rw-r--r--source/blender/blenlib/tests/BLI_vector_test.cc639
-rw-r--r--source/blender/blenloader/BLO_blend_defs.h5
-rw-r--r--source/blender/blenloader/BLO_blend_validate.h5
-rw-r--r--source/blender/blenloader/BLO_read_write.h7
-rw-r--r--source/blender/blenloader/BLO_readfile.h5
-rw-r--r--source/blender/blenloader/BLO_undofile.h5
-rw-r--r--source/blender/blenloader/BLO_writefile.h5
-rw-r--r--source/blender/blenloader/CMakeLists.txt2
-rw-r--r--source/blender/blenloader/intern/readblenentry.c23
-rw-r--r--source/blender/blenloader/intern/readfile.c427
-rw-r--r--source/blender/blenloader/intern/readfile.h20
-rw-r--r--source/blender/blenloader/intern/versioning_250.c8
-rw-r--r--source/blender/blenloader/intern/versioning_260.c4
-rw-r--r--source/blender/blenloader/intern/versioning_270.c2
-rw-r--r--source/blender/blenloader/intern/versioning_280.c16
-rw-r--r--source/blender/blenloader/intern/versioning_290.c170
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c8
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c6
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c6
-rw-r--r--source/blender/blenloader/intern/writefile.c61
-rw-r--r--source/blender/blentranslation/BLT_lang.h5
-rw-r--r--source/blender/blentranslation/BLT_translation.h5
-rw-r--r--source/blender/bmesh/CMakeLists.txt6
-rw-r--r--source/blender/bmesh/bmesh.h6
-rw-r--r--source/blender/bmesh/bmesh_class.h5
-rw-r--r--source/blender/bmesh/bmesh_tools.h7
-rw-r--r--source/blender/bmesh/intern/bmesh_callback_generic.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c9
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_delete.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_error.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_inline.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators_inline.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_log.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c21
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_convert.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_duplicate.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_validate.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c11
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api_inline.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h11
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_private.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_query.c31
-rw-r--r--source/blender/bmesh/intern/bmesh_query.h8
-rw-r--r--source/blender/bmesh/intern/bmesh_query_inline.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_query_uv.c169
-rw-r--r--source/blender/bmesh/intern/bmesh_query_uv.h55
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_structure_inline.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_private.h5
-rw-r--r--source/blender/bmesh/operators/bmo_beautify.c5
-rw-r--r--source/blender/bmesh/operators/bmo_bevel.c4
-rw-r--r--source/blender/bmesh/operators/bmo_create.c2
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c9
-rw-r--r--source/blender/bmesh/tools/bmesh_beautify.c9
-rw-r--r--source/blender/bmesh/tools/bmesh_beautify.h8
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c364
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.h7
-rw-r--r--source/blender/bmesh/tools/bmesh_bisect_plane.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_edgenet.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_edgesplit.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect_edges.c24
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect_edges.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_path.c126
-rw-r--r--source/blender/bmesh/tools/bmesh_path.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_path_region.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_path_region_uv.c502
-rw-r--r--source/blender/bmesh/tools/bmesh_path_region_uv.h45
-rw-r--r--source/blender/bmesh/tools/bmesh_path_uv.c433
-rw-r--r--source/blender/bmesh/tools/bmesh_path_uv.h44
-rw-r--r--source/blender/bmesh/tools/bmesh_region_match.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_region_match.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_separate.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_triangulate.h5
-rw-r--r--source/blender/bmesh/tools/bmesh_wireframe.h5
-rw-r--r--source/blender/compositor/COM_compositor.h4
-rw-r--r--source/blender/compositor/COM_defines.h5
-rw-r--r--source/blender/compositor/intern/COM_CPUDevice.h5
-rw-r--r--source/blender/compositor/intern/COM_ChunkOrder.h5
-rw-r--r--source/blender/compositor/intern/COM_ChunkOrderHotspot.h5
-rw-r--r--source/blender/compositor/intern/COM_CompositorContext.h5
-rw-r--r--source/blender/compositor/intern/COM_Converter.h4
-rw-r--r--source/blender/compositor/intern/COM_Debug.h5
-rw-r--r--source/blender/compositor/intern/COM_Device.h5
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.h5
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystem.h5
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.h5
-rw-r--r--source/blender/compositor/intern/COM_MemoryProxy.h6
-rw-r--r--source/blender/compositor/intern/COM_Node.h5
-rw-r--r--source/blender/compositor/intern/COM_NodeConverter.h5
-rw-r--r--source/blender/compositor/intern/COM_NodeGraph.h5
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h5
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.h5
-rw-r--r--source/blender/compositor/intern/COM_OpenCLDevice.h5
-rw-r--r--source/blender/compositor/intern/COM_SingleThreadedOperation.h5
-rw-r--r--source/blender/compositor/intern/COM_SocketReader.h6
-rw-r--r--source/blender/compositor/intern/COM_WorkPackage.h6
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.h5
-rw-r--r--source/blender/compositor/nodes/COM_AlphaOverNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_BilateralBlurNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_BlurNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_BokehBlurNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_BokehImageNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_BoxMaskNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_BrightnessNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ChannelMatteNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ChromaMatteNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ColorBalanceNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ColorCorrectionNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ColorCurveNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ColorMatteNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ColorNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ColorRampNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ColorSpillNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ColorToBWNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_CombineColorNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_CompositorNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_ConvertAlphaNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_CornerPinNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_CropNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_CryptomatteNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_DefocusNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_DenoiseNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_DespeckleNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_DifferenceMatteNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_DilateErodeNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_DirectionalBlurNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_DisplaceNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_DistanceMatteNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_EllipseMaskNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_FilterNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_FlipNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_GammaNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_GlareNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_HueSaturationValueNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_IDMaskNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_InpaintNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_InvertNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_KeyingNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_KeyingScreenNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_LensDistortionNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_LuminanceMatteNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_MapRangeNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_MapUVNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_MapValueNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_MaskNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_MathNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_MixNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_MovieClipNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_MovieDistortionNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_NormalNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_NormalizeNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_OutputFileNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_PixelateNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_RenderLayersNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_RotateNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ScaleNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_SeparateColorNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_SetAlphaNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_SocketProxyNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_SplitViewerNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_Stabilize2dNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_SunBeamsNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_SwitchNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_SwitchViewNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_TextureNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_TimeNode.cpp2
-rw-r--r--source/blender/compositor/nodes/COM_TimeNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_TonemapNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_TrackPositionNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_TransformNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_TranslateNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ValueNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_VectorBlurNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_VectorCurveNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ViewLevelsNode.h5
-rw-r--r--source/blender/compositor/nodes/COM_ViewerNode.h4
-rw-r--r--source/blender/compositor/nodes/COM_ZCombineNode.h5
-rw-r--r--source/blender/compositor/operations/COM_AlphaOverKeyOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_AlphaOverMixedOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_AntiAliasOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_BilateralBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_BlurBaseOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_BokehBlurOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_BokehImageOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_BoxMaskOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_BrightnessOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_CalculateMeanOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ChangeHSVOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ChannelMatteOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ChromaMatteOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ColorCorrectionOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ColorCurveOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_ColorMatteOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ColorRampOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ColorSpillOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ConvertColorProfileOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ConvertOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ConvolutionFilterOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_CropOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_CryptomatteOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_CurveBaseOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_CurveBaseOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_DenoiseOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_DespeckleOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_DifferenceMatteOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_DirectionalBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_DisplaceOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_DisplaceSimpleOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_DotproductOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp28
-rw-r--r--source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_EllipseMaskOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_FlipOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GammaCorrectOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_GammaOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_GaussianXBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GaussianYBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GlareBaseOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_GlareFogGlowOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GlareGhostOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GlareSimpleStarOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GlareStreaksOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_GlareThresholdOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_IDMaskOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ImageOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_InpaintOperation.cpp18
-rw-r--r--source/blender/compositor/operations/COM_InpaintOperation.h10
-rw-r--r--source/blender/compositor/operations/COM_InvertOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_KeyingBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_KeyingClipOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_KeyingDespillOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_KeyingOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_KeyingScreenOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_LuminanceMatteOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_MapRangeOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_MapUVOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_MapValueOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_MaskOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_MathBaseOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_MixOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_MovieClipAttributeOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_MovieClipOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_MovieDistortionOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_MultilayerImageOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_NormalizeOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_NormalizeOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_PixelateOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_PlaneCornerPinOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_PreviewOperation.cpp21
-rw-r--r--source/blender/compositor/operations/COM_PreviewOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_QualityStepHelper.h5
-rw-r--r--source/blender/compositor/operations/COM_ReadBufferOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.h5
-rw-r--r--source/blender/compositor/operations/COM_RotateOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ScaleOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_SetAlphaOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_SetColorOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_SetSamplerOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_SetValueOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_SetVectorOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_SocketProxyOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_SplitOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_TrackPositionOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_TranslateOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_VectorBlurOperation.cpp3
-rw-r--r--source/blender/compositor/operations/COM_VectorBlurOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_VectorCurveOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_WrapOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_WriteBufferOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_ZCombineOperation.h6
-rw-r--r--source/blender/depsgraph/CMakeLists.txt23
-rw-r--r--source/blender/depsgraph/DEG_depsgraph.h5
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h5
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_debug.h5
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_physics.h5
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h5
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_map.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc31
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc205
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc258
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.h76
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc33
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.h13
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna_test.cc60
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline.cc132
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline.h77
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_compositor.cc49
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_compositor.h (renamed from source/blender/functions/FN_cpp_types.hh)43
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_from_ids.cc154
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_from_ids.h62
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_render.cc49
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_render.h41
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_view_layer.cc48
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_view_layer.h41
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc357
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc261
-rw-r--r--source/blender/depsgraph/intern/depsgraph_registry.cc16
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc8
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc50
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc21
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h5
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc10
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h6
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.cc6
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.h2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.h2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.h1
-rw-r--r--source/blender/draw/CMakeLists.txt31
-rw-r--r--source/blender/draw/DRW_engine.h9
-rw-r--r--source/blender/draw/DRW_engine_types.h5
-rw-r--r--source/blender/draw/DRW_select_buffer.h5
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c2
-rw-r--r--source/blender/draw/engines/basic/basic_engine.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_data.c46
-rw-r--r--source/blender/draw/engines/eevee/eevee_depth_of_field.c36
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c32
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c112
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c52
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c165
-rw-r--r--source/blender/draw/engines/eevee/eevee_lut.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_lut_gen.c33
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c128
-rw-r--r--source/blender/draw/engines/eevee/eevee_mist.c16
-rw-r--r--source/blender/draw/engines/eevee/eevee_motion_blur.c101
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c19
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h44
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c31
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c10
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c24
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c465
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows.c25
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c38
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c17
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c111
-rw-r--r--source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl14
-rw-r--r--source/blender/draw/engines/eevee/shaders/background_vert.glsl18
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl877
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_lib.glsl181
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl (renamed from source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl)42
-rw-r--r--source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl65
-rw-r--r--source/blender/draw/engines/eevee/shaders/concentric_samples_lib.glsl265
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_frag.glsl51
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl12
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl38
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl29
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl13
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl80
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl31
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_grid_fill_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl20
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lights_lib.glsl95
-rw-r--r--source/blender/draw/engines/eevee/shaders/lookdev_world_frag.glsl (renamed from source/blender/draw/engines/eevee/shaders/default_world_frag.glsl)43
-rw-r--r--source/blender/draw/engines/eevee/shaders/ltc_lib.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/prepass_frag.glsl14
-rw-r--r--source/blender/draw/engines/eevee/shaders/prepass_vert.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl43
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl12
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_vert.glsl36
-rw-r--r--source/blender/draw/engines/eevee/shaders/ssr_lib.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_frag.glsl89
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_geom.glsl46
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_lib.glsl43
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_vert.glsl (renamed from source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl)33
-rw-r--r--source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl22
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl8
-rw-r--r--source/blender/draw/engines/external/external_engine.h5
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c13
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_data.c9
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c6
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h5
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_render.c3
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl34
-rw-r--r--source/blender/draw/engines/overlay/overlay_armature.c25
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_curve.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_mesh.c4
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_text.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c8
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.h5
-rw-r--r--source/blender/draw/engines/overlay/overlay_extra.c40
-rw-r--r--source/blender/draw/engines/overlay/overlay_facing.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_image.c22
-rw-r--r--source/blender/draw/engines/overlay/overlay_metaball.c4
-rw-r--r--source/blender/draw/engines/overlay/overlay_outline.c21
-rw-r--r--source/blender/draw/engines/overlay/overlay_paint.c12
-rw-r--r--source/blender/draw/engines/overlay/overlay_pointcloud.c72
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h15
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.c55
-rw-r--r--source/blender/draw/engines/overlay/overlay_wireframe.c20
-rw-r--r--source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl13
-rw-r--r--source/blender/draw/engines/overlay/shaders/grid_frag.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/grid_vert.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/outline_prepass_vert.glsl6
-rw-r--r--source/blender/draw/engines/overlay/shaders/pointcloud_frag.glsl16
-rw-r--r--source/blender/draw/engines/overlay/shaders/pointcloud_vert.glsl27
-rw-r--r--source/blender/draw/engines/select/select_engine.c2
-rw-r--r--source/blender/draw/engines/select/select_engine.h5
-rw-r--r--source/blender/draw/engines/select/select_private.h5
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl5
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl32
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl1
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl10
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_hair_vert.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl38
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shader_interface_lib.glsl6
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl6
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl12
-rw-r--r--source/blender/draw/engines/workbench/workbench_data.c40
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_antialiasing.c101
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c41
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.h5
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c30
-rw-r--r--source/blender/draw/engines/workbench/workbench_opaque.c24
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h43
-rw-r--r--source/blender/draw/engines/workbench/workbench_render.c1
-rw-r--r--source/blender/draw/engines/workbench/workbench_shader.c54
-rw-r--r--source/blender/draw/engines/workbench/workbench_transparent.c24
-rw-r--r--source/blender/draw/engines/workbench/workbench_volume.c13
-rw-r--r--source/blender/draw/intern/DRW_render.h39
-rw-r--r--source/blender/draw/intern/draw_cache.c113
-rw-r--r--source/blender/draw/intern/draw_cache.h6
-rw-r--r--source/blender/draw/intern/draw_cache_extract.h12
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c128
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h9
-rw-r--r--source/blender/draw/intern/draw_cache_impl_gpencil.c8
-rw-r--r--source/blender/draw/intern/draw_cache_impl_lattice.c25
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c218
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c20
-rw-r--r--source/blender/draw/intern/draw_cache_impl_pointcloud.c164
-rw-r--r--source/blender/draw/intern/draw_cache_impl_volume.c2
-rw-r--r--source/blender/draw/intern/draw_cache_inline.h5
-rw-r--r--source/blender/draw/intern/draw_color_management.h5
-rw-r--r--source/blender/draw/intern/draw_common.c9
-rw-r--r--source/blender/draw/intern/draw_common.h23
-rw-r--r--source/blender/draw/intern/draw_debug.h5
-rw-r--r--source/blender/draw/intern/draw_fluid.c (renamed from source/blender/gpu/intern/gpu_draw_smoke.c)54
-rw-r--r--source/blender/draw/intern/draw_hair.c2
-rw-r--r--source/blender/draw/intern/draw_hair_private.h5
-rw-r--r--source/blender/draw/intern/draw_instance_data.h5
-rw-r--r--source/blender/draw/intern/draw_manager.c152
-rw-r--r--source/blender/draw/intern/draw_manager.h8
-rw-r--r--source/blender/draw/intern/draw_manager_data.c128
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c36
-rw-r--r--source/blender/draw/intern/draw_manager_profiling.h5
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c106
-rw-r--r--source/blender/draw/intern/draw_manager_text.c6
-rw-r--r--source/blender/draw/intern/draw_manager_text.h5
-rw-r--r--source/blender/draw/intern/draw_manager_texture.c6
-rw-r--r--source/blender/draw/intern/draw_select_buffer.c19
-rw-r--r--source/blender/draw/intern/draw_view.c13
-rw-r--r--source/blender/draw/intern/draw_view.h5
-rw-r--r--source/blender/draw/intern/shaders/common_hair_lib.glsl22
-rw-r--r--source/blender/draw/intern/shaders/common_math_geom_lib.glsl119
-rw-r--r--source/blender/draw/intern/shaders/common_math_lib.glsl130
-rw-r--r--source/blender/draw/intern/shaders/common_pointcloud_lib.glsl39
-rw-r--r--source/blender/draw/intern/shaders/common_view_lib.glsl112
-rw-r--r--source/blender/draw/intern/smaa_textures.h4
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c104
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c24
-rw-r--r--source/blender/editors/animation/anim_draw.c4
-rw-r--r--source/blender/editors/animation/anim_filter.c20
-rw-r--r--source/blender/editors/animation/anim_intern.h5
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c3
-rw-r--r--source/blender/editors/animation/anim_markers.c19
-rw-r--r--source/blender/editors/animation/drivers.c30
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c3
-rw-r--r--source/blender/editors/animation/keyframes_draw.c37
-rw-r--r--source/blender/editors/animation/keyframes_edit.c16
-rw-r--r--source/blender/editors/animation/keyframes_general.c2
-rw-r--r--source/blender/editors/animation/keyframing.c201
-rw-r--r--source/blender/editors/animation/keyingsets.c45
-rw-r--r--source/blender/editors/armature/armature_add.c17
-rw-r--r--source/blender/editors/armature/armature_edit.c6
-rw-r--r--source/blender/editors/armature/armature_intern.h5
-rw-r--r--source/blender/editors/armature/armature_relations.c7
-rw-r--r--source/blender/editors/armature/armature_select.c13
-rw-r--r--source/blender/editors/armature/armature_utils.c18
-rw-r--r--source/blender/editors/armature/meshlaplacian.c10
-rw-r--r--source/blender/editors/armature/meshlaplacian.h7
-rw-r--r--source/blender/editors/armature/pose_group.c17
-rw-r--r--source/blender/editors/armature/pose_lib.c56
-rw-r--r--source/blender/editors/armature/pose_select.c6
-rw-r--r--source/blender/editors/armature/pose_slide.c64
-rw-r--r--source/blender/editors/armature/pose_transform.c15
-rw-r--r--source/blender/editors/curve/curve_intern.h5
-rw-r--r--source/blender/editors/curve/editcurve.c45
-rw-r--r--source/blender/editors/curve/editcurve_query.c6
-rw-r--r--source/blender/editors/curve/editcurve_select.c25
-rw-r--r--source/blender/editors/curve/editfont.c60
-rw-r--r--source/blender/editors/gizmo_library/gizmo_draw_utils.c5
-rw-r--r--source/blender/editors/gizmo_library/gizmo_geometry.h5
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_intern.h5
-rw-r--r--source/blender/editors/gizmo_library/gizmo_library_utils.c30
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c3
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c8
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c4
-rw-r--r--source/blender/editors/gpencil/annotate_draw.c17
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c6
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c16
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c69
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c148
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c16
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c57
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h6
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c28
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.c13
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c1
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c22
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c23
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c20
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c42
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c8
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c16
-rw-r--r--source/blender/editors/include/BIF_glutil.h42
-rw-r--r--source/blender/editors/include/ED_anim_api.h9
-rw-r--r--source/blender/editors/include/ED_armature.h13
-rw-r--r--source/blender/editors/include/ED_buttons.h9
-rw-r--r--source/blender/editors/include/ED_clip.h5
-rw-r--r--source/blender/editors/include/ED_curve.h5
-rw-r--r--source/blender/editors/include/ED_datafiles.h5
-rw-r--r--source/blender/editors/include/ED_fileselect.h7
-rw-r--r--source/blender/editors/include/ED_gizmo_library.h5
-rw-r--r--source/blender/editors/include/ED_gizmo_utils.h5
-rw-r--r--source/blender/editors/include/ED_gpencil.h7
-rw-r--r--source/blender/editors/include/ED_image.h9
-rw-r--r--source/blender/editors/include/ED_info.h11
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h5
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h5
-rw-r--r--source/blender/editors/include/ED_keyframing.h12
-rw-r--r--source/blender/editors/include/ED_lattice.h5
-rw-r--r--source/blender/editors/include/ED_markers.h5
-rw-r--r--source/blender/editors/include/ED_mask.h5
-rw-r--r--source/blender/editors/include/ED_mball.h5
-rw-r--r--source/blender/editors/include/ED_mesh.h6
-rw-r--r--source/blender/editors/include/ED_node.h7
-rw-r--r--source/blender/editors/include/ED_numinput.h13
-rw-r--r--source/blender/editors/include/ED_object.h19
-rw-r--r--source/blender/editors/include/ED_outliner.h5
-rw-r--r--source/blender/editors/include/ED_paint.h5
-rw-r--r--source/blender/editors/include/ED_particle.h5
-rw-r--r--source/blender/editors/include/ED_physics.h5
-rw-r--r--source/blender/editors/include/ED_render.h5
-rw-r--r--source/blender/editors/include/ED_scene.h5
-rw-r--r--source/blender/editors/include/ED_screen.h18
-rw-r--r--source/blender/editors/include/ED_screen_types.h5
-rw-r--r--source/blender/editors/include/ED_sculpt.h5
-rw-r--r--source/blender/editors/include/ED_select_utils.h5
-rw-r--r--source/blender/editors/include/ED_sequencer.h5
-rw-r--r--source/blender/editors/include/ED_sound.h5
-rw-r--r--source/blender/editors/include/ED_space_api.h5
-rw-r--r--source/blender/editors/include/ED_text.h5
-rw-r--r--source/blender/editors/include/ED_time_scrub_ui.h5
-rw-r--r--source/blender/editors/include/ED_transform.h5
-rw-r--r--source/blender/editors/include/ED_transform_snap_object_context.h5
-rw-r--r--source/blender/editors/include/ED_transverts.h5
-rw-r--r--source/blender/editors/include/ED_types.h5
-rw-r--r--source/blender/editors/include/ED_undo.h5
-rw-r--r--source/blender/editors/include/ED_userpref.h5
-rw-r--r--source/blender/editors/include/ED_util.h5
-rw-r--r--source/blender/editors/include/ED_util_imbuf.h5
-rw-r--r--source/blender/editors/include/ED_uvedit.h82
-rw-r--r--source/blender/editors/include/ED_view3d.h51
-rw-r--r--source/blender/editors/include/ED_view3d_offscreen.h13
-rw-r--r--source/blender/editors/include/UI_interface.h35
-rw-r--r--source/blender/editors/include/UI_interface_icons.h5
-rw-r--r--source/blender/editors/include/UI_resources.h5
-rw-r--r--source/blender/editors/include/UI_view2d.h5
-rw-r--r--source/blender/editors/interface/interface.c116
-rw-r--r--source/blender/editors/interface/interface_align.c67
-rw-r--r--source/blender/editors/interface/interface_anim.c8
-rw-r--r--source/blender/editors/interface/interface_context_menu.c5
-rw-r--r--source/blender/editors/interface/interface_draw.c25
-rw-r--r--source/blender/editors/interface/interface_eyedropper_color.c2
-rw-r--r--source/blender/editors/interface/interface_eyedropper_intern.h5
-rw-r--r--source/blender/editors/interface/interface_handlers.c43
-rw-r--r--source/blender/editors/interface/interface_icons.c148
-rw-r--r--source/blender/editors/interface/interface_intern.h29
-rw-r--r--source/blender/editors/interface/interface_layout.c62
-rw-r--r--source/blender/editors/interface/interface_ops.c12
-rw-r--r--source/blender/editors/interface/interface_panel.c225
-rw-r--r--source/blender/editors/interface/interface_query.c2
-rw-r--r--source/blender/editors/interface/interface_region_hud.c2
-rw-r--r--source/blender/editors/interface/interface_region_popup.c2
-rw-r--r--source/blender/editors/interface/interface_region_search.c52
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c12
-rw-r--r--source/blender/editors/interface/interface_regions_intern.h5
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.c2
-rw-r--r--source/blender/editors/interface/interface_template_search_operator.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c127
-rw-r--r--source/blender/editors/interface/interface_utils.c14
-rw-r--r--source/blender/editors/interface/interface_widgets.c66
-rw-r--r--source/blender/editors/interface/resources.c2
-rw-r--r--source/blender/editors/interface/view2d.c6
-rw-r--r--source/blender/editors/interface/view2d_draw.c59
-rw-r--r--source/blender/editors/interface/view2d_ops.c51
-rw-r--r--source/blender/editors/io/io_alembic.c136
-rw-r--r--source/blender/editors/io/io_alembic.h5
-rw-r--r--source/blender/editors/io/io_cache.h5
-rw-r--r--source/blender/editors/io/io_collada.c267
-rw-r--r--source/blender/editors/io/io_collada.h5
-rw-r--r--source/blender/editors/io/io_ops.h5
-rw-r--r--source/blender/editors/io/io_usd.c12
-rw-r--r--source/blender/editors/io/io_usd.h5
-rw-r--r--source/blender/editors/lattice/editlattice_select.c13
-rw-r--r--source/blender/editors/lattice/lattice_intern.h5
-rw-r--r--source/blender/editors/mask/mask_add.c10
-rw-r--r--source/blender/editors/mask/mask_draw.c3
-rw-r--r--source/blender/editors/mask/mask_intern.h5
-rw-r--r--source/blender/editors/mask/mask_ops.c18
-rw-r--r--source/blender/editors/mask/mask_select.c67
-rw-r--r--source/blender/editors/mask/mask_shapekey.c16
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c129
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c7
-rw-r--r--source/blender/editors/mesh/editmesh_inset.c314
-rw-r--r--source/blender/editors/mesh/editmesh_intersect.c22
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c542
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c13
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c9
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c4
-rw-r--r--source/blender/editors/mesh/editmesh_path.c4
-rw-r--r--source/blender/editors/mesh/editmesh_polybuild.c18
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c137
-rw-r--r--source/blender/editors/mesh/editmesh_select.c323
-rw-r--r--source/blender/editors/mesh/editmesh_select_similar.c10
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c114
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c2
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c55
-rw-r--r--source/blender/editors/mesh/mesh_data.c40
-rw-r--r--source/blender/editors/mesh/mesh_intern.h6
-rw-r--r--source/blender/editors/mesh/mesh_mirror.c14
-rw-r--r--source/blender/editors/mesh/meshtools.c71
-rw-r--r--source/blender/editors/metaball/mball_intern.h5
-rw-r--r--source/blender/editors/object/object_add.c95
-rw-r--r--source/blender/editors/object/object_bake.c4
-rw-r--r--source/blender/editors/object/object_bake_api.c38
-rw-r--r--source/blender/editors/object/object_constraint.c164
-rw-r--r--source/blender/editors/object/object_data_transfer.c30
-rw-r--r--source/blender/editors/object/object_data_transform.c213
-rw-r--r--source/blender/editors/object/object_edit.c21
-rw-r--r--source/blender/editors/object/object_gpencil_modifier.c37
-rw-r--r--source/blender/editors/object/object_hook.c8
-rw-r--r--source/blender/editors/object/object_intern.h6
-rw-r--r--source/blender/editors/object/object_modifier.c258
-rw-r--r--source/blender/editors/object/object_ops.c1
-rw-r--r--source/blender/editors/object/object_relations.c696
-rw-r--r--source/blender/editors/object/object_remesh.c3
-rw-r--r--source/blender/editors/object/object_select.c39
-rw-r--r--source/blender/editors/object/object_shader_fx.c109
-rw-r--r--source/blender/editors/object/object_shapekey.c4
-rw-r--r--source/blender/editors/object/object_transform.c8
-rw-r--r--source/blender/editors/object/object_utils.c12
-rw-r--r--source/blender/editors/object/object_vgroup.c80
-rw-r--r--source/blender/editors/object/object_volume.c2
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c10
-rw-r--r--source/blender/editors/physics/particle_edit.c20
-rw-r--r--source/blender/editors/physics/particle_edit_utildefines.h5
-rw-r--r--source/blender/editors/physics/particle_object.c8
-rw-r--r--source/blender/editors/physics/physics_fluid.c3
-rw-r--r--source/blender/editors/physics/physics_intern.h5
-rw-r--r--source/blender/editors/physics/rigidbody_constraint.c12
-rw-r--r--source/blender/editors/physics/rigidbody_object.c35
-rw-r--r--source/blender/editors/render/render_intern.h5
-rw-r--r--source/blender/editors/render/render_internal.c10
-rw-r--r--source/blender/editors/render/render_opengl.c27
-rw-r--r--source/blender/editors/render/render_preview.c15
-rw-r--r--source/blender/editors/render/render_shading.c47
-rw-r--r--source/blender/editors/render/render_view.c4
-rw-r--r--source/blender/editors/scene/scene_edit.c4
-rw-r--r--source/blender/editors/screen/area.c83
-rw-r--r--source/blender/editors/screen/glutil.c394
-rw-r--r--source/blender/editors/screen/screen_context.c118
-rw-r--r--source/blender/editors/screen/screen_draw.c6
-rw-r--r--source/blender/editors/screen/screen_edit.c55
-rw-r--r--source/blender/editors/screen/screen_geometry.c31
-rw-r--r--source/blender/editors/screen/screen_intern.h15
-rw-r--r--source/blender/editors/screen/screen_ops.c133
-rw-r--r--source/blender/editors/screen/screendump.c8
-rw-r--r--source/blender/editors/screen/workspace_edit.c31
-rw-r--r--source/blender/editors/screen/workspace_layout_edit.c60
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c1272
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve.c16
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c13
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c33
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c275
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h6
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c52
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c17
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c19
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c19
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c14
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_ops.c30
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_utils.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c10
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c448
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_automasking.c93
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c449
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c12
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c108
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h57
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c33
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c38
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c224
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c14
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c6
-rw-r--r--source/blender/editors/sound/sound_intern.h5
-rw-r--r--source/blender/editors/sound/sound_ops.c3
-rw-r--r--source/blender/editors/space_action/action_data.c81
-rw-r--r--source/blender/editors/space_action/action_edit.c13
-rw-r--r--source/blender/editors/space_action/action_intern.h5
-rw-r--r--source/blender/editors/space_action/space_action.c4
-rw-r--r--source/blender/editors/space_api/spacetypes.c6
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c305
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h5
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c103
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c1
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c119
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c10
-rw-r--r--source/blender/editors/space_clip/clip_draw.c66
-rw-r--r--source/blender/editors/space_clip/clip_editor.c29
-rw-r--r--source/blender/editors/space_clip/clip_intern.h5
-rw-r--r--source/blender/editors/space_clip/clip_ops.c54
-rw-r--r--source/blender/editors/space_clip/space_clip.c31
-rw-r--r--source/blender/editors/space_clip/tracking_ops_intern.h5
-rw-r--r--source/blender/editors/space_clip/tracking_ops_orient.c4
-rw-r--r--source/blender/editors/space_clip/tracking_ops_plane.c19
-rw-r--r--source/blender/editors/space_clip/tracking_ops_solve.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops_track.c23
-rw-r--r--source/blender/editors/space_clip/tracking_select.c4
-rw-r--r--source/blender/editors/space_console/console_draw.c1
-rw-r--r--source/blender/editors/space_console/console_intern.h5
-rw-r--r--source/blender/editors/space_console/console_ops.c46
-rw-r--r--source/blender/editors/space_console/space_console.c4
-rw-r--r--source/blender/editors/space_file/file_draw.c9
-rw-r--r--source/blender/editors/space_file/file_intern.h5
-rw-r--r--source/blender/editors/space_file/file_ops.c18
-rw-r--r--source/blender/editors/space_file/filelist.c197
-rw-r--r--source/blender/editors/space_file/filelist.h5
-rw-r--r--source/blender/editors/space_file/filesel.c15
-rw-r--r--source/blender/editors/space_file/fsmenu.c56
-rw-r--r--source/blender/editors/space_file/fsmenu.h5
-rw-r--r--source/blender/editors/space_file/space_file.c10
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c2
-rw-r--r--source/blender/editors/space_graph/graph_draw.c4
-rw-r--r--source/blender/editors/space_graph/graph_edit.c74
-rw-r--r--source/blender/editors/space_graph/graph_intern.h5
-rw-r--r--source/blender/editors/space_graph/graph_select.c9
-rw-r--r--source/blender/editors/space_graph/space_graph.c8
-rw-r--r--source/blender/editors/space_image/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_image/image_buttons.c18
-rw-r--r--source/blender/editors/space_image/image_draw.c42
-rw-r--r--source/blender/editors/space_image/image_edit.c5
-rw-r--r--source/blender/editors/space_image/image_intern.h5
-rw-r--r--source/blender/editors/space_image/image_ops.c157
-rw-r--r--source/blender/editors/space_image/image_undo.c7
-rw-r--r--source/blender/editors/space_image/space_image.c26
-rw-r--r--source/blender/editors/space_info/info_draw.c25
-rw-r--r--source/blender/editors/space_info/info_intern.h5
-rw-r--r--source/blender/editors/space_info/info_stats.c242
-rw-r--r--source/blender/editors/space_info/space_info.c4
-rw-r--r--source/blender/editors/space_info/textview.c2
-rw-r--r--source/blender/editors/space_info/textview.h5
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c2
-rw-r--r--source/blender/editors/space_nla/nla_channels.c35
-rw-r--r--source/blender/editors/space_nla/nla_draw.c5
-rw-r--r--source/blender/editors/space_nla/nla_edit.c46
-rw-r--r--source/blender/editors/space_nla/nla_intern.h5
-rw-r--r--source/blender/editors/space_nla/space_nla.c4
-rw-r--r--source/blender/editors/space_node/drawnode.c48
-rw-r--r--source/blender/editors/space_node/node_add.c4
-rw-r--r--source/blender/editors/space_node/node_draw.c21
-rw-r--r--source/blender/editors/space_node/node_edit.c13
-rw-r--r--source/blender/editors/space_node/node_group.c137
-rw-r--r--source/blender/editors/space_node/node_intern.h5
-rw-r--r--source/blender/editors/space_node/node_relationships.c34
-rw-r--r--source/blender/editors/space_node/node_select.c6
-rw-r--r--source/blender/editors/space_node/node_templates.c4
-rw-r--r--source/blender/editors/space_node/node_view.c12
-rw-r--r--source/blender/editors/space_node/space_node.c20
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c85
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c117
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c38
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h21
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c57
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c329
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c67
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c6
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c4
-rw-r--r--source/blender/editors/space_script/script_intern.h5
-rw-r--r--source/blender/editors/space_script/space_script.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c71
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c225
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h5
-rw-r--r--source/blender/editors/space_sequencer/sequencer_scopes.c22
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c4
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c20
-rw-r--r--source/blender/editors/space_statusbar/space_statusbar.c4
-rw-r--r--source/blender/editors/space_text/space_text.c6
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c19
-rw-r--r--source/blender/editors/space_text/text_draw.c22
-rw-r--r--source/blender/editors/space_text/text_format.c7
-rw-r--r--source/blender/editors/space_text/text_format.h5
-rw-r--r--source/blender/editors/space_text/text_format_lua.c2
-rw-r--r--source/blender/editors/space_text/text_format_osl.c2
-rw-r--r--source/blender/editors/space_text/text_format_pov.c2
-rw-r--r--source/blender/editors/space_text/text_format_pov_ini.c2
-rw-r--r--source/blender/editors/space_text/text_format_py.c2
-rw-r--r--source/blender/editors/space_text/text_intern.h5
-rw-r--r--source/blender/editors/space_text/text_ops.c31
-rw-r--r--source/blender/editors/space_topbar/space_topbar.c4
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c6
-rw-r--r--source/blender/editors/space_userpref/userpref_intern.h5
-rw-r--r--source/blender/editors/space_view3d/drawobject.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c25
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c53
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c69
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c108
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c100
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c25
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_ruler.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h5
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c169
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c31
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c81
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c62
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c24
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c20
-rw-r--r--source/blender/editors/transform/transform.c8
-rw-r--r--source/blender/editors/transform/transform.h6
-rw-r--r--source/blender/editors/transform/transform_constraints.c10
-rw-r--r--source/blender/editors/transform/transform_constraints.h5
-rw-r--r--source/blender/editors/transform/transform_convert.c114
-rw-r--r--source/blender/editors/transform/transform_convert.h8
-rw-r--r--source/blender/editors/transform/transform_convert_action.c12
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c21
-rw-r--r--source/blender/editors/transform/transform_convert_curve.c16
-rw-r--r--source/blender/editors/transform/transform_convert_gpencil.c4
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c670
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_uv.c256
-rw-r--r--source/blender/editors/transform/transform_convert_object.c21
-rw-r--r--source/blender/editors/transform/transform_convert_paintcurve.c12
-rw-r--r--source/blender/editors/transform/transform_convert_particle.c2
-rw-r--r--source/blender/editors/transform/transform_data.h5
-rw-r--r--source/blender/editors/transform/transform_draw_cursors.h5
-rw-r--r--source/blender/editors/transform/transform_generics.c2
-rw-r--r--source/blender/editors/transform/transform_input.c8
-rw-r--r--source/blender/editors/transform/transform_mode.c38
-rw-r--r--source/blender/editors/transform/transform_mode.h4
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c17
-rw-r--r--source/blender/editors/transform/transform_mode_shear.c10
-rw-r--r--source/blender/editors/transform/transform_mode_shrink_fatten.c4
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c24
-rw-r--r--source/blender/editors/transform/transform_mode_vert_slide.c6
-rw-r--r--source/blender/editors/transform/transform_ops.c21
-rw-r--r--source/blender/editors/transform/transform_orientations.c4
-rw-r--r--source/blender/editors/transform/transform_snap.c30
-rw-r--r--source/blender/editors/transform/transform_snap.h5
-rw-r--r--source/blender/editors/transform/transform_snap_object.c52
-rw-r--r--source/blender/editors/undo/ed_undo.c10
-rw-r--r--source/blender/editors/undo/undo_intern.h5
-rw-r--r--source/blender/editors/util/CMakeLists.txt2
-rw-r--r--source/blender/editors/util/ed_util.c5
-rw-r--r--source/blender/editors/util/ed_util_imbuf.c7
-rw-r--r--source/blender/editors/util/numinput.c46
-rw-r--r--source/blender/editors/uvedit/CMakeLists.txt3
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c31
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h21
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c40
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c62
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.h5
-rw-r--r--source/blender/editors/uvedit/uvedit_path.c873
-rw-r--r--source/blender/editors/uvedit/uvedit_rip.c980
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c1234
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c44
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c476
-rw-r--r--source/blender/freestyle/FRS_freestyle.h7
-rw-r--r--source/blender/freestyle/intern/application/AppCanvas.h5
-rw-r--r--source/blender/freestyle/intern/application/AppConfig.cpp20
-rw-r--r--source/blender/freestyle/intern/application/AppConfig.h5
-rw-r--r--source/blender/freestyle/intern/application/AppView.cpp2
-rw-r--r--source/blender/freestyle/intern/application/AppView.h5
-rw-r--r--source/blender/freestyle/intern/application/Controller.cpp2
-rw-r--r--source/blender/freestyle/intern/application/Controller.h5
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp2
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h9
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h5
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h5
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp6
-rw-r--r--source/blender/freestyle/intern/geometry/BBox.h5
-rw-r--r--source/blender/freestyle/intern/geometry/Bezier.cpp4
-rw-r--r--source/blender/freestyle/intern/geometry/Bezier.h5
-rw-r--r--source/blender/freestyle/intern/geometry/FastGrid.h5
-rw-r--r--source/blender/freestyle/intern/geometry/FitCurve.h5
-rw-r--r--source/blender/freestyle/intern/geometry/Geom.h5
-rw-r--r--source/blender/freestyle/intern/geometry/GeomCleaner.h5
-rw-r--r--source/blender/freestyle/intern/geometry/GeomUtils.h5
-rw-r--r--source/blender/freestyle/intern/geometry/Grid.h5
-rw-r--r--source/blender/freestyle/intern/geometry/GridHelpers.h5
-rw-r--r--source/blender/freestyle/intern/geometry/HashGrid.h5
-rw-r--r--source/blender/freestyle/intern/geometry/Noise.h5
-rw-r--r--source/blender/freestyle/intern/geometry/Polygon.h5
-rw-r--r--source/blender/freestyle/intern/geometry/SweepLine.h5
-rw-r--r--source/blender/freestyle/intern/geometry/VecMat.h5
-rw-r--r--source/blender/freestyle/intern/geometry/matrix_util.cpp1
-rw-r--r--source/blender/freestyle/intern/geometry/matrix_util.h5
-rw-r--r--source/blender/freestyle/intern/geometry/normal_cycle.h5
-rw-r--r--source/blender/freestyle/intern/image/GaussianFilter.cpp8
-rw-r--r--source/blender/freestyle/intern/image/GaussianFilter.h5
-rw-r--r--source/blender/freestyle/intern/image/Image.h7
-rw-r--r--source/blender/freestyle/intern/image/ImagePyramid.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_BBox.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp5
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_ContextFunctions.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_Convert.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsMaterial.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsNoise.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_Id.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Id.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_IntegrationType.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface0D.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface1D.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_Iterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_Iterator.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_MediumType.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_Nature.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_Operators.cpp8
-rw-r--r--source/blender/freestyle/intern/python/BPy_Operators.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_SShape.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeAttribute.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeShader.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewMap.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewMap.h5
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewShape.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewShape.h5
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/Director.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp8
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp3
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h5
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp3
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp6
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h5
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h5
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/DrawingStyle.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/FrsMaterial.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/LineRep.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/Node.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeCamera.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeGroup.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeLight.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeShape.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeTransform.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeViewLayer.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/OrientedLineRep.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/Rep.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneHash.cpp2
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneHash.h7
-rw-r--r--source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp16
-rw-r--r--source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneVisitor.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/TriangleRep.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/VertexRep.h5
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h5
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h5
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h5
-rw-r--r--source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h5
-rw-r--r--source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp2
-rw-r--r--source/blender/freestyle/intern/stroke/BasicStrokeShaders.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Canvas.cpp4
-rw-r--r--source/blender/freestyle/intern/stroke/Canvas.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Chain.h5
-rw-r--r--source/blender/freestyle/intern/stroke/ChainingIterators.h5
-rw-r--r--source/blender/freestyle/intern/stroke/ContextFunctions.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Curve.h5
-rw-r--r--source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h5
-rw-r--r--source/blender/freestyle/intern/stroke/CurveIterators.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Modifiers.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Module.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Operators.h5
-rw-r--r--source/blender/freestyle/intern/stroke/PSStrokeRenderer.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Predicates0D.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Predicates1D.h5
-rw-r--r--source/blender/freestyle/intern/stroke/QInformationMap.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.cpp4
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.h5
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h5
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeIO.h5
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeIterators.h5
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeLayer.h5
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRenderer.h5
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.h5
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeShader.h5
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeTesselator.h5
-rw-r--r--source/blender/freestyle/intern/stroke/StyleModule.h5
-rw-r--r--source/blender/freestyle/intern/system/BaseIterator.h5
-rw-r--r--source/blender/freestyle/intern/system/BaseObject.h5
-rw-r--r--source/blender/freestyle/intern/system/Cast.h5
-rw-r--r--source/blender/freestyle/intern/system/Exception.h5
-rw-r--r--source/blender/freestyle/intern/system/FreestyleConfig.h5
-rw-r--r--source/blender/freestyle/intern/system/Id.h5
-rw-r--r--source/blender/freestyle/intern/system/Interpreter.h5
-rw-r--r--source/blender/freestyle/intern/system/Iterator.h5
-rw-r--r--source/blender/freestyle/intern/system/PointerSequence.h5
-rw-r--r--source/blender/freestyle/intern/system/Precision.h5
-rw-r--r--source/blender/freestyle/intern/system/ProgressBar.h5
-rw-r--r--source/blender/freestyle/intern/system/PseudoNoise.h5
-rw-r--r--source/blender/freestyle/intern/system/PythonInterpreter.h7
-rw-r--r--source/blender/freestyle/intern/system/RandGen.h5
-rw-r--r--source/blender/freestyle/intern/system/RenderMonitor.h7
-rw-r--r--source/blender/freestyle/intern/system/StringUtils.h7
-rw-r--r--source/blender/freestyle/intern/system/TimeStamp.h5
-rw-r--r--source/blender/freestyle/intern/system/TimeUtils.h5
-rw-r--r--source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h5
-rw-r--r--source/blender/freestyle/intern/view_map/AutoPtrHelper.h5
-rw-r--r--source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h5
-rw-r--r--source/blender/freestyle/intern/view_map/BoxGrid.h5
-rw-r--r--source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/CulledOccluderSource.h5
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.h5
-rw-r--r--source/blender/freestyle/intern/view_map/Functions0D.h5
-rw-r--r--source/blender/freestyle/intern/view_map/Functions1D.h5
-rw-r--r--source/blender/freestyle/intern/view_map/GridDensityProvider.h5
-rw-r--r--source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h5
-rw-r--r--source/blender/freestyle/intern/view_map/Interface0D.cpp4
-rw-r--r--source/blender/freestyle/intern/view_map/Interface0D.h5
-rw-r--r--source/blender/freestyle/intern/view_map/Interface1D.h5
-rw-r--r--source/blender/freestyle/intern/view_map/OccluderSource.h5
-rw-r--r--source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h5
-rw-r--r--source/blender/freestyle/intern/view_map/Silhouette.h5
-rw-r--r--source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h5
-rw-r--r--source/blender/freestyle/intern/view_map/SphericalGrid.h5
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.cpp4
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.h5
-rw-r--r--source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h5
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.h5
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h5
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.h5
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIO.h5
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIterators.h5
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.h5
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.cpp2
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.h5
-rw-r--r--source/blender/freestyle/intern/winged_edge/Nature.h5
-rw-r--r--source/blender/freestyle/intern/winged_edge/WEdge.h5
-rw-r--r--source/blender/freestyle/intern/winged_edge/WFillGrid.h5
-rw-r--r--source/blender/freestyle/intern/winged_edge/WSFillGrid.h5
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdge.h5
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h5
-rw-r--r--source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp6
-rw-r--r--source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h5
-rw-r--r--source/blender/functions/CMakeLists.txt22
-rw-r--r--source/blender/functions/FN_array_spans.hh29
-rw-r--r--source/blender/functions/FN_attributes_ref.hh143
-rw-r--r--source/blender/functions/FN_cpp_type.hh434
-rw-r--r--source/blender/functions/FN_generic_vector_array.hh55
-rw-r--r--source/blender/functions/FN_multi_function.hh33
-rw-r--r--source/blender/functions/FN_multi_function_builder.hh103
-rw-r--r--source/blender/functions/FN_multi_function_context.hh31
-rw-r--r--source/blender/functions/FN_multi_function_data_type.hh10
-rw-r--r--source/blender/functions/FN_multi_function_network.hh135
-rw-r--r--source/blender/functions/FN_multi_function_network_evaluation.hh5
-rw-r--r--source/blender/functions/FN_multi_function_network_optimization.hh29
-rw-r--r--source/blender/functions/FN_multi_function_param_type.hh10
-rw-r--r--source/blender/functions/FN_multi_function_params.hh109
-rw-r--r--source/blender/functions/FN_multi_function_signature.hh40
-rw-r--r--source/blender/functions/FN_spans.hh121
-rw-r--r--source/blender/functions/intern/attributes_ref.cc21
-rw-r--r--source/blender/functions/intern/cpp_types.cc2
-rw-r--r--source/blender/functions/intern/multi_function_builder.cc119
-rw-r--r--source/blender/functions/intern/multi_function_network.cc80
-rw-r--r--source/blender/functions/intern/multi_function_network_evaluation.cc79
-rw-r--r--source/blender/functions/intern/multi_function_network_optimization.cc504
-rw-r--r--source/blender/functions/tests/FN_array_spans_test.cc132
-rw-r--r--source/blender/functions/tests/FN_attributes_ref_test.cc97
-rw-r--r--source/blender/functions/tests/FN_cpp_type_test.cc325
-rw-r--r--source/blender/functions/tests/FN_generic_vector_array_test.cc101
-rw-r--r--source/blender/functions/tests/FN_multi_function_network_test.cc255
-rw-r--r--source/blender/functions/tests/FN_multi_function_test.cc387
-rw-r--r--source/blender/functions/tests/FN_spans_test.cc222
-rw-r--r--source/blender/gpencil_modifiers/CMakeLists.txt4
-rw-r--r--source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h5
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.c26
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.h5
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h5
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c13
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c4
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c8
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c4
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c3
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c2
-rw-r--r--source/blender/gpu/CMakeLists.txt43
-rw-r--r--source/blender/gpu/GPU_attr_binding.h5
-rw-r--r--source/blender/gpu/GPU_batch.h10
-rw-r--r--source/blender/gpu/GPU_batch_presets.h7
-rw-r--r--source/blender/gpu/GPU_batch_utils.h5
-rw-r--r--source/blender/gpu/GPU_buffers.h7
-rw-r--r--source/blender/gpu/GPU_common.h5
-rw-r--r--source/blender/gpu/GPU_context.h13
-rw-r--r--source/blender/gpu/GPU_debug.h7
-rw-r--r--source/blender/gpu/GPU_draw.h95
-rw-r--r--source/blender/gpu/GPU_element.h5
-rw-r--r--source/blender/gpu/GPU_extensions.h11
-rw-r--r--source/blender/gpu/GPU_framebuffer.h51
-rw-r--r--source/blender/gpu/GPU_glew.h5
-rw-r--r--source/blender/gpu/GPU_immediate.h14
-rw-r--r--source/blender/gpu/GPU_immediate_util.h5
-rw-r--r--source/blender/gpu/GPU_init_exit.h7
-rw-r--r--source/blender/gpu/GPU_legacy_stubs.h5
-rw-r--r--source/blender/gpu/GPU_material.h20
-rw-r--r--source/blender/gpu/GPU_matrix.h21
-rw-r--r--source/blender/gpu/GPU_platform.h16
-rw-r--r--source/blender/gpu/GPU_primitive.h5
-rw-r--r--source/blender/gpu/GPU_select.h5
-rw-r--r--source/blender/gpu/GPU_shader.h19
-rw-r--r--source/blender/gpu/GPU_shader_interface.h5
-rw-r--r--source/blender/gpu/GPU_state.h30
-rw-r--r--source/blender/gpu/GPU_texture.h48
-rw-r--r--source/blender/gpu/GPU_uniformbuffer.h8
-rw-r--r--source/blender/gpu/GPU_vertex_buffer.h11
-rw-r--r--source/blender/gpu/GPU_vertex_format.h15
-rw-r--r--source/blender/gpu/GPU_viewport.h10
-rw-r--r--source/blender/gpu/intern/gpu_attr_binding.cc (renamed from source/blender/gpu/intern/gpu_attr_binding.c)0
-rw-r--r--source/blender/gpu/intern/gpu_attr_binding_private.h12
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc (renamed from source/blender/gpu/intern/gpu_batch.c)74
-rw-r--r--source/blender/gpu/intern/gpu_batch_presets.c13
-rw-r--r--source/blender/gpu/intern/gpu_batch_private.h5
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c10
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c529
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h16
-rw-r--r--source/blender/gpu/intern/gpu_context.cc (renamed from source/blender/gpu/intern/gpu_context.cpp)11
-rw-r--r--source/blender/gpu/intern/gpu_context_private.h5
-rw-r--r--source/blender/gpu/intern/gpu_debug.cc (renamed from source/blender/gpu/intern/gpu_debug.c)0
-rw-r--r--source/blender/gpu/intern/gpu_draw.c1464
-rw-r--r--source/blender/gpu/intern/gpu_element.cc (renamed from source/blender/gpu/intern/gpu_element.c)24
-rw-r--r--source/blender/gpu/intern/gpu_extensions.cc (renamed from source/blender/gpu/intern/gpu_extensions.c)45
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.cc (renamed from source/blender/gpu/intern/gpu_framebuffer.c)182
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc (renamed from source/blender/gpu/intern/gpu_immediate.c)68
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c2
-rw-r--r--source/blender/gpu/intern/gpu_material.c12
-rw-r--r--source/blender/gpu/intern/gpu_material_library.h5
-rw-r--r--source/blender/gpu/intern/gpu_matrix.cc (renamed from source/blender/gpu/intern/gpu_matrix.c)121
-rw-r--r--source/blender/gpu/intern/gpu_matrix_private.h5
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.h8
-rw-r--r--source/blender/gpu/intern/gpu_platform.cc (renamed from source/blender/gpu/intern/gpu_platform.c)0
-rw-r--r--source/blender/gpu/intern/gpu_primitive.c29
-rw-r--r--source/blender/gpu/intern/gpu_primitive_private.h12
-rw-r--r--source/blender/gpu/intern/gpu_private.h11
-rw-r--r--source/blender/gpu/intern/gpu_select.c1
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c9
-rw-r--r--source/blender/gpu/intern/gpu_select_private.h5
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c8
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc839
-rw-r--r--source/blender/gpu/intern/gpu_shader_builtin.c (renamed from source/blender/gpu/intern/gpu_shader.c)743
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.cc (renamed from source/blender/gpu/intern/gpu_shader_interface.c)119
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.h14
-rw-r--r--source/blender/gpu/intern/gpu_state.cc (renamed from source/blender/gpu/intern/gpu_state.c)161
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc (renamed from source/blender/gpu/intern/gpu_texture.c)501
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.cc (renamed from source/blender/gpu/intern/gpu_uniformbuffer.c)306
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer.cc (renamed from source/blender/gpu/intern/gpu_vertex_buffer.c)25
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc (renamed from source/blender/gpu/intern/gpu_vertex_format.c)52
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format_private.h12
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c21
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl50
-rw-r--r--source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl87
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl12
-rw-r--r--source/blender/gpu/shaders/gpu_shader_text_frag.glsl1
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl12
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl1
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl148
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl2
-rw-r--r--source/blender/ikplugin/BIK_api.h13
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.c2
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.h5
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.h5
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp32
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.h5
-rw-r--r--source/blender/imbuf/CMakeLists.txt2
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h6
-rw-r--r--source/blender/imbuf/IMB_imbuf.h47
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h5
-rw-r--r--source/blender/imbuf/IMB_metadata.h5
-rw-r--r--source/blender/imbuf/IMB_moviecache.h5
-rw-r--r--source/blender/imbuf/IMB_thumbs.h5
-rw-r--r--source/blender/imbuf/intern/IMB_allocimbuf.h5
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h5
-rw-r--r--source/blender/imbuf/intern/IMB_colormanagement_intern.h5
-rw-r--r--source/blender/imbuf/intern/IMB_filetype.h5
-rw-r--r--source/blender/imbuf/intern/IMB_filter.h5
-rw-r--r--source/blender/imbuf/intern/IMB_indexer.h11
-rw-r--r--source/blender/imbuf/intern/anim_movie.c43
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.h5
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.h5
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.h5
-rw-r--r--source/blender/imbuf/intern/cineon/logmemfile.h5
-rw-r--r--source/blender/imbuf/intern/colormanagement.c11
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.cpp4
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.h9
-rw-r--r--source/blender/imbuf/intern/dds/Color.h5
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.h5
-rw-r--r--source/blender/imbuf/intern/dds/Common.h5
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.h5
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.h5
-rw-r--r--source/blender/imbuf/intern/dds/Image.cpp4
-rw-r--r--source/blender/imbuf/intern/dds/Image.h5
-rw-r--r--source/blender/imbuf/intern/dds/PixelFormat.h5
-rw-r--r--source/blender/imbuf/intern/dds/Stream.h5
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.h5
-rw-r--r--source/blender/imbuf/intern/filter.c2
-rw-r--r--source/blender/imbuf/intern/imageprocess.c2
-rw-r--r--source/blender/imbuf/intern/imbuf.h5
-rw-r--r--source/blender/imbuf/intern/indexer.c4
-rw-r--r--source/blender/imbuf/intern/iris.c4
-rw-r--r--source/blender/imbuf/intern/jp2.c4
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.h5
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp100
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.h5
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_multi.h5
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c5
-rw-r--r--source/blender/imbuf/intern/stereoimbuf.c92
-rw-r--r--source/blender/imbuf/intern/tiff.c16
-rw-r--r--source/blender/imbuf/intern/util_gpu.c261
-rw-r--r--source/blender/io/alembic/ABC_alembic.h10
-rw-r--r--source/blender/io/alembic/CMakeLists.txt4
-rw-r--r--source/blender/io/alembic/exporter/abc_export_capi.cc44
-rw-r--r--source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc13
-rw-r--r--source/blender/io/alembic/exporter/abc_hierarchy_iterator.h6
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_curves.cc6
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_nurbs.cc2
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_transform.cc3
-rw-r--r--source/blender/io/alembic/intern/abc_axis_conversion.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_axis_conversion.h2
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_reader_object.cc2
-rw-r--r--source/blender/io/alembic/intern/alembic_capi.cc146
-rw-r--r--source/blender/io/avi/AVI_avi.h5
-rw-r--r--source/blender/io/avi/intern/avi_endian.h5
-rw-r--r--source/blender/io/avi/intern/avi_intern.h5
-rw-r--r--source/blender/io/avi/intern/avi_mjpeg.c15
-rw-r--r--source/blender/io/avi/intern/avi_mjpeg.h10
-rw-r--r--source/blender/io/avi/intern/avi_rgb.c5
-rw-r--r--source/blender/io/avi/intern/avi_rgb.h10
-rw-r--r--source/blender/io/avi/intern/avi_rgb32.h5
-rw-r--r--source/blender/io/collada/AnimationClipExporter.h5
-rw-r--r--source/blender/io/collada/AnimationExporter.cpp2
-rw-r--r--source/blender/io/collada/AnimationExporter.h5
-rw-r--r--source/blender/io/collada/AnimationImporter.cpp4
-rw-r--r--source/blender/io/collada/AnimationImporter.h5
-rw-r--r--source/blender/io/collada/ArmatureExporter.h5
-rw-r--r--source/blender/io/collada/ArmatureImporter.cpp4
-rw-r--r--source/blender/io/collada/ArmatureImporter.h5
-rw-r--r--source/blender/io/collada/BCAnimationCurve.h5
-rw-r--r--source/blender/io/collada/BCAnimationSampler.h5
-rw-r--r--source/blender/io/collada/BCMath.cpp23
-rw-r--r--source/blender/io/collada/BCMath.h5
-rw-r--r--source/blender/io/collada/BCSampleData.h5
-rw-r--r--source/blender/io/collada/BlenderContext.h5
-rw-r--r--source/blender/io/collada/BlenderTypes.h5
-rw-r--r--source/blender/io/collada/CameraExporter.h5
-rw-r--r--source/blender/io/collada/ControllerExporter.h5
-rw-r--r--source/blender/io/collada/DocumentExporter.h5
-rw-r--r--source/blender/io/collada/DocumentImporter.h5
-rw-r--r--source/blender/io/collada/EffectExporter.h5
-rw-r--r--source/blender/io/collada/ErrorHandler.h5
-rw-r--r--source/blender/io/collada/ExportSettings.h5
-rw-r--r--source/blender/io/collada/ExtraHandler.h5
-rw-r--r--source/blender/io/collada/ExtraTags.h5
-rw-r--r--source/blender/io/collada/GeometryExporter.h5
-rw-r--r--source/blender/io/collada/ImageExporter.h5
-rw-r--r--source/blender/io/collada/ImportSettings.h5
-rw-r--r--source/blender/io/collada/InstanceWriter.h5
-rw-r--r--source/blender/io/collada/LightExporter.h5
-rw-r--r--source/blender/io/collada/MaterialExporter.h5
-rw-r--r--source/blender/io/collada/Materials.h5
-rw-r--r--source/blender/io/collada/MeshImporter.cpp2
-rw-r--r--source/blender/io/collada/MeshImporter.h7
-rw-r--r--source/blender/io/collada/SceneExporter.h5
-rw-r--r--source/blender/io/collada/SkinInfo.h5
-rw-r--r--source/blender/io/collada/TransformReader.h5
-rw-r--r--source/blender/io/collada/TransformWriter.cpp6
-rw-r--r--source/blender/io/collada/TransformWriter.h10
-rw-r--r--source/blender/io/collada/collada.h5
-rw-r--r--source/blender/io/collada/collada_internal.cpp2
-rw-r--r--source/blender/io/collada/collada_internal.h5
-rw-r--r--source/blender/io/collada/collada_utils.cpp9
-rw-r--r--source/blender/io/collada/collada_utils.h7
-rw-r--r--source/blender/io/common/CMakeLists.txt19
-rw-r--r--source/blender/io/common/IO_abstract_hierarchy_iterator.h61
-rw-r--r--source/blender/io/common/IO_dupli_persistent_id.hh65
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator.cc108
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc319
-rw-r--r--source/blender/io/common/intern/dupli_parent_finder.cc104
-rw-r--r--source/blender/io/common/intern/dupli_parent_finder.hh59
-rw-r--r--source/blender/io/common/intern/dupli_persistent_id.cc167
-rw-r--r--source/blender/io/common/intern/hierarchy_context_order_test.cc127
-rw-r--r--source/blender/io/common/intern/object_identifier.cc116
-rw-r--r--source/blender/io/common/intern/object_identifier_test.cc234
-rw-r--r--source/blender/io/usd/CMakeLists.txt12
-rw-r--r--source/blender/io/usd/intern/usd_capi.cc7
-rw-r--r--source/blender/io/usd/intern/usd_exporter_context.h5
-rw-r--r--source/blender/io/usd/intern/usd_hierarchy_iterator.cc8
-rw-r--r--source/blender/io/usd/intern/usd_hierarchy_iterator.h7
-rw-r--r--source/blender/io/usd/intern/usd_writer_abstract.h5
-rw-r--r--source/blender/io/usd/intern/usd_writer_camera.h5
-rw-r--r--source/blender/io/usd/intern/usd_writer_hair.cc2
-rw-r--r--source/blender/io/usd/intern/usd_writer_hair.h5
-rw-r--r--source/blender/io/usd/intern/usd_writer_light.h5
-rw-r--r--source/blender/io/usd/intern/usd_writer_mesh.cc2
-rw-r--r--source/blender/io/usd/intern/usd_writer_mesh.h5
-rw-r--r--source/blender/io/usd/intern/usd_writer_metaball.h5
-rw-r--r--source/blender/io/usd/intern/usd_writer_transform.cc3
-rw-r--r--source/blender/io/usd/intern/usd_writer_transform.h5
-rw-r--r--source/blender/io/usd/tests/usd_stage_creation_test.cc70
-rw-r--r--source/blender/io/usd/usd.h5
-rw-r--r--source/blender/makesdna/DNA_ID.h27
-rw-r--r--source/blender/makesdna/DNA_action_types.h8
-rw-r--r--source/blender/makesdna/DNA_anim_types.h5
-rw-r--r--source/blender/makesdna/DNA_armature_types.h5
-rw-r--r--source/blender/makesdna/DNA_boid_types.h5
-rw-r--r--source/blender/makesdna/DNA_brush_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_brush_types.h76
-rw-r--r--source/blender/makesdna/DNA_cachefile_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_cachefile_types.h18
-rw-r--r--source/blender/makesdna/DNA_camera_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_camera_types.h5
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h5
-rw-r--r--source/blender/makesdna/DNA_collection_types.h5
-rw-r--r--source/blender/makesdna/DNA_color_types.h5
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h5
-rw-r--r--source/blender/makesdna/DNA_curve_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_curve_types.h14
-rw-r--r--source/blender/makesdna/DNA_curveprofile_types.h7
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h17
-rw-r--r--source/blender/makesdna/DNA_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_defs.h5
-rw-r--r--source/blender/makesdna/DNA_dynamicpaint_types.h5
-rw-r--r--source/blender/makesdna/DNA_effect_types.h5
-rw-r--r--source/blender/makesdna/DNA_fileglobal_types.h5
-rw-r--r--source/blender/makesdna/DNA_fluid_types.h16
-rw-r--r--source/blender/makesdna/DNA_freestyle_types.h5
-rw-r--r--source/blender/makesdna/DNA_genfile.h11
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h5
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h5
-rw-r--r--source/blender/makesdna/DNA_gpu_types.h5
-rw-r--r--source/blender/makesdna/DNA_hair_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_hair_types.h5
-rw-r--r--source/blender/makesdna/DNA_image_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_image_types.h23
-rw-r--r--source/blender/makesdna/DNA_ipo_types.h5
-rw-r--r--source/blender/makesdna/DNA_key_types.h5
-rw-r--r--source/blender/makesdna/DNA_lattice_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_lattice_types.h5
-rw-r--r--source/blender/makesdna/DNA_layer_types.h6
-rw-r--r--source/blender/makesdna/DNA_light_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_light_types.h5
-rw-r--r--source/blender/makesdna/DNA_lightprobe_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_lightprobe_types.h11
-rw-r--r--source/blender/makesdna/DNA_linestyle_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_linestyle_types.h5
-rw-r--r--source/blender/makesdna/DNA_listBase.h5
-rw-r--r--source/blender/makesdna/DNA_mask_types.h5
-rw-r--r--source/blender/makesdna/DNA_material_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_material_types.h4
-rw-r--r--source/blender/makesdna/DNA_mesh_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h5
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h5
-rw-r--r--source/blender/makesdna/DNA_meta_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_meta_types.h5
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h55
-rw-r--r--source/blender/makesdna/DNA_movieclip_types.h9
-rw-r--r--source/blender/makesdna/DNA_nla_types.h5
-rw-r--r--source/blender/makesdna/DNA_node_types.h10
-rw-r--r--source/blender/makesdna/DNA_object_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_object_enums.h5
-rw-r--r--source/blender/makesdna/DNA_object_fluidsim_types.h5
-rw-r--r--source/blender/makesdna/DNA_object_force_types.h5
-rw-r--r--source/blender/makesdna/DNA_object_types.h33
-rw-r--r--source/blender/makesdna/DNA_outliner_types.h5
-rw-r--r--source/blender/makesdna/DNA_packedFile_types.h5
-rw-r--r--source/blender/makesdna/DNA_particle_types.h5
-rw-r--r--source/blender/makesdna/DNA_pointcache_types.h5
-rw-r--r--source/blender/makesdna/DNA_pointcloud_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_pointcloud_types.h5
-rw-r--r--source/blender/makesdna/DNA_rigidbody_types.h7
-rw-r--r--source/blender/makesdna/DNA_scene_defaults.h4
-rw-r--r--source/blender/makesdna/DNA_scene_types.h7
-rw-r--r--source/blender/makesdna/DNA_screen_types.h14
-rw-r--r--source/blender/makesdna/DNA_sdna_types.h5
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h13
-rw-r--r--source/blender/makesdna/DNA_session_uuid_types.h43
-rw-r--r--source/blender/makesdna/DNA_shader_fx_types.h4
-rw-r--r--source/blender/makesdna/DNA_simulation_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_simulation_types.h68
-rw-r--r--source/blender/makesdna/DNA_sound_types.h5
-rw-r--r--source/blender/makesdna/DNA_space_types.h10
-rw-r--r--source/blender/makesdna/DNA_speaker_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_speaker_types.h5
-rw-r--r--source/blender/makesdna/DNA_text_types.h5
-rw-r--r--source/blender/makesdna/DNA_texture_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_texture_types.h5
-rw-r--r--source/blender/makesdna/DNA_tracking_types.h5
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h32
-rw-r--r--source/blender/makesdna/DNA_vec_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_vec_types.h5
-rw-r--r--source/blender/makesdna/DNA_vfont_types.h5
-rw-r--r--source/blender/makesdna/DNA_view2d_types.h7
-rw-r--r--source/blender/makesdna/DNA_view3d_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_view3d_enums.h5
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h6
-rw-r--r--source/blender/makesdna/DNA_volume_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_volume_types.h5
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h9
-rw-r--r--source/blender/makesdna/DNA_workspace_types.h5
-rw-r--r--source/blender/makesdna/DNA_world_defaults.h5
-rw-r--r--source/blender/makesdna/DNA_world_types.h11
-rw-r--r--source/blender/makesdna/DNA_xr_types.h5
-rw-r--r--source/blender/makesdna/intern/CMakeLists.txt3
-rw-r--r--source/blender/makesdna/intern/dna_rename_defs.h2
-rw-r--r--source/blender/makesdna/intern/dna_utils.c17
-rw-r--r--source/blender/makesdna/intern/dna_utils.h5
-rw-r--r--source/blender/makesdna/intern/makesdna.c18
-rw-r--r--source/blender/makesrna/RNA_access.h17
-rw-r--r--source/blender/makesrna/RNA_define.h5
-rw-r--r--source/blender/makesrna/RNA_enum_types.h5
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt15
-rw-r--r--source/blender/makesrna/intern/makesrna.c84
-rw-r--r--source/blender/makesrna/intern/rna_ID.c3
-rw-r--r--source/blender/makesrna/intern/rna_access.c86
-rw-r--r--source/blender/makesrna/intern/rna_access_compare_override.c209
-rw-r--r--source/blender/makesrna/intern/rna_access_internal.h10
-rw-r--r--source/blender/makesrna/intern/rna_brush.c187
-rw-r--r--source/blender/makesrna/intern/rna_cachefile.c26
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c10
-rw-r--r--source/blender/makesrna/intern/rna_color.c2
-rw-r--r--source/blender/makesrna/intern/rna_context.c2
-rw-r--r--source/blender/makesrna/intern/rna_curve.c8
-rw-r--r--source/blender/makesrna/intern/rna_curve_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_curveprofile.c2
-rw-r--r--source/blender/makesrna/intern/rna_depsgraph.c2
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c2
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c105
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c3
-rw-r--r--source/blender/makesrna/intern/rna_image.c7
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c15
-rw-r--r--source/blender/makesrna/intern/rna_internal.h21
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h56
-rw-r--r--source/blender/makesrna/intern/rna_layer.c2
-rw-r--r--source/blender/makesrna/intern/rna_main.c4
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c2
-rw-r--r--source/blender/makesrna/intern/rna_mesh_utils.h5
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c188
-rw-r--r--source/blender/makesrna/intern/rna_movieclip.c2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c68
-rw-r--r--source/blender/makesrna/intern/rna_object.c18
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c4
-rw-r--r--source/blender/makesrna/intern/rna_particle.c6
-rw-r--r--source/blender/makesrna/intern/rna_render.c25
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c5
-rw-r--r--source/blender/makesrna/intern/rna_rna.c231
-rw-r--r--source/blender/makesrna/intern/rna_scene.c37
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c13
-rw-r--r--source/blender/makesrna/intern/rna_screen.c35
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c92
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c44
-rw-r--r--source/blender/makesrna/intern/rna_shader_fx.c106
-rw-r--r--source/blender/makesrna/intern/rna_space.c99
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c69
-rw-r--r--source/blender/modifiers/CMakeLists.txt2
-rw-r--r--source/blender/modifiers/MOD_modifiertypes.h5
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c7
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c19
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c7
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c12
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c116
-rw-r--r--source/blender/modifiers/intern/MOD_lattice.c7
-rw-r--r--source/blender/modifiers/intern/MOD_mask.cc5
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_util.h5
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c5
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c22
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c167
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c40
-rw-r--r--source/blender/modifiers/intern/MOD_simulation.cc67
-rw-r--r--source/blender/modifiers/intern/MOD_smooth.c4
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_extrude.c2
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_util.h5
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c43
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c4
-rw-r--r--source/blender/modifiers/intern/MOD_ui_common.c45
-rw-r--r--source/blender/modifiers/intern/MOD_ui_common.h5
-rw-r--r--source/blender/modifiers/intern/MOD_util.h4
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c2
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c4
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.h4
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c2
-rw-r--r--source/blender/nodes/CMakeLists.txt34
-rw-r--r--source/blender/nodes/NOD_common.h5
-rw-r--r--source/blender/nodes/NOD_composite.h5
-rw-r--r--source/blender/nodes/NOD_derived_node_tree.hh (renamed from source/blender/blenkernel/BKE_derived_node_tree.hh)99
-rw-r--r--source/blender/nodes/NOD_function.h7
-rw-r--r--source/blender/nodes/NOD_node_tree_dependencies.hh76
-rw-r--r--source/blender/nodes/NOD_node_tree_multi_function.hh388
-rw-r--r--source/blender/nodes/NOD_node_tree_ref.hh (renamed from source/blender/blenkernel/BKE_node_tree_ref.hh)66
-rw-r--r--source/blender/nodes/NOD_shader.h5
-rw-r--r--source/blender/nodes/NOD_simulation.h7
-rw-r--r--source/blender/nodes/NOD_socket.h10
-rw-r--r--source/blender/nodes/NOD_static_types.h4
-rw-r--r--source/blender/nodes/NOD_texture.h5
-rw-r--r--source/blender/nodes/composite/node_composite_util.h5
-rw-r--r--source/blender/nodes/function/node_function_util.cc2
-rw-r--r--source/blender/nodes/function/node_function_util.hh (renamed from source/blender/nodes/function/node_function_util.h)9
-rw-r--r--source/blender/nodes/function/nodes/node_fn_boolean_math.cc30
-rw-r--r--source/blender/nodes/function/nodes/node_fn_combine_strings.cc27
-rw-r--r--source/blender/nodes/function/nodes/node_fn_float_compare.cc45
-rw-r--r--source/blender/nodes/function/nodes/node_fn_group_instance_id.cc32
-rw-r--r--source/blender/nodes/function/nodes/node_fn_object_transforms.cc88
-rw-r--r--source/blender/nodes/function/nodes/node_fn_random_float.cc89
-rw-r--r--source/blender/nodes/function/nodes/node_fn_switch.cc2
-rw-r--r--source/blender/nodes/intern/derived_node_tree.cc (renamed from source/blender/blenkernel/intern/derived_node_tree.cc)28
-rw-r--r--source/blender/nodes/intern/node_common.c3
-rw-r--r--source/blender/nodes/intern/node_common.h5
-rw-r--r--source/blender/nodes/intern/node_exec.h5
-rw-r--r--source/blender/nodes/intern/node_socket.cc217
-rw-r--r--source/blender/nodes/intern/node_tree_dependencies.cc57
-rw-r--r--source/blender/nodes/intern/node_tree_multi_function.cc344
-rw-r--r--source/blender/nodes/intern/node_tree_ref.cc (renamed from source/blender/blenkernel/intern/node_tree_ref.cc)12
-rw-r--r--source/blender/nodes/intern/node_util.c2
-rw-r--r--source/blender/nodes/intern/node_util.h5
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c14
-rw-r--r--source/blender/nodes/shader/node_shader_util.h13
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_clamp.cc (renamed from source/blender/nodes/shader/nodes/node_shader_clamp.c)25
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geometry.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_map_range.cc (renamed from source/blender/nodes/shader/nodes/node_shader_map_range.c)90
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c115
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.cc387
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc (renamed from source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c)45
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc (renamed from source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c)45
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.c171
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.cc (renamed from source/blender/nodes/shader/nodes/node_shader_valToRgb.c)48
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_value.cc (renamed from source/blender/nodes/shader/nodes/node_shader_value.c)10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_math.c144
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_math.cc292
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vertex_color.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_wireframe.c1
-rw-r--r--source/blender/nodes/simulation/node_simulation_util.h5
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc38
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc36
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc3
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc3
-rw-r--r--source/blender/nodes/texture/node_texture_util.h5
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_curves.c2
-rw-r--r--source/blender/python/BPY_extern.h17
-rw-r--r--source/blender/python/BPY_extern_clog.h5
-rw-r--r--source/blender/python/bmesh/bmesh_py_api.h5
-rw-r--r--source/blender/python/bmesh/bmesh_py_geometry.h5
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops.h5
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.h5
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.h5
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.h5
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.h5
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_select.h5
-rw-r--r--source/blender/python/bmesh/bmesh_py_utils.h5
-rw-r--r--source/blender/python/generic/CMakeLists.txt2
-rw-r--r--source/blender/python/generic/bgl.c2
-rw-r--r--source/blender/python/generic/bgl.h5
-rw-r--r--source/blender/python/generic/bl_math_py_api.c162
-rw-r--r--source/blender/python/generic/bl_math_py_api.h (renamed from source/blender/editors/include/ED_logic.h)24
-rw-r--r--source/blender/python/generic/blf_py_api.h5
-rw-r--r--source/blender/python/generic/idprop_py_api.h5
-rw-r--r--source/blender/python/generic/imbuf_py_api.h5
-rw-r--r--source/blender/python/generic/py_capi_utils.c165
-rw-r--r--source/blender/python/generic/py_capi_utils.h1
-rw-r--r--source/blender/python/generic/python_utildefines.h5
-rw-r--r--source/blender/python/gpu/gpu_py_api.c4
-rw-r--r--source/blender/python/gpu/gpu_py_api.h11
-rw-r--r--source/blender/python/gpu/gpu_py_batch.c7
-rw-r--r--source/blender/python/gpu/gpu_py_batch.h5
-rw-r--r--source/blender/python/gpu/gpu_py_element.h5
-rw-r--r--source/blender/python/gpu/gpu_py_matrix.h5
-rw-r--r--source/blender/python/gpu/gpu_py_offscreen.h5
-rw-r--r--source/blender/python/gpu/gpu_py_select.h5
-rw-r--r--source/blender/python/gpu/gpu_py_shader.h5
-rw-r--r--source/blender/python/gpu/gpu_py_types.h5
-rw-r--r--source/blender/python/gpu/gpu_py_vertex_buffer.h5
-rw-r--r--source/blender/python/gpu/gpu_py_vertex_format.h5
-rw-r--r--source/blender/python/intern/bpy.h11
-rw-r--r--source/blender/python/intern/bpy_app.c29
-rw-r--r--source/blender/python/intern/bpy_app.h11
-rw-r--r--source/blender/python/intern/bpy_app_alembic.h11
-rw-r--r--source/blender/python/intern/bpy_app_build_options.h11
-rw-r--r--source/blender/python/intern/bpy_app_ffmpeg.h11
-rw-r--r--source/blender/python/intern/bpy_app_handlers.h11
-rw-r--r--source/blender/python/intern/bpy_app_icons.h11
-rw-r--r--source/blender/python/intern/bpy_app_ocio.h11
-rw-r--r--source/blender/python/intern/bpy_app_oiio.h11
-rw-r--r--source/blender/python/intern/bpy_app_opensubdiv.h11
-rw-r--r--source/blender/python/intern/bpy_app_openvdb.h11
-rw-r--r--source/blender/python/intern/bpy_app_sdl.h11
-rw-r--r--source/blender/python/intern/bpy_app_timers.h11
-rw-r--r--source/blender/python/intern/bpy_app_translations.c8
-rw-r--r--source/blender/python/intern/bpy_app_translations.h11
-rw-r--r--source/blender/python/intern/bpy_app_usd.h11
-rw-r--r--source/blender/python/intern/bpy_capi_utils.c39
-rw-r--r--source/blender/python/intern/bpy_capi_utils.h15
-rw-r--r--source/blender/python/intern/bpy_driver.c78
-rw-r--r--source/blender/python/intern/bpy_driver.h11
-rw-r--r--source/blender/python/intern/bpy_gizmo_wrap.h11
-rw-r--r--source/blender/python/intern/bpy_interface.c68
-rw-r--r--source/blender/python/intern/bpy_intern_string.h11
-rw-r--r--source/blender/python/intern/bpy_library.h11
-rw-r--r--source/blender/python/intern/bpy_msgbus.h11
-rw-r--r--source/blender/python/intern/bpy_operator.h9
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.h9
-rw-r--r--source/blender/python/intern/bpy_path.h9
-rw-r--r--source/blender/python/intern/bpy_props.c364
-rw-r--r--source/blender/python/intern/bpy_props.h9
-rw-r--r--source/blender/python/intern/bpy_rna.c4
-rw-r--r--source/blender/python/intern/bpy_rna.h9
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c24
-rw-r--r--source/blender/python/intern/bpy_rna_anim.h11
-rw-r--r--source/blender/python/intern/bpy_rna_callback.h11
-rw-r--r--source/blender/python/intern/bpy_rna_driver.h11
-rw-r--r--source/blender/python/intern/bpy_rna_gizmo.h11
-rw-r--r--source/blender/python/intern/bpy_rna_id_collection.c2
-rw-r--r--source/blender/python/intern/bpy_rna_id_collection.h11
-rw-r--r--source/blender/python/intern/bpy_rna_types_capi.h11
-rw-r--r--source/blender/python/intern/bpy_traceback.c8
-rw-r--r--source/blender/python/intern/bpy_traceback.h11
-rw-r--r--source/blender/python/intern/bpy_utils_previews.h11
-rw-r--r--source/blender/python/intern/bpy_utils_units.h11
-rw-r--r--source/blender/python/mathutils/mathutils.h5
-rw-r--r--source/blender/python/mathutils/mathutils_Color.h5
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.h5
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c11
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.h5
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c13
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.h5
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c17
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.h5
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.h5
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c6
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.h5
-rw-r--r--source/blender/python/mathutils/mathutils_interpolate.h5
-rw-r--r--source/blender/python/mathutils/mathutils_kdtree.h5
-rw-r--r--source/blender/python/mathutils/mathutils_noise.h5
-rw-r--r--source/blender/render/CMakeLists.txt2
-rw-r--r--source/blender/render/extern/include/RE_bake.h11
-rw-r--r--source/blender/render/extern/include/RE_engine.h12
-rw-r--r--source/blender/render/extern/include/RE_multires_bake.h9
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h9
-rw-r--r--source/blender/render/extern/include/RE_render_ext.h11
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h5
-rw-r--r--source/blender/render/intern/include/initrender.h11
-rw-r--r--source/blender/render/intern/include/render_result.h11
-rw-r--r--source/blender/render/intern/include/render_types.h11
-rw-r--r--source/blender/render/intern/include/renderpipeline.h11
-rw-r--r--source/blender/render/intern/include/texture.h11
-rw-r--r--source/blender/render/intern/include/zbuf.h9
-rw-r--r--source/blender/render/intern/source/bake_api.c24
-rw-r--r--source/blender/render/intern/source/external_engine.c16
-rw-r--r--source/blender/render/intern/source/initrender.c12
-rw-r--r--source/blender/render/intern/source/multires_bake.c7
-rw-r--r--source/blender/render/intern/source/pipeline.c29
-rw-r--r--source/blender/render/intern/source/pointdensity.c2
-rw-r--r--source/blender/render/intern/source/render_texture.c2
-rw-r--r--source/blender/shader_fx/CMakeLists.txt2
-rw-r--r--source/blender/shader_fx/FX_shader_types.h5
-rw-r--r--source/blender/shader_fx/intern/FX_shader_rim.c8
-rw-r--r--source/blender/shader_fx/intern/FX_shader_util.h5
-rw-r--r--source/blender/shader_fx/intern/FX_ui_common.c25
-rw-r--r--source/blender/shader_fx/intern/FX_ui_common.h5
-rw-r--r--source/blender/simulation/CMakeLists.txt (renamed from source/blender/physics/CMakeLists.txt)33
-rw-r--r--source/blender/simulation/SIM_mass_spring.h (renamed from source/blender/physics/BPH_mass_spring.h)29
-rw-r--r--source/blender/simulation/SIM_simulation_update.hh31
-rw-r--r--source/blender/simulation/intern/ConstrainedConjugateGradient.h (renamed from source/blender/physics/intern/ConstrainedConjugateGradient.h)5
-rw-r--r--source/blender/simulation/intern/SIM_mass_spring.cpp (renamed from source/blender/physics/intern/BPH_mass_spring.cpp)156
-rw-r--r--source/blender/simulation/intern/eigen_utils.h (renamed from source/blender/physics/intern/eigen_utils.h)5
-rw-r--r--source/blender/simulation/intern/hair_volume.cpp (renamed from source/blender/physics/intern/hair_volume.cpp)28
-rw-r--r--source/blender/simulation/intern/implicit.h (renamed from source/blender/physics/intern/implicit.h)101
-rw-r--r--source/blender/simulation/intern/implicit_blender.c (renamed from source/blender/physics/intern/implicit_blender.c)102
-rw-r--r--source/blender/simulation/intern/implicit_eigen.cpp (renamed from source/blender/physics/intern/implicit_eigen.cpp)70
-rw-r--r--source/blender/simulation/intern/particle_allocator.cc86
-rw-r--r--source/blender/simulation/intern/particle_allocator.hh98
-rw-r--r--source/blender/simulation/intern/particle_function.cc167
-rw-r--r--source/blender/simulation/intern/particle_function.hh94
-rw-r--r--source/blender/simulation/intern/particle_mesh_emitter.cc362
-rw-r--r--source/blender/simulation/intern/particle_mesh_emitter.hh49
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.cc907
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.hh65
-rw-r--r--source/blender/simulation/intern/simulation_solver.cc522
-rw-r--r--source/blender/simulation/intern/simulation_solver.hh37
-rw-r--r--source/blender/simulation/intern/simulation_solver_influences.cc57
-rw-r--r--source/blender/simulation/intern/simulation_solver_influences.hh234
-rw-r--r--source/blender/simulation/intern/simulation_update.cc356
-rw-r--r--source/blender/simulation/intern/time_interval.hh90
-rw-r--r--source/blender/windowmanager/WM_api.h14
-rw-r--r--source/blender/windowmanager/WM_keymap.h5
-rw-r--r--source/blender/windowmanager/WM_message.h5
-rw-r--r--source/blender/windowmanager/WM_toolsystem.h5
-rw-r--r--source/blender/windowmanager/WM_types.h6
-rw-r--r--source/blender/windowmanager/gizmo/WM_gizmo_api.h11
-rw-r--r--source/blender/windowmanager/gizmo/WM_gizmo_types.h11
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo.c5
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c23
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h5
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c25
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c12
-rw-r--r--source/blender/windowmanager/gizmo/wm_gizmo_fn.h11
-rw-r--r--source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h11
-rw-r--r--source/blender/windowmanager/intern/wm.c12
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c6
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c10
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c124
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c323
-rw-r--r--source/blender/windowmanager/intern/wm_files.c35
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c210
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c35
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c20
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c8
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c16
-rw-r--r--source/blender/windowmanager/intern/wm_operator_type.c8
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c370
-rw-r--r--source/blender/windowmanager/intern/wm_platform_support.h5
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c26
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c25
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c13
-rw-r--r--source/blender/windowmanager/intern/wm_window.c52
-rw-r--r--source/blender/windowmanager/intern/wm_window_private.h5
-rw-r--r--source/blender/windowmanager/message_bus/intern/wm_message_bus_intern.h5
-rw-r--r--source/blender/windowmanager/message_bus/wm_message_bus.h11
-rw-r--r--source/blender/windowmanager/wm.h9
-rw-r--r--source/blender/windowmanager/wm_cursors.h11
-rw-r--r--source/blender/windowmanager/wm_draw.h13
-rw-r--r--source/blender/windowmanager/wm_event_system.h11
-rw-r--r--source/blender/windowmanager/wm_event_types.h11
-rw-r--r--source/blender/windowmanager/wm_files.h11
-rw-r--r--source/blender/windowmanager/wm_surface.h11
-rw-r--r--source/blender/windowmanager/wm_window.h11
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_intern.h5
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_session.c92
-rw-r--r--source/blender/windowmanager/xr/wm_xr.h5
2490 files changed, 51866 insertions, 30041 deletions
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index 593d972b0af..e178b0f7935 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -45,6 +45,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_hair_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ipo_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_key_types.h
@@ -71,12 +72,14 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_packedFile_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_particle_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_pointcache_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_pointcloud_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_rigidbody_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_scene_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_screen_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_sdna_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_sequence_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_shader_fx_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_simulation_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_sound_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_space_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_speaker_types.h
@@ -87,7 +90,9 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_vec_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_vfont_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_view2d_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_view3d_enums.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_view3d_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_volume_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_windowmanager_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_workspace_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_world_types.h
@@ -107,7 +112,7 @@ add_subdirectory(blentranslation)
add_subdirectory(blenloader)
add_subdirectory(depsgraph)
add_subdirectory(ikplugin)
-add_subdirectory(physics)
+add_subdirectory(simulation)
add_subdirectory(gpu)
add_subdirectory(imbuf)
add_subdirectory(nodes)
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 1d0cb2f524c..9013836fd1e 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -21,8 +21,7 @@
* \ingroup blf
*/
-#ifndef __BLF_API_H__
-#define __BLF_API_H__
+#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_sys_types.h"
@@ -305,5 +304,3 @@ struct ResultBLF {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLF_API_H__ */
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index da6224cff7f..ff31878a929 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -194,6 +194,8 @@ static GPUTexture *blf_batch_cache_texture_load(void)
int offset_x = bitmap_len_landed % tex_width;
int offset_y = bitmap_len_landed / tex_width;
+ GPU_texture_bind(gc->texture, 0);
+
/* TODO(germano): Update more than one row in a single call. */
while (remain) {
int remain_row = tex_width - offset_x;
@@ -297,7 +299,7 @@ void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
}
}
- err = FT_Set_Char_Size(font->face, 0, (FT_F26Dot6)(size * 64), dpi, dpi);
+ err = FT_Set_Char_Size(font->face, 0, ((FT_F26Dot6)(size)) * 64, dpi, dpi);
if (err) {
/* FIXME: here we can go through the fixed size and choice a close one */
printf("The current font don't support the size, %u and dpi, %u\n", size, dpi);
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 4ae592d323f..ba0873f4fd4 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -21,8 +21,7 @@
* \ingroup blf
*/
-#ifndef __BLF_INTERNAL_H__
-#define __BLF_INTERNAL_H__
+#pragma once
struct FontBLF;
struct GlyphBLF;
@@ -151,5 +150,3 @@ extern FT_Error FT_New_Face__win32_compat(FT_Library library,
FT_Face *aface);
# endif
#endif
-
-#endif /* __BLF_INTERNAL_H__ */
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 34b674670fd..36bb8769306 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -21,8 +21,7 @@
* \ingroup blf
*/
-#ifndef __BLF_INTERNAL_TYPES_H__
-#define __BLF_INTERNAL_TYPES_H__
+#pragma once
#include "GPU_texture.h"
#include "GPU_vertex_buffer.h"
@@ -258,5 +257,3 @@ typedef struct DirBLF {
/* full path where search fonts. */
char *path;
} DirBLF;
-
-#endif /* __BLF_INTERNAL_TYPES_H__ */
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 9162ed56655..76c610fb5bd 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_DERIVEDMESH_H__
-#define __BKE_DERIVEDMESH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -382,7 +381,6 @@ void DM_calc_loop_tangents(DerivedMesh *dm,
#ifndef NDEBUG
char *DM_debug_info(DerivedMesh *dm);
void DM_debug_print(DerivedMesh *dm);
-void DM_debug_print_cdlayers(CustomData *cdata);
bool DM_is_valid(DerivedMesh *dm);
#endif
@@ -390,5 +388,3 @@ bool DM_is_valid(DerivedMesh *dm);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DERIVEDMESH_H__ */
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 104582be932..e08604f02ad 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_ACTION_H__
-#define __BKE_ACTION_H__
+#pragma once
/** \file
* \ingroup bke
@@ -32,6 +31,7 @@ extern "C" {
#endif
/* The following structures are defined in DNA_action_types.h, and DNA_anim_types.h */
+struct AnimationEvalContext;
struct FCurve;
struct Main;
struct Object;
@@ -128,6 +128,8 @@ void BKE_pose_channel_free(struct bPoseChannel *pchan);
void BKE_pose_channel_free_ex(struct bPoseChannel *pchan, bool do_id_user);
void BKE_pose_channel_runtime_reset(struct bPoseChannel_Runtime *runtime);
+void BKE_pose_channel_runtime_reset_on_copy(struct bPoseChannel_Runtime *runtime);
+
void BKE_pose_channel_runtime_free(struct bPoseChannel_Runtime *runtime);
void BKE_pose_channel_free_bbone_cache(struct bPoseChannel_Runtime *runtime);
@@ -152,12 +154,15 @@ void BKE_pose_copy_data_ex(struct bPose **dst,
const bool copy_constraints);
void BKE_pose_copy_data(struct bPose **dst, const struct bPose *src, const bool copy_constraints);
void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from);
+void BKE_pose_channel_session_uuid_generate(struct bPoseChannel *pchan);
struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name);
struct bPoseChannel *BKE_pose_channel_active(struct Object *ob);
struct bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob);
struct bPoseChannel *BKE_pose_channel_verify(struct bPose *pose, const char *name);
struct bPoseChannel *BKE_pose_channel_get_mirrored(const struct bPose *pose, const char *name);
+void BKE_pose_check_uuids_unique_and_report(const struct bPose *pose);
+
#ifndef NDEBUG
bool BKE_pose_channels_is_valid(const struct bPose *pose);
#endif
@@ -202,14 +207,14 @@ void what_does_obaction(struct Object *ob,
struct bPose *pose,
struct bAction *act,
char groupname[],
- float cframe);
+ const struct AnimationEvalContext *anim_eval_context);
/* for proxy */
void BKE_pose_copy_pchan_result(struct bPoseChannel *pchanto,
const struct bPoseChannel *pchanfrom);
bool BKE_pose_copy_result(struct bPose *to, struct bPose *from);
-/* clear all transforms */
-void BKE_pose_rest(struct bPose *pose);
+/* Clear transforms. */
+void BKE_pose_rest(struct bPose *pose, bool selected_bones_only);
/* Tag pose for recalc. Also tag all related data to be recalc. */
void BKE_pose_tag_recalc(struct Main *bmain, struct bPose *pose);
@@ -217,5 +222,3 @@ void BKE_pose_tag_recalc(struct Main *bmain, struct bPose *pose);
#ifdef __cplusplus
};
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_addon.h b/source/blender/blenkernel/BKE_addon.h
index 741be17bb25..73e3f6e41dc 100644
--- a/source/blender/blenkernel/BKE_addon.h
+++ b/source/blender/blenkernel/BKE_addon.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_ADDON_H__
-#define __BKE_ADDON_H__
+#pragma once
/** \file
* \ingroup bke
@@ -56,5 +55,3 @@ void BKE_addon_free(struct bAddon *addon);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_ADDON_H__ */
diff --git a/source/blender/blenkernel/BKE_anim_data.h b/source/blender/blenkernel/BKE_anim_data.h
index 5aeaf4405f5..189e45f4fe5 100644
--- a/source/blender/blenkernel/BKE_anim_data.h
+++ b/source/blender/blenkernel/BKE_anim_data.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_ANIM_DATA_H__
-#define __BKE_ANIM_DATA_H__
+#pragma once
/** \file
* \ingroup bke
@@ -71,7 +70,11 @@ bool BKE_animdata_copy_id(struct Main *bmain,
const int flag);
/* Copy AnimData Actions */
-void BKE_animdata_copy_id_action(struct Main *bmain, struct ID *id, const bool set_newid);
+void BKE_animdata_copy_id_action(struct Main *bmain, struct ID *id);
+
+void BKE_animdata_duplicate_id_action(struct Main *bmain,
+ struct ID *id,
+ const uint duplicate_flags);
/* Merge copies of data from source AnimData block */
typedef enum eAnimData_MergeCopy_Modes {
@@ -94,5 +97,3 @@ void BKE_animdata_merge_copy(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_ANIM_DATA_H__*/
diff --git a/source/blender/blenkernel/BKE_anim_path.h b/source/blender/blenkernel/BKE_anim_path.h
index 4de853303ad..ae2d13530ed 100644
--- a/source/blender/blenkernel/BKE_anim_path.h
+++ b/source/blender/blenkernel/BKE_anim_path.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_ANIM_PATH_H__
-#define __BKE_ANIM_PATH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -47,5 +46,3 @@ bool where_on_path(const struct Object *ob,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_anim_visualization.h b/source/blender/blenkernel/BKE_anim_visualization.h
index 5dcbfa0919e..fb7875a112e 100644
--- a/source/blender/blenkernel/BKE_anim_visualization.h
+++ b/source/blender/blenkernel/BKE_anim_visualization.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_ANIM_VISUALIZATION_H__
-#define __BKE_ANIM_VISUALIZATION_H__
+#pragma once
/** \file
* \ingroup bke
@@ -52,5 +51,3 @@ struct bMotionPath *animviz_verify_motionpaths(struct ReportList *reports,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 4a2ad28f90f..ef74bb61a7e 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_ANIMSYS_H__
-#define __BKE_ANIMSYS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -48,6 +47,23 @@ struct bAction;
struct bActionGroup;
struct bContext;
+/* Container for data required to do FCurve and Driver evaluation. */
+typedef struct AnimationEvalContext {
+ /* For drivers, so that they have access to the dependency graph and the current view layer. See
+ * T77086. */
+ struct Depsgraph *depsgraph;
+
+ /* FCurves and Drivers can be evaluated at a different time than the current scene time, for
+ * example when evaluating NLA strips. This means that, even though the current time is stored in
+ * the dependency graph, we need an explicit evaluation time. */
+ float eval_time;
+} AnimationEvalContext;
+
+AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph,
+ float eval_time);
+AnimationEvalContext BKE_animsys_eval_context_construct_at(
+ const AnimationEvalContext *anim_eval_context, float eval_time);
+
/* ************************************* */
/* KeyingSets API */
@@ -131,17 +147,18 @@ bool BKE_animdata_fix_paths_remove(struct ID *id, const char *path);
/* -------------------------------------- */
+typedef struct AnimationBasePathChange {
+ struct AnimationBasePathChange *next, *prev;
+ const char *src_basepath;
+ const char *dst_basepath;
+} AnimationBasePathChange;
+
/* Move animation data from src to destination if it's paths are based on basepaths */
-void BKE_animdata_separate_by_basepath(struct Main *bmain,
+void BKE_animdata_transfer_by_basepath(struct Main *bmain,
struct ID *srcID,
struct ID *dstID,
struct ListBase *basepaths);
-/* Move F-Curves from src to destination if it's path is based on basepath */
-void action_move_fcurves_by_basepath(struct bAction *srcAct,
- struct bAction *dstAct,
- const char basepath[]);
-
char *BKE_animdata_driver_path_hack(struct bContext *C,
struct PointerRNA *ptr,
struct PropertyRNA *prop,
@@ -172,11 +189,12 @@ void BKE_fcurves_id_cb(struct ID *id, ID_FCurve_Edit_Callback func, void *user_d
typedef struct NlaKeyframingContext NlaKeyframingContext;
-struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache,
- struct PointerRNA *ptr,
- struct AnimData *adt,
- float ctime,
- const bool flush_to_original);
+struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
+ struct ListBase *cache,
+ struct PointerRNA *ptr,
+ struct AnimData *adt,
+ const struct AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original);
bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
struct PointerRNA *prop_ptr,
struct PropertyRNA *prop,
@@ -209,7 +227,7 @@ bool BKE_animsys_write_rna_setting(struct PathResolvedRNA *anim_rna, const float
/* Evaluation loop for evaluating animation data */
void BKE_animsys_evaluate_animdata(struct ID *id,
struct AnimData *adt,
- float ctime,
+ const struct AnimationEvalContext *anim_eval_context,
eAnimData_Recalc recalc,
const bool flush_to_original);
@@ -229,14 +247,14 @@ void BKE_animsys_evaluate_all_animation(struct Main *main,
/* Evaluate Action (F-Curve Bag) */
void animsys_evaluate_action(struct PointerRNA *ptr,
struct bAction *act,
- float ctime,
+ const struct AnimationEvalContext *anim_eval_context,
const bool flush_to_original);
/* Evaluate Action Group */
void animsys_evaluate_action_group(struct PointerRNA *ptr,
struct bAction *act,
struct bActionGroup *agrp,
- float ctime);
+ const struct AnimationEvalContext *anim_eval_context);
/* ************************************* */
@@ -257,5 +275,3 @@ void BKE_animsys_update_driver_array(struct ID *id);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_ANIMSYS_H__*/
diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h
index e49fc260810..b8a4497c7be 100644
--- a/source/blender/blenkernel/BKE_appdir.h
+++ b/source/blender/blenkernel/BKE_appdir.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_APPDIR_H__
-#define __BKE_APPDIR_H__
+#pragma once
/** \file
* \ingroup bli
@@ -101,5 +100,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_APPDIR_H__ */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 6fb6675a05a..6d48397b1af 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_ARMATURE_H__
-#define __BKE_ARMATURE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -123,22 +122,24 @@ void get_objectspace_bone_matrix(struct Bone *bone,
float M_accumulatedMatrix[4][4],
int root,
int posed);
-void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]);
-void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float mat[3][3]);
+void vec_roll_to_mat3(const float vec[3], const float roll, float r_mat[3][3]);
+void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float r_mat[3][3]);
void mat3_to_vec_roll(const float mat[3][3], float r_vec[3], float *r_roll);
void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll);
/* Common Conversions Between Co-ordinate Spaces */
-void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[4][4], float outmat[4][4]);
+void BKE_armature_mat_world_to_pose(struct Object *ob,
+ const float inmat[4][4],
+ float outmat[4][4]);
void BKE_armature_loc_world_to_pose(struct Object *ob, const float inloc[3], float outloc[3]);
void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan,
- float inmat[4][4],
+ const float inmat[4][4],
float outmat[4][4]);
void BKE_armature_loc_pose_to_bone(struct bPoseChannel *pchan,
const float inloc[3],
float outloc[3]);
void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan,
- float inmat[4][4],
+ const float inmat[4][4],
float outmat[4][4]);
void BKE_armature_mat_pose_to_delta(float delta_mat[4][4],
float pose_mat[4][4],
@@ -147,13 +148,13 @@ void BKE_armature_mat_pose_to_delta(float delta_mat[4][4],
void BKE_armature_mat_pose_to_bone_ex(struct Depsgraph *depsgraph,
struct Object *ob,
struct bPoseChannel *pchan,
- float inmat[4][4],
+ const float inmat[4][4],
float outmat[4][4]);
-void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], bool use_compat);
-void BKE_pchan_rot_to_mat3(const struct bPoseChannel *pchan, float mat[3][3]);
-void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], bool use_comat);
-void BKE_pchan_to_mat4(const struct bPoseChannel *pchan, float chan_mat[4][4]);
+void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, const float mat[3][3], bool use_compat);
+void BKE_pchan_rot_to_mat3(const struct bPoseChannel *pchan, float r_mat[3][3]);
+void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, const float mat[4][4], bool use_comat);
+void BKE_pchan_to_mat4(const struct bPoseChannel *pchan, float r_mat[4][4]);
void BKE_pchan_calc_mat(struct bPoseChannel *pchan);
/* Simple helper, computes the offset bone matrix. */
@@ -387,5 +388,3 @@ void BKE_armature_deform_coords_with_editmesh(const struct Object *ob_arm,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_autoexec.h b/source/blender/blenkernel/BKE_autoexec.h
index bb847d49a4b..84d83ae5d30 100644
--- a/source/blender/blenkernel/BKE_autoexec.h
+++ b/source/blender/blenkernel/BKE_autoexec.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_AUTOEXEC_H__
-#define __BKE_AUTOEXEC_H__
+#pragma once
/** \file
* \ingroup bke
@@ -29,5 +28,3 @@ bool BKE_autoexec_match(const char *path);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_AUTOEXEC_H__ */
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 3feba4b3a66..abc0ce1f092 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_BLENDER_H__
-#define __BKE_BLENDER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -54,5 +53,3 @@ void BKE_blender_atexit(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_H__ */
diff --git a/source/blender/blenkernel/BKE_blender_copybuffer.h b/source/blender/blenkernel/BKE_blender_copybuffer.h
index ca20d3d9bba..1dd6d495276 100644
--- a/source/blender/blenkernel/BKE_blender_copybuffer.h
+++ b/source/blender/blenkernel/BKE_blender_copybuffer.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDER_COPYBUFFER_H__
-#define __BKE_BLENDER_COPYBUFFER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -48,5 +47,3 @@ int BKE_copybuffer_paste(struct bContext *C,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_COPYBUFFER_H__ */
diff --git a/source/blender/blenkernel/BKE_blender_undo.h b/source/blender/blenkernel/BKE_blender_undo.h
index 4ecedbbfc1e..e5ce91df3fb 100644
--- a/source/blender/blenkernel/BKE_blender_undo.h
+++ b/source/blender/blenkernel/BKE_blender_undo.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDER_UNDO_H__
-#define __BKE_BLENDER_UNDO_H__
+#pragma once
/** \file
* \ingroup bke
@@ -41,5 +40,3 @@ void BKE_memfile_undo_free(struct MemFileUndoData *mfu);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_UNDO_H__ */
diff --git a/source/blender/blenkernel/BKE_blender_user_menu.h b/source/blender/blenkernel/BKE_blender_user_menu.h
index 805a343b976..8d00cde488e 100644
--- a/source/blender/blenkernel/BKE_blender_user_menu.h
+++ b/source/blender/blenkernel/BKE_blender_user_menu.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDER_USER_MENU_H__
-#define __BKE_BLENDER_USER_MENU_H__
+#pragma once
/** \file
* \ingroup bke
@@ -43,5 +42,3 @@ void BKE_blender_user_menu_item_free_list(struct ListBase *lb);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_USER_MENU_H__ */
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 229b5193e9c..ae0a669bfb3 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDER_VERSION_H__
-#define __BKE_BLENDER_VERSION_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -32,7 +31,7 @@ extern "C" {
*/
/* Blender major and minor version. */
-#define BLENDER_VERSION 290
+#define BLENDER_VERSION 291
/* Blender patch version for bugfix releases. */
#define BLENDER_VERSION_PATCH 0
/** Blender release cycle stage: alpha/beta/rc/release. */
@@ -40,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 5
+#define BLENDER_FILE_SUBVERSION 0
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
@@ -54,5 +53,3 @@ const char *BKE_blender_version_string(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDER_VERSION_H__ */
diff --git a/source/blender/blenkernel/BKE_blendfile.h b/source/blender/blenkernel/BKE_blendfile.h
index e835137bfa1..94d203eeb2c 100644
--- a/source/blender/blenkernel/BKE_blendfile.h
+++ b/source/blender/blenkernel/BKE_blendfile.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BLENDFILE_H__
-#define __BKE_BLENDFILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -81,5 +80,3 @@ void BKE_blendfile_write_partial_end(struct Main *bmain_src);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BLENDFILE_H__ */
diff --git a/source/blender/blenkernel/BKE_boids.h b/source/blender/blenkernel/BKE_boids.h
index f9fd814b5f2..c9e6f0e7346 100644
--- a/source/blender/blenkernel/BKE_boids.h
+++ b/source/blender/blenkernel/BKE_boids.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_BOIDS_H__
-#define __BKE_BOIDS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -62,5 +61,3 @@ BoidState *boid_get_current_state(BoidSettings *boids);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_bpath.h b/source/blender/blenkernel/BKE_bpath.h
index cc8dd0d5b33..787dc4d1147 100644
--- a/source/blender/blenkernel/BKE_bpath.h
+++ b/source/blender/blenkernel/BKE_bpath.h
@@ -20,8 +20,7 @@
* so for BPath we don't need to malloc
*/
-#ifndef __BKE_BPATH_H__
-#define __BKE_BPATH_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -92,5 +91,3 @@ void BKE_bpath_absolute_convert(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_BPATH_H__ */
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 4e9430ab3e1..af299c917eb 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_BRUSH_H__
-#define __BKE_BRUSH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -157,5 +156,3 @@ void BKE_brush_debug_print_state(struct Brush *br);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index 5d7e8fe743e..e973bee9e20 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2006 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_BVHUTILS_H__
-#define __BKE_BVHUTILS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -263,5 +262,3 @@ void bvhcache_free(struct BVHCache *bvh_cache);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_cachefile.h b/source/blender/blenkernel/BKE_cachefile.h
index 596085f9c6f..9912b4e4b70 100644
--- a/source/blender/blenkernel/BKE_cachefile.h
+++ b/source/blender/blenkernel/BKE_cachefile.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CACHEFILE_H__
-#define __BKE_CACHEFILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -66,5 +65,3 @@ void BKE_cachefile_reader_free(struct CacheFile *cache_file, struct CacheReader
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_CACHEFILE_H__ */
diff --git a/source/blender/blenkernel/BKE_callbacks.h b/source/blender/blenkernel/BKE_callbacks.h
index 284948da634..fadba5644de 100644
--- a/source/blender/blenkernel/BKE_callbacks.h
+++ b/source/blender/blenkernel/BKE_callbacks.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __BKE_CALLBACKS_H__
-#define __BKE_CALLBACKS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -88,5 +87,3 @@ void BKE_callback_global_finalize(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_CALLBACKS_H__ */
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 812f5d520d7..533d5ae13cd 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CAMERA_H__
-#define __BKE_CAMERA_H__
+#pragma once
/** \file
* \ingroup bke
@@ -167,5 +166,3 @@ void BKE_camera_background_image_clear(struct Camera *cam);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_ccg.h b/source/blender/blenkernel/BKE_ccg.h
index ad1e05ee367..acdaa81da8d 100644
--- a/source/blender/blenkernel/BKE_ccg.h
+++ b/source/blender/blenkernel/BKE_ccg.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CCG_H__
-#define __BKE_CCG_H__
+#pragma once
/** \file
* \ingroup bke
@@ -166,5 +165,3 @@ BLI_INLINE CCGElem *CCG_elem_next(const CCGKey *key, CCGElem *elem)
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index dd7d20c0407..e997678001f 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -26,8 +26,7 @@
* \note This is deprecated & should eventually be removed.
*/
-#ifndef __BKE_CDDERIVEDMESH_H__
-#define __BKE_CDDERIVEDMESH_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -49,5 +48,3 @@ struct DerivedMesh *CDDM_copy(struct DerivedMesh *dm);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index f25482570b1..5af37829577 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_CLOTH_H__
-#define __BKE_CLOTH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -93,10 +92,10 @@ typedef struct Cloth {
struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
struct EdgeSet *edgeset; /* used for selfcollisions */
int last_frame;
- float initial_mesh_volume; /* Initial volume of the mesh. Used for pressure */
- float average_acceleration[3]; /* Moving average of overall acceleration. */
- struct MEdge *edges; /* Used for hair collisions. */
- struct GHash *sew_edge_graph; /* Sewing edges represented using a GHash */
+ float initial_mesh_volume; /* Initial volume of the mesh. Used for pressure */
+ float average_acceleration[3]; /* Moving average of overall acceleration. */
+ struct MEdge *edges; /* Used for hair collisions. */
+ struct EdgeSet *sew_edge_graph; /* Sewing edges represented using a GHash */
} Cloth;
/**
@@ -307,5 +306,3 @@ void cloth_parallel_transport_hair_frame(float mat[3][3],
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 4cf33640ebd..f4393742dff 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_COLLECTION_H__
-#define __BKE_COLLECTION_H__
+#pragma once
/** \file
* \ingroup bke
@@ -56,6 +55,10 @@ void BKE_collection_add_from_object(struct Main *bmain,
struct Scene *scene,
const struct Object *ob_src,
struct Collection *collection_dst);
+void BKE_collection_add_from_collection(struct Main *bmain,
+ struct Scene *scene,
+ struct Collection *collection_src,
+ struct Collection *collection_dst);
void BKE_collection_free(struct Collection *collection);
bool BKE_collection_delete(struct Main *bmain, struct Collection *collection, bool hierarchy);
@@ -149,7 +152,8 @@ bool BKE_collection_move(struct Main *bmain,
bool relative_after,
struct Collection *collection);
-bool BKE_collection_find_cycle(struct Collection *new_ancestor, struct Collection *collection);
+bool BKE_collection_cycle_find(struct Collection *new_ancestor, struct Collection *collection);
+bool BKE_collection_cycles_fix(struct Main *bmain, struct Collection *collection);
bool BKE_collection_has_collection(struct Collection *parent, struct Collection *collection);
@@ -250,5 +254,3 @@ void BKE_scene_objects_iterator_end(struct BLI_Iterator *iter);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_COLLECTION_H__ */
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index c3ecd0b7ed0..579adb61057 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_COLLISION_H__
-#define __BKE_COLLISION_H__
+#pragma once
/** \file
* \ingroup bke
@@ -178,5 +177,3 @@ void BKE_collider_cache_free(struct ListBase **colliders);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_colorband.h b/source/blender/blenkernel/BKE_colorband.h
index 355682671fe..6ac96a1ed36 100644
--- a/source/blender/blenkernel/BKE_colorband.h
+++ b/source/blender/blenkernel/BKE_colorband.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_COLORBAND_H__
-#define __BKE_COLORBAND_H__
+#pragma once
/** \file
* \ingroup bke
@@ -47,5 +46,3 @@ void BKE_colorband_update_sort(struct ColorBand *coba);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_COLORBAND_H__ */
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index 0623e0e5395..1ada83c0163 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2006 Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_COLORTOOLS_H__
-#define __BKE_COLORTOOLS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -70,7 +69,7 @@ void BKE_curvemapping_changed(struct CurveMapping *cumap, const bool rem_doubles
void BKE_curvemapping_changed_all(struct CurveMapping *cumap);
/* call before _all_ evaluation functions */
-void BKE_curvemapping_initialize(struct CurveMapping *cumap);
+void BKE_curvemapping_init(struct CurveMapping *cumap);
/* keep these (const CurveMap) - to help with thread safety */
/* single curve, no table check */
@@ -152,5 +151,3 @@ bool BKE_color_managed_colorspace_settings_equals(
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 8d7fe875c37..94349f4db22 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CONSTRAINT_H__
-#define __BKE_CONSTRAINT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -224,5 +223,3 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 70ca29d5795..eb26f1c3969 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CONTEXT_H__
-#define __BKE_CONTEXT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -312,6 +311,8 @@ int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
+bool CTX_wm_interface_locked(const bContext *C);
+
/* Gets pointer to the dependency graph.
* If it doesn't exist yet, it will be allocated.
*
@@ -344,5 +345,3 @@ struct Depsgraph *CTX_data_depsgraph_on_load(const bContext *C);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_crazyspace.h b/source/blender/blenkernel/BKE_crazyspace.h
index 6ac6b17d468..b95be70379f 100644
--- a/source/blender/blenkernel/BKE_crazyspace.h
+++ b/source/blender/blenkernel/BKE_crazyspace.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_CRAZYSPACE_H__
-#define __BKE_CRAZYSPACE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -65,5 +64,3 @@ void BKE_crazyspace_build_sculpt(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index d32ab474229..0bd4e3a7582 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_CURVE_H__
-#define __BKE_CURVE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -98,15 +97,15 @@ bool BKE_curve_minmax(struct Curve *cu, bool use_radius, float min[3], float max
bool BKE_curve_center_median(struct Curve *cu, float cent[3]);
bool BKE_curve_center_bounds(struct Curve *cu, float cent[3]);
void BKE_curve_transform_ex(struct Curve *cu,
- float mat[4][4],
+ const float mat[4][4],
const bool do_keys,
const bool do_props,
const float unit_scale);
void BKE_curve_transform(struct Curve *cu,
- float mat[4][4],
+ const float mat[4][4],
const bool do_keys,
const bool do_props);
-void BKE_curve_translate(struct Curve *cu, float offset[3], const bool do_keys);
+void BKE_curve_translate(struct Curve *cu, const float offset[3], const bool do_keys);
void BKE_curve_material_index_remove(struct Curve *cu, int index);
bool BKE_curve_material_index_used(struct Curve *cu, int index);
void BKE_curve_material_index_clear(struct Curve *cu);
@@ -140,7 +139,7 @@ void BKE_curve_nurbs_vert_coords_apply(struct ListBase *lb,
float (*BKE_curve_nurbs_key_vert_coords_alloc(struct ListBase *lb,
float *key,
int *r_vert_len))[3];
-void BKE_curve_nurbs_key_vert_tilts_apply(struct ListBase *lb, float *key);
+void BKE_curve_nurbs_key_vert_tilts_apply(struct ListBase *lb, const float *key);
void BKE_curve_editNurb_keyIndex_delCV(struct GHash *keyindex, const void *cv);
void BKE_curve_editNurb_keyIndex_free(struct GHash **keyindex);
@@ -339,5 +338,3 @@ void BKE_curve_deform_co(const struct Object *ob_curve,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_CURVE_H__ */
diff --git a/source/blender/blenkernel/BKE_curveprofile.h b/source/blender/blenkernel/BKE_curveprofile.h
index 877ab887138..9c72a866fa9 100644
--- a/source/blender/blenkernel/BKE_curveprofile.h
+++ b/source/blender/blenkernel/BKE_curveprofile.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_CURVEPROFILE_H__
-#define __BKE_CURVEPROFILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -72,7 +71,7 @@ void BKE_curveprofile_create_samples(struct CurveProfile *profile,
bool sample_straight_edges,
struct CurveProfilePoint *r_samples);
-void BKE_curveprofile_initialize(struct CurveProfile *profile, short segments_len);
+void BKE_curveprofile_init(struct CurveProfile *profile, short segments_len);
/* Called for a complete update of the widget after modifications */
enum {
@@ -101,5 +100,3 @@ void BKE_curveprofile_blend_read(struct BlendDataReader *reader, struct CurvePro
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 42beda352f5..92bfa3a9490 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -22,8 +22,7 @@
* \brief CustomData interface, see also DNA_customdata_types.h.
*/
-#ifndef __BKE_CUSTOMDATA_H__
-#define __BKE_CUSTOMDATA_H__
+#pragma once
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
@@ -455,6 +454,7 @@ bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *ldata, bool f
bool CustomData_layer_validate(struct CustomDataLayer *layer,
const uint totitems,
const bool do_fixes);
+void CustomData_layers__print(struct CustomData *data);
/* External file storage */
@@ -574,5 +574,3 @@ void CustomData_data_transfer(const struct MeshPairRemap *me_remap,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_customdata_file.h b/source/blender/blenkernel/BKE_customdata_file.h
index 2be2f71a168..f9f02204bb9 100644
--- a/source/blender/blenkernel/BKE_customdata_file.h
+++ b/source/blender/blenkernel/BKE_customdata_file.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_CUSTOMDATA_FILE_H__
-#define __BKE_CUSTOMDATA_FILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -60,5 +59,3 @@ CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, const char *name, size_t
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_CUSTOMDATA_FILE_H__ */
diff --git a/source/blender/blenkernel/BKE_data_transfer.h b/source/blender/blenkernel/BKE_data_transfer.h
index a723a9ed38c..d861baba14d 100644
--- a/source/blender/blenkernel/BKE_data_transfer.h
+++ b/source/blender/blenkernel/BKE_data_transfer.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_DATA_TRANSFER_H__
-#define __BKE_DATA_TRANSFER_H__
+#pragma once
#include "BKE_customdata.h"
@@ -181,5 +180,3 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DATA_TRANSFER_H__ */
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 04b85aebb39..35111d5240e 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_DEFORM_H__
-#define __BKE_DEFORM_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -111,7 +110,7 @@ void BKE_defvert_sync_mapped(struct MDeformVert *dvert_dst,
const int *flip_map,
const int flip_map_len,
const bool use_ensure);
-void BKE_defvert_remap(struct MDeformVert *dvert, int *map, const int map_len);
+void BKE_defvert_remap(struct MDeformVert *dvert, const int *map, const int map_len);
void BKE_defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
void BKE_defvert_flip_merged(struct MDeformVert *dvert,
const int *flip_map,
@@ -166,5 +165,3 @@ void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DEFORM_H__ */
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index b7e4acdc636..7e1a6e54ede 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_DISPLIST_H__
-#define __BKE_DISPLIST_H__
+#pragma once
/** \file
* \ingroup bke
@@ -119,5 +118,3 @@ void BKE_displist_minmax(struct ListBase *dispbase, float min[3], float max[3]);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_displist_tangent.h b/source/blender/blenkernel/BKE_displist_tangent.h
index 5e1c6ac8a21..c91c2c97dda 100644
--- a/source/blender/blenkernel/BKE_displist_tangent.h
+++ b/source/blender/blenkernel/BKE_displist_tangent.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_DISPLIST_TANGENT_H__
-#define __BKE_DISPLIST_TANGENT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -30,5 +29,3 @@ void BKE_displist_tangent_calc(const DispList *dl, float (*fnormals)[3], float (
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DISPLIST_TANGENT_H__ */
diff --git a/source/blender/blenkernel/BKE_duplilist.h b/source/blender/blenkernel/BKE_duplilist.h
index 71b6d06b450..c142d5338d1 100644
--- a/source/blender/blenkernel/BKE_duplilist.h
+++ b/source/blender/blenkernel/BKE_duplilist.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_DUPLILIST_H__
-#define __BKE_DUPLILIST_H__
+#pragma once
/** \file
* \ingroup bke
@@ -52,7 +51,7 @@ typedef struct DupliObject {
/* 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 */
+ int persistent_id[8]; /* MAX_DUPLI_RECUR */
/* Particle this dupli was generated from. */
struct ParticleSystem *particle_system;
@@ -64,5 +63,3 @@ typedef struct DupliObject {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h
index 5e3603a8339..99b58b2f40a 100644
--- a/source/blender/blenkernel/BKE_dynamicpaint.h
+++ b/source/blender/blenkernel/BKE_dynamicpaint.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_DYNAMICPAINT_H__
-#define __BKE_DYNAMICPAINT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -124,5 +123,3 @@ void dynamicPaint_outputSurfaceImage(struct DynamicPaintSurface *surface,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_DYNAMICPAINT_H__ */
diff --git a/source/blender/blenkernel/BKE_editlattice.h b/source/blender/blenkernel/BKE_editlattice.h
index c587ddb551b..be791487c27 100644
--- a/source/blender/blenkernel/BKE_editlattice.h
+++ b/source/blender/blenkernel/BKE_editlattice.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __BKE_EDITLATTICE_H__
-#define __BKE_EDITLATTICE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -34,5 +33,3 @@ void BKE_editlattice_load(struct Object *obedit);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITLATTICE_H__ */
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 9bd62858902..819e91b438e 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_EDITMESH_H__
-#define __BKE_EDITMESH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -107,5 +106,3 @@ struct BoundBox *BKE_editmesh_cage_boundbox_get(BMEditMesh *em);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITMESH_H__ */
diff --git a/source/blender/blenkernel/BKE_editmesh_bvh.h b/source/blender/blenkernel/BKE_editmesh_bvh.h
index b8d1e26fad2..8f8e573ee2f 100644
--- a/source/blender/blenkernel/BKE_editmesh_bvh.h
+++ b/source/blender/blenkernel/BKE_editmesh_bvh.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_EDITMESH_BVH_H__
-#define __BKE_EDITMESH_BVH_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -104,5 +103,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITMESH_BVH_H__ */
diff --git a/source/blender/blenkernel/BKE_editmesh_cache.h b/source/blender/blenkernel/BKE_editmesh_cache.h
index 6c812098b2e..bc2a70124fe 100644
--- a/source/blender/blenkernel/BKE_editmesh_cache.h
+++ b/source/blender/blenkernel/BKE_editmesh_cache.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_EDITMESH_CACHE_H__
-#define __BKE_EDITMESH_CACHE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -41,5 +40,3 @@ bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITMESH_CACHE_H__ */
diff --git a/source/blender/blenkernel/BKE_editmesh_tangent.h b/source/blender/blenkernel/BKE_editmesh_tangent.h
index 27f24438528..0e3f063ae44 100644
--- a/source/blender/blenkernel/BKE_editmesh_tangent.h
+++ b/source/blender/blenkernel/BKE_editmesh_tangent.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_EDITMESH_TANGENT_H__
-#define __BKE_EDITMESH_TANGENT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -39,5 +38,3 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_EDITMESH_TANGENT_H__ */
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 0518ce8ffa3..0585f67703c 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_EFFECT_H__
-#define __BKE_EFFECT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -283,5 +282,3 @@ void BKE_sim_debug_data_clear_category(const char *category);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index c3a597e29b9..3717eb0f282 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_FCURVE_H__
-#define __BKE_FCURVE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -36,6 +35,7 @@ struct FCurve;
struct FModifier;
struct AnimData;
+struct AnimationEvalContext;
struct BezTriple;
struct LibraryForeachIDData;
struct PathResolvedRNA;
@@ -271,7 +271,7 @@ void testhandles_fcurve(struct FCurve *fcu, eBezTriple_Flag sel_flag, const bool
void sort_time_fcurve(struct FCurve *fcu);
short test_time_fcurve(struct FCurve *fcu);
-void correct_bezpart(float v1[2], float v2[2], float v3[2], float v4[2]);
+void correct_bezpart(const float v1[2], float v2[2], float v3[2], const float v4[2]);
/* -------- Evaluation -------- */
@@ -281,10 +281,12 @@ float evaluate_fcurve_only_curve(struct FCurve *fcu, float evaltime);
float evaluate_fcurve_driver(struct PathResolvedRNA *anim_rna,
struct FCurve *fcu,
struct ChannelDriver *driver_orig,
- float evaltime);
+ const struct AnimationEvalContext *anim_eval_context);
bool BKE_fcurve_is_empty(struct FCurve *fcu);
/* evaluate fcurve and store value */
-float calculate_fcurve(struct PathResolvedRNA *anim_rna, struct FCurve *fcu, float evaltime);
+float calculate_fcurve(struct PathResolvedRNA *anim_rna,
+ struct FCurve *fcu,
+ const struct AnimationEvalContext *anim_eval_context);
/* ************* F-Curve Samples API ******************** */
@@ -312,5 +314,3 @@ void fcurve_store_samples(
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_FCURVE_H__*/
diff --git a/source/blender/blenkernel/BKE_fcurve_driver.h b/source/blender/blenkernel/BKE_fcurve_driver.h
index 563ed408ed7..5b4da4a78a4 100644
--- a/source/blender/blenkernel/BKE_fcurve_driver.h
+++ b/source/blender/blenkernel/BKE_fcurve_driver.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_FCURVE_DRIVER_H__
-#define __BKE_FCURVE_DRIVER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -30,6 +29,7 @@
extern "C" {
#endif
+struct AnimationEvalContext;
struct ChannelDriver;
struct DriverTarget;
struct DriverVar;
@@ -97,10 +97,8 @@ void BKE_driver_invalidate_expression(struct ChannelDriver *driver,
float evaluate_driver(struct PathResolvedRNA *anim_rna,
struct ChannelDriver *driver,
struct ChannelDriver *driver_orig,
- const float evaltime);
+ const struct AnimationEvalContext *anim_eval_context);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_FCURVE_DRIVER_H__*/
diff --git a/source/blender/blenkernel/BKE_fluid.h b/source/blender/blenkernel/BKE_fluid.h
index c958afb212e..88a5492d85b 100644
--- a/source/blender/blenkernel/BKE_fluid.h
+++ b/source/blender/blenkernel/BKE_fluid.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_FLUID_H__
-#define __BKE_FLUID_H__
+#pragma once
/** \file
* \ingroup bke
@@ -37,7 +36,7 @@ struct Main;
struct Scene;
typedef float (*BKE_Fluid_BresenhamFn)(
- float *result, float *input, int res[3], int *pixel, float *tRay, float correct);
+ float *result, const float *input, int res[3], int *pixel, float *tRay, float correct);
struct Mesh *BKE_fluid_modifier_do(struct FluidModifierData *fmd,
struct Depsgraph *depsgraph,
@@ -56,9 +55,9 @@ bool BKE_fluid_reallocate_fluid(struct FluidDomainSettings *fds, int res[3], int
void BKE_fluid_reallocate_copy_fluid(struct FluidDomainSettings *fds,
int o_res[3],
int n_res[3],
- int o_min[3],
- int n_min[3],
- int o_max[3],
+ const int o_min[3],
+ const int n_min[3],
+ const int o_max[3],
int o_shift[3],
int n_shift[3]);
void BKE_fluid_cache_free_all(struct FluidDomainSettings *fds, struct Object *ob);
@@ -101,5 +100,3 @@ void BKE_fluid_flow_behavior_set(struct Object *object,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_FLUID_H__ */
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index 35f7d8b7d53..b23ccbe25ff 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_FONT_H__
-#define __BKE_FONT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -102,5 +101,3 @@ void BKE_vfont_clipboard_get(char32_t **r_text_buf,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_freestyle.h b/source/blender/blenkernel/BKE_freestyle.h
index 888a3d96aa2..47f0b547d83 100644
--- a/source/blender/blenkernel/BKE_freestyle.h
+++ b/source/blender/blenkernel/BKE_freestyle.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_FREESTYLE_H__
-#define __BKE_FREESTYLE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -66,5 +65,3 @@ void BKE_freestyle_lineset_unique_name(FreestyleConfig *config, FreestyleLineSet
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 61c270202f1..9ffd496616d 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_GLOBAL_H__
-#define __BKE_GLOBAL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -145,18 +144,19 @@ enum {
G_DEBUG_DEPSGRAPH_TIME = (1 << 11), /* depsgraph timing statistics and messages */
G_DEBUG_DEPSGRAPH_NO_THREADS = (1 << 12), /* single threaded depsgraph */
G_DEBUG_DEPSGRAPH_PRETTY = (1 << 13), /* use pretty colors in depsgraph messages */
+ G_DEBUG_DEPSGRAPH_UUID = (1 << 14), /* use pretty colors in depsgraph messages */
G_DEBUG_DEPSGRAPH = (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_EVAL | G_DEBUG_DEPSGRAPH_TAG |
- G_DEBUG_DEPSGRAPH_TIME),
- G_DEBUG_SIMDATA = (1 << 14), /* sim debug data display */
- G_DEBUG_GPU_MEM = (1 << 15), /* gpu memory in status bar */
- G_DEBUG_GPU = (1 << 16), /* gpu debug */
- G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...)*/
- G_DEBUG_GPU_SHADERS = (1 << 18), /* GLSL shaders */
- G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 19), /* force gpu workarounds bypassing detections. */
- G_DEBUG_XR = (1 << 20), /* XR/OpenXR messages */
- G_DEBUG_XR_TIME = (1 << 21), /* XR/OpenXR timing messages */
-
- G_DEBUG_GHOST = (1 << 20), /* Debug GHOST module. */
+ G_DEBUG_DEPSGRAPH_TIME | G_DEBUG_DEPSGRAPH_UUID),
+ G_DEBUG_SIMDATA = (1 << 15), /* sim debug data display */
+ G_DEBUG_GPU_MEM = (1 << 16), /* gpu memory in status bar */
+ G_DEBUG_GPU = (1 << 17), /* gpu debug */
+ G_DEBUG_IO = (1 << 18), /* IO Debugging (for Collada, ...)*/
+ G_DEBUG_GPU_SHADERS = (1 << 19), /* GLSL shaders */
+ G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 20), /* force gpu workarounds bypassing detections. */
+ G_DEBUG_XR = (1 << 21), /* XR/OpenXR messages */
+ G_DEBUG_XR_TIME = (1 << 22), /* XR/OpenXR timing messages */
+
+ G_DEBUG_GHOST = (1 << 23), /* Debug GHOST module. */
};
#define G_DEBUG_ALL \
@@ -223,5 +223,3 @@ extern Global G;
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index cd434566e43..6defc2ffd68 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -17,8 +17,7 @@
* This is a new part of Blender
*/
-#ifndef __BKE_GPENCIL_H__
-#define __BKE_GPENCIL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -280,5 +279,3 @@ void BKE_gpencil_update_layer_parent(const struct Depsgraph *depsgraph, struct O
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_GPENCIL_H__ */
diff --git a/source/blender/blenkernel/BKE_gpencil_curve.h b/source/blender/blenkernel/BKE_gpencil_curve.h
index cf6f9074bda..3fbd0ce1a51 100644
--- a/source/blender/blenkernel/BKE_gpencil_curve.h
+++ b/source/blender/blenkernel/BKE_gpencil_curve.h
@@ -17,8 +17,7 @@
* This is a new part of Blender
*/
-#ifndef __BKE_GPENCIL_CURVE_H__
-#define __BKE_GPENCIL_CURVE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -43,5 +42,3 @@ void BKE_gpencil_convert_curve(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_GPENCIL_CURVE_H__ */
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index b79bbf3948f..0abd87d3d4e 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -17,8 +17,7 @@
* This is a new part of Blender
*/
-#ifndef __BKE_GPENCIL_GEOM_H__
-#define __BKE_GPENCIL_GEOM_H__
+#pragma once
/** \file
* \ingroup bke
@@ -76,7 +75,21 @@ void BKE_gpencil_stroke_fill_triangulate(struct bGPDstroke *gps);
void BKE_gpencil_stroke_geometry_update(struct bGPDstroke *gps);
void BKE_gpencil_stroke_uv_update(struct bGPDstroke *gps);
-void BKE_gpencil_transform(struct bGPdata *gpd, float mat[4][4]);
+void BKE_gpencil_transform(struct bGPdata *gpd, const float mat[4][4]);
+
+typedef struct GPencilPointCoordinates {
+ /* This is used when doing "move only origin" in object_data_transform.c.
+ * pressure is needs to be stored here as it is tied to object scale. */
+ float co[3];
+ float pressure;
+} GPencilPointCoordinates;
+
+int BKE_gpencil_stroke_point_count(struct bGPdata *gpd);
+void BKE_gpencil_point_coords_get(struct bGPdata *gpd, GPencilPointCoordinates *elem_data);
+void BKE_gpencil_point_coords_apply(struct bGPdata *gpd, const GPencilPointCoordinates *elem_data);
+void BKE_gpencil_point_coords_apply_with_mat4(struct bGPdata *gpd,
+ const GPencilPointCoordinates *elem_data,
+ const float mat[4][4]);
bool BKE_gpencil_stroke_sample(struct bGPDstroke *gps, const float dist, const bool select);
bool BKE_gpencil_stroke_smooth(struct bGPDstroke *gps, int i, float inf);
@@ -98,6 +111,8 @@ bool BKE_gpencil_stroke_shrink(struct bGPDstroke *gps, const float dist);
float BKE_gpencil_stroke_length(const struct bGPDstroke *gps, bool use_3d);
+void BKE_gpencil_stroke_set_random_color(struct bGPDstroke *gps);
+
void BKE_gpencil_convert_mesh(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
@@ -109,10 +124,9 @@ void BKE_gpencil_convert_mesh(struct Main *bmain,
const float matrix[4][4],
const int frame_offset,
const bool use_seams,
- const bool use_faces);
+ const bool use_faces,
+ const bool simple_material);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_GPENCIL_GEOM_H__ */
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
index ac5f4607838..8eafbe04a14 100644
--- a/source/blender/blenkernel/BKE_gpencil_modifier.h
+++ b/source/blender/blenkernel/BKE_gpencil_modifier.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_GPENCIL_MODIFIER_H__
-#define __BKE_GPENCIL_MODIFIER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -316,5 +315,3 @@ struct bGPDframe *BKE_gpencil_frame_retime_get(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_GPENCIL_MODIFIER_H__ */
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index ea515416b58..bf386e099e0 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_HAIR_H__
-#define __BKE_HAIR_H__
+#pragma once
/** \file
* \ingroup bke
@@ -61,5 +60,3 @@ extern void (*BKE_hair_batch_cache_free_cb)(struct Hair *hair);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index 56c50c22bf4..8a4fc78eb97 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_ICONS_H__
-#define __BKE_ICONS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -173,5 +172,3 @@ int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_ICONS_H__ */
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index dc01e8ea27b..58629cde6ec 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_IDPROP_H__
-#define __BKE_IDPROP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -200,5 +199,3 @@ void IDP_print(const struct IDProperty *prop);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_IDPROP_H__ */
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
index a823693e126..aefba9ef02a 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_IDTYPE_H__
-#define __BKE_IDTYPE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -47,9 +46,9 @@ enum {
};
typedef struct IDCacheKey {
- /* The session uuid of the ID owning the cached data. */
+ /* The session UUID of the ID owning the cached data. */
unsigned int id_session_uuid;
- /* Value uniquely indentifying the cache whithin its ID.
+ /* Value uniquely identifying the cache within its ID.
* Typically the offset of its member in the data-block struct, but can be anything. */
size_t offset_in_ID;
/* Actual address of the cached data to save and restore. */
@@ -59,7 +58,7 @@ typedef struct IDCacheKey {
uint BKE_idtype_cache_key_hash(const void *key_v);
bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v);
-/* ********** Prototypes for IDTypeInfo callbacks. ********** */
+/* ********** Prototypes for #IDTypeInfo callbacks. ********** */
typedef void (*IDTypeInitDataFunction)(struct ID *id);
@@ -76,9 +75,15 @@ typedef void (*IDTypeMakeLocalFunction)(struct Main *bmain, struct ID *id, const
typedef void (*IDTypeForeachIDFunction)(struct ID *id, struct LibraryForeachIDData *data);
+typedef enum eIDTypeInfoCacheCallbackFlags {
+ /** Indicates to the callback that that cache may be stored in the .blend file, so its pointer
+ * should not be cleared at read-time. */
+ IDTYPE_CACHE_CB_FLAGS_PERSISTENT = 1 << 0,
+} eIDTypeInfoCacheCallbackFlags;
typedef void (*IDTypeForeachCacheFunctionCallback)(struct ID *id,
const struct IDCacheKey *cache_key,
void **cache_p,
+ uint flags,
void *user_data);
typedef void (*IDTypeForeachCacheFunction)(struct ID *id,
IDTypeForeachCacheFunctionCallback function_callback,
@@ -229,8 +234,14 @@ short BKE_idtype_idcode_from_index(const int index);
short BKE_idtype_idcode_iter_step(int *index);
+/* Some helpers/wrappers around callbacks defined in #IDTypeInfo, dealing e.g. with embedded IDs.
+ * XXX Ideally those would rather belong to #BKE_lib_id, but using callback function pointers makes
+ * this hard to do properly if we want to avoid headers includes in headers. */
+
+void BKE_idtype_id_foreach_cache(struct ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_IDTYPE_H__ */
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 1e5573ab014..f052ba400fc 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_IMAGE_H__
-#define __BKE_IMAGE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -55,6 +54,7 @@ void BKE_image_free_packedfiles(struct Image *image);
void BKE_image_free_views(struct Image *image);
void BKE_image_free_buffers(struct Image *image);
void BKE_image_free_buffers_ex(struct Image *image, bool do_lock);
+void BKE_image_free_gputextures(struct Image *ima);
/* call from library */
void BKE_image_free(struct Image *image);
@@ -274,6 +274,10 @@ void BKE_image_free_anim_ibufs(struct Image *ima, int except_frame);
/* does all images with type MOVIE or SEQUENCE */
void BKE_image_all_free_anim_ibufs(struct Main *bmain, int except_frame);
+void BKE_image_free_all_gputextures(struct Main *bmain);
+void BKE_image_free_anim_gputextures(struct Main *bmain);
+void BKE_image_free_old_gputextures(struct Main *bmain);
+
bool BKE_image_memorypack(struct Image *ima);
void BKE_image_packfiles(struct ReportList *reports, struct Image *ima, const char *basepath);
void BKE_image_packfiles_from_mem(struct ReportList *reports,
@@ -362,6 +366,30 @@ bool BKE_image_has_loaded_ibuf(struct Image *image);
struct ImBuf *BKE_image_get_ibuf_with_name(struct Image *image, const char *name);
struct ImBuf *BKE_image_get_first_ibuf(struct Image *image);
+/* Not to be use directly. */
+struct GPUTexture *BKE_image_create_gpu_texture_from_ibuf(struct Image *image, struct ImBuf *ibuf);
+
+/* Get the GPUTexture for a given `Image`.
+ *
+ * `iuser` and `ibuf` are mutual exclusive parameters. The caller can pass the `ibuf` when already
+ * available. It is also required when requesting the GPUTexture for a render result. */
+struct GPUTexture *BKE_image_get_gpu_texture(struct Image *image,
+ struct ImageUser *iuser,
+ struct ImBuf *ibuf);
+struct GPUTexture *BKE_image_get_gpu_tiles(struct Image *image,
+ struct ImageUser *iuser,
+ struct ImBuf *ibuf);
+struct GPUTexture *BKE_image_get_gpu_tilemap(struct Image *image,
+ struct ImageUser *iuser,
+ struct ImBuf *ibuf);
+
+void BKE_image_update_gputexture(
+ struct Image *ima, struct ImageUser *iuser, int x, int y, int w, int h);
+void BKE_image_paint_set_mipmap(struct Main *bmain, bool mipmap);
+
+/* Delayed free of OpenGL buffers by main thread */
+void BKE_image_free_unused_gpu_textures(void);
+
struct RenderSlot *BKE_image_add_renderslot(struct Image *ima, const char *name);
bool BKE_image_remove_renderslot(struct Image *ima, struct ImageUser *iuser, int slot);
struct RenderSlot *BKE_image_get_renderslot(struct Image *ima, int slot);
@@ -370,5 +398,3 @@ bool BKE_image_clear_renderslot(struct Image *ima, struct ImageUser *iuser, int
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_image_save.h b/source/blender/blenkernel/BKE_image_save.h
index 8dfece944ff..0620442d998 100644
--- a/source/blender/blenkernel/BKE_image_save.h
+++ b/source/blender/blenkernel/BKE_image_save.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_IMAGE_SAVE_H__
-#define __BKE_IMAGE_SAVE_H__
+#pragma once
#include "DNA_scene_types.h"
@@ -62,5 +61,3 @@ bool BKE_image_save(struct ReportList *reports,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_IMAGE_SAVE_H__ */
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h
index ab5d2f66441..40b9f738bfd 100644
--- a/source/blender/blenkernel/BKE_ipo.h
+++ b/source/blender/blenkernel/BKE_ipo.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_IPO_H__
-#define __BKE_IPO_H__
+#pragma once
/** \file
* \ingroup bke
@@ -37,5 +36,3 @@ void do_versions_ipos_to_animato(struct Main *main);
#ifdef __cplusplus
};
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_kelvinlet.h b/source/blender/blenkernel/BKE_kelvinlet.h
index b8290730751..b3966d3ca4a 100644
--- a/source/blender/blenkernel/BKE_kelvinlet.h
+++ b/source/blender/blenkernel/BKE_kelvinlet.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_KELVINLET_H__
-#define __BKE_KELVINLET_H__
+#pragma once
/** \file
* \ingroup bke
@@ -81,5 +80,3 @@ void BKE_kelvinlet_twist(float r_elem_disp[3],
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 6581891062c..e67df194431 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_KEY_H__
-#define __BKE_KEY_H__
+#pragma once
/** \file
* \ingroup bke
@@ -51,6 +50,12 @@ void key_curve_normal_weights(float t, float data[4], int type);
float *BKE_key_evaluate_object_ex(struct Object *ob, int *r_totelem, float *arr, size_t arr_size);
float *BKE_key_evaluate_object(struct Object *ob, int *r_totelem);
+int BKE_keyblock_element_count_from_shape(const struct Key *key, const int shape_index);
+int BKE_keyblock_element_count(const struct Key *key);
+
+size_t BKE_keyblock_element_calc_size_from_shape(const struct Key *key, const int shape_index);
+size_t BKE_keyblock_element_calc_size(const struct Key *key);
+
bool BKE_key_idtype_support(const short id_type);
struct Key **BKE_key_from_id_p(struct ID *id);
@@ -74,6 +79,10 @@ void BKE_keyblock_convert_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
void BKE_keyblock_convert_to_lattice(struct KeyBlock *kb, struct Lattice *lt);
int BKE_keyblock_curve_element_count(struct ListBase *nurb);
+void BKE_keyblock_curve_data_transform(const struct ListBase *nurb,
+ const float mat[4][4],
+ const void *src,
+ void *dst);
void BKE_keyblock_update_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
void BKE_keyblock_convert_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
void BKE_keyblock_convert_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb);
@@ -104,8 +113,28 @@ bool BKE_keyblock_move(struct Object *ob, int org_index, int new_index);
bool BKE_keyblock_is_basis(struct Key *key, const int index);
+/* -------------------------------------------------------------------- */
+/** \name Key-Block Data Access
+ * \{ */
+
+void BKE_keyblock_data_get_from_shape(const struct Key *key,
+ float (*arr)[3],
+ const int shape_index);
+void BKE_keyblock_data_get(const struct Key *key, float (*arr)[3]);
+
+void BKE_keyblock_data_set_with_mat4(struct Key *key,
+ const int shape_index,
+ const float (*vertices)[3],
+ const float mat[4][4]);
+void BKE_keyblock_curve_data_set_with_mat4(struct Key *key,
+ const struct ListBase *nurb,
+ const int shape_index,
+ const void *data,
+ const float mat[4][4]);
+void BKE_keyblock_data_set(struct Key *key, const int shape_index, const void *data);
+
+/** \} */
+
#ifdef __cplusplus
};
#endif
-
-#endif /* __BKE_KEY_H__ */
diff --git a/source/blender/blenkernel/BKE_keyconfig.h b/source/blender/blenkernel/BKE_keyconfig.h
index bc33cc2669e..ab42d5742ea 100644
--- a/source/blender/blenkernel/BKE_keyconfig.h
+++ b/source/blender/blenkernel/BKE_keyconfig.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_KEYCONFIG_H__
-#define __BKE_KEYCONFIG_H__
+#pragma once
/** \file
* \ingroup bke
@@ -76,5 +75,3 @@ void BKE_keyconfig_pref_filter_items(struct UserDef *userdef,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_KEYCONFIG_H__ */
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index bb23ad63020..03c57d4caac 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LATTICE_H__
-#define __BKE_LATTICE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -67,8 +66,8 @@ void BKE_lattice_minmax_dl(struct Object *ob, struct Lattice *lt, float min[3],
void BKE_lattice_minmax(struct Lattice *lt, float min[3], float max[3]);
void BKE_lattice_center_median(struct Lattice *lt, float cent[3]);
void BKE_lattice_center_bounds(struct Lattice *lt, float cent[3]);
-void BKE_lattice_translate(struct Lattice *lt, float offset[3], bool do_keys);
-void BKE_lattice_transform(struct Lattice *lt, float mat[4][4], bool do_keys);
+void BKE_lattice_translate(struct Lattice *lt, const float offset[3], bool do_keys);
+void BKE_lattice_transform(struct Lattice *lt, const float mat[4][4], bool do_keys);
bool BKE_lattice_is_any_selected(const struct Lattice *lt);
@@ -140,5 +139,3 @@ void BKE_lattice_deform_coords_with_editmesh(const struct Object *ob_lattice,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LATTICE_H__ */
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 7a0252e6813..7fe932edf31 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_LAYER_H__
-#define __BKE_LAYER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -416,5 +415,3 @@ bool BKE_view_layer_filter_edit_mesh_has_edges(struct Object *ob, void *user_dat
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LAYER_H__ */
diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index bc72afdd08d..a2cbe537349 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_LIB_ID_H__
-#define __BKE_LIB_ID_H__
+#pragma once
/** \file
* \ingroup bke
@@ -229,7 +228,6 @@ bool BKE_id_copy(struct Main *bmain, const struct ID *id, struct ID **newid);
bool BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag);
struct ID *BKE_id_copy_for_duplicate(struct Main *bmain,
struct ID *id,
- const bool is_owner_id_liboverride,
const uint duplicate_flags);
void BKE_lib_id_swap(struct Main *bmain, struct ID *id_a, struct ID *id_b);
@@ -268,7 +266,8 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const struct ID *id, char
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
const struct ID *id,
const bool add_lib_hint,
- char separator_char);
+ char separator_char,
+ int *r_prefix_len);
char *BKE_id_to_unique_string_key(const struct ID *id);
@@ -291,5 +290,3 @@ void BKE_id_reorder(const struct ListBase *lb, struct ID *id, struct ID *relativ
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIB_ID_H__ */
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 411df66fe36..5843992b25c 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LIB_OVERRIDE_H__
-#define __BKE_LIB_OVERRIDE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -50,9 +49,8 @@ struct IDOverrideLibraryPropertyOperation;
struct Main;
struct PointerRNA;
struct PropertyRNA;
-
-void BKE_lib_override_library_enable(const bool do_enable);
-bool BKE_lib_override_library_is_enabled(void);
+struct Scene;
+struct ViewLayer;
struct IDOverrideLibrary *BKE_lib_override_library_init(struct ID *local_id,
struct ID *reference_id);
@@ -66,6 +64,15 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
struct ID *reference_id,
const bool do_tagged_remap);
bool BKE_lib_override_library_create_from_tag(struct Main *bmain);
+void BKE_lib_override_library_dependencies_tag(struct Main *bmain,
+ struct ID *id_root,
+ const uint tag,
+ const bool do_create_main_relashionships);
+bool BKE_lib_override_library_create(struct Main *bmain,
+ struct Scene *scene,
+ struct ViewLayer *view_layer,
+ struct ID *id_root,
+ struct ID *id_reference);
struct IDOverrideLibraryProperty *BKE_lib_override_library_property_find(
struct IDOverrideLibrary *override, const char *rna_path);
@@ -111,6 +118,9 @@ bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct
bool BKE_lib_override_library_operations_create(struct Main *bmain, struct ID *local);
void BKE_lib_override_library_main_operations_create(struct Main *bmain, const bool force_auto);
+void BKE_lib_override_library_id_reset(struct Main *bmain, struct ID *id_root);
+void BKE_lib_override_library_id_hierarchy_reset(struct Main *bmain, struct ID *id_root);
+
void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property,
const short tag,
const bool do_set);
@@ -130,7 +140,7 @@ void BKE_lib_override_library_main_update(struct Main *bmain);
/* For now, we just use a temp main list. */
typedef struct Main OverrideLibraryStorage;
-OverrideLibraryStorage *BKE_lib_override_library_operations_store_initialize(void);
+OverrideLibraryStorage *BKE_lib_override_library_operations_store_init(void);
struct ID *BKE_lib_override_library_operations_store_start(
struct Main *bmain, OverrideLibraryStorage *override_storage, struct ID *local);
void BKE_lib_override_library_operations_store_end(OverrideLibraryStorage *override_storage,
@@ -140,5 +150,3 @@ void BKE_lib_override_library_operations_store_finalize(OverrideLibraryStorage *
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIB_OVERRIDE_H__ */
diff --git a/source/blender/blenkernel/BKE_lib_query.h b/source/blender/blenkernel/BKE_lib_query.h
index c5a25e8e7af..b6abe0bf18c 100644
--- a/source/blender/blenkernel/BKE_lib_query.h
+++ b/source/blender/blenkernel/BKE_lib_query.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2014 by Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_LIB_QUERY_H__
-#define __BKE_LIB_QUERY_H__
+#pragma once
/** \file
* \ingroup bke
@@ -182,5 +181,3 @@ void BKE_library_indirectly_used_data_tag_clear(struct Main *bmain);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIB_QUERY_H__ */
diff --git a/source/blender/blenkernel/BKE_lib_remap.h b/source/blender/blenkernel/BKE_lib_remap.h
index 8129b9dbafb..fb14e340d8b 100644
--- a/source/blender/blenkernel/BKE_lib_remap.h
+++ b/source/blender/blenkernel/BKE_lib_remap.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_LIB_REMAP_H__
-#define __BKE_LIB_REMAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -113,5 +112,3 @@ void BKE_library_callback_remap_editor_id_reference_set(
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIB_REMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 7883d740b0a..3981a4c14ea 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_LIBRARY_H__
-#define __BKE_LIBRARY_H__
+#pragma once
/** \file
* \ingroup bke
@@ -39,5 +38,3 @@ void BKE_library_filepath_set(struct Main *bmain, struct Library *lib, const cha
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIBRARY_H__ */
diff --git a/source/blender/blenkernel/BKE_light.h b/source/blender/blenkernel/BKE_light.h
index ead27ec8002..026e5d1a13b 100644
--- a/source/blender/blenkernel/BKE_light.h
+++ b/source/blender/blenkernel/BKE_light.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LIGHT_H__
-#define __BKE_LIGHT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -44,5 +43,3 @@ void BKE_light_eval(struct Depsgraph *depsgraph, struct Light *la);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_lightprobe.h b/source/blender/blenkernel/BKE_lightprobe.h
index 6304f61a1f4..e66d4ef75ca 100644
--- a/source/blender/blenkernel/BKE_lightprobe.h
+++ b/source/blender/blenkernel/BKE_lightprobe.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LIGHTPROBE_H__
-#define __BKE_LIGHTPROBE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -39,5 +38,3 @@ struct LightProbe *BKE_lightprobe_copy(struct Main *bmain, const struct LightPro
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LIGHTPROBE_H__ */
diff --git a/source/blender/blenkernel/BKE_linestyle.h b/source/blender/blenkernel/BKE_linestyle.h
index b086f244923..19238c4d090 100644
--- a/source/blender/blenkernel/BKE_linestyle.h
+++ b/source/blender/blenkernel/BKE_linestyle.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_LINESTYLE_H__
-#define __BKE_LINESTYLE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -106,5 +105,3 @@ void BKE_linestyle_default_shader(const struct bContext *C, FreestyleLineStyle *
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_LINESTYLE_H__ */
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index b7c70168a49..2187ab6b9f5 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MAIN_H__
-#define __BKE_MAIN_H__
+#pragma once
/** \file
* \ingroup bke
@@ -250,5 +249,3 @@ int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MAIN_H__ */
diff --git a/source/blender/blenkernel/BKE_main_idmap.h b/source/blender/blenkernel/BKE_main_idmap.h
index e392b7db60e..b89714cefa4 100644
--- a/source/blender/blenkernel/BKE_main_idmap.h
+++ b/source/blender/blenkernel/BKE_main_idmap.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MAIN_IDMAP_H__
-#define __BKE_MAIN_IDMAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -69,5 +68,3 @@ struct ID *BKE_main_idmap_lookup_uuid(struct IDNameLib_Map *id_typemap,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MAIN_IDMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index dca677343ce..ab731c5e42f 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MASK_H__
-#define __BKE_MASK_H__
+#pragma once
/** \file
* \ingroup bke
@@ -331,5 +330,3 @@ void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MASK_H__ */
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 225d966a51a..a30d7d55985 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MATERIAL_H__
-#define __BKE_MATERIAL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -84,7 +83,8 @@ void BKE_object_material_assign(
void BKE_object_material_array_assign(struct Main *bmain,
struct Object *ob,
struct Material ***matar,
- short totcol);
+ int totcol,
+ const bool to_object_only);
short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma);
bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob);
@@ -135,5 +135,3 @@ void BKE_material_eval(struct Depsgraph *depsgraph, struct Material *material);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 5f51f528d14..f2ad23a35f1 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MBALL_H__
-#define __BKE_MBALL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -92,5 +91,3 @@ extern void (*BKE_mball_batch_cache_free_cb)(struct MetaBall *mb);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_mball_tessellate.h b/source/blender/blenkernel/BKE_mball_tessellate.h
index 4e0649cf930..0ffbcf5bb05 100644
--- a/source/blender/blenkernel/BKE_mball_tessellate.h
+++ b/source/blender/blenkernel/BKE_mball_tessellate.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MBALL_TESSELLATE_H__
-#define __BKE_MBALL_TESSELLATE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -38,5 +37,3 @@ void BKE_mball_cubeTable_free(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MBALL_TESSELLATE_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 7d989bfcf69..045563f8e52 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MESH_H__
-#define __BKE_MESH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -231,7 +230,7 @@ void BKE_mesh_nomain_to_meshkey(struct Mesh *mesh_src, struct Mesh *mesh_dst, st
/* vertex level transformations & checks (no derived mesh) */
bool BKE_mesh_minmax(const struct Mesh *me, float r_min[3], float r_max[3]);
-void BKE_mesh_transform(struct Mesh *me, float mat[4][4], bool do_keys);
+void BKE_mesh_transform(struct Mesh *me, const float mat[4][4], bool do_keys);
void BKE_mesh_translate(struct Mesh *me, const float offset[3], const bool do_keys);
void BKE_mesh_ensure_navmesh(struct Mesh *me);
@@ -513,13 +512,13 @@ void BKE_mesh_loops_to_mface_corners(struct CustomData *fdata,
void BKE_mesh_loops_to_tessdata(struct CustomData *fdata,
struct CustomData *ldata,
struct MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces);
void BKE_mesh_tangent_loops_to_tessdata(struct CustomData *fdata,
struct CustomData *ldata,
struct MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces,
const char *layer_name);
@@ -707,5 +706,3 @@ BLI_INLINE int BKE_mesh_origindex_mface_mpoly(const int *index_mf_to_mpoly,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_iterators.h b/source/blender/blenkernel/BKE_mesh_iterators.h
index f7eaa7f69b8..103e7b5b78f 100644
--- a/source/blender/blenkernel/BKE_mesh_iterators.h
+++ b/source/blender/blenkernel/BKE_mesh_iterators.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MESH_ITERATORS_H__
-#define __BKE_MESH_ITERATORS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -70,5 +69,3 @@ void BKE_mesh_foreach_mapped_vert_coords_get(struct Mesh *me_eval,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_ITERATORS_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index 9864cc4d28d..140a60dbdb7 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MESH_MAPPING_H__
-#define __BKE_MESH_MAPPING_H__
+#pragma once
/** \file
* \ingroup bke
@@ -199,7 +198,7 @@ void BKE_mesh_loop_islands_clear(MeshIslandStore *island_store);
void BKE_mesh_loop_islands_free(MeshIslandStore *island_store);
void BKE_mesh_loop_islands_add(MeshIslandStore *islands,
const int item_num,
- int *item_indices,
+ const int *item_indices,
const int num_island_items,
int *island_item_indices,
const int num_innercut_items,
@@ -258,5 +257,3 @@ int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_MAPPING_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_mirror.h b/source/blender/blenkernel/BKE_mesh_mirror.h
index 0a68d028e35..2c6920a18bf 100644
--- a/source/blender/blenkernel/BKE_mesh_mirror.h
+++ b/source/blender/blenkernel/BKE_mesh_mirror.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MESH_MIRROR_H__
-#define __BKE_MESH_MIRROR_H__
+#pragma once
/** \file
* \ingroup bke
@@ -49,5 +48,3 @@ struct Mesh *BKE_mesh_mirror_apply_mirror_on_axis(struct MirrorModifierData *mmd
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_MIRROR_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h
index fff89e50744..d9b6ab3813e 100644
--- a/source/blender/blenkernel/BKE_mesh_remap.h
+++ b/source/blender/blenkernel/BKE_mesh_remap.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MESH_REMAP_H__
-#define __BKE_MESH_REMAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -234,5 +233,3 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_REMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
index 24f95f7ed20..2265fa6e105 100644
--- a/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
+++ b/source/blender/blenkernel/BKE_mesh_remesh_voxel.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MESH_REMESH_VOXEL_H__
-#define __BKE_MESH_REMESH_VOXEL_H__
+#pragma once
/** \file
* \ingroup bke
@@ -66,5 +65,3 @@ void BKE_remesh_reproject_sculpt_face_sets(struct Mesh *target, struct Mesh *sou
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_REMESH_VOXEL_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index 468ec6a44cd..adb7c357049 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_MESH_RUNTIME_H__
-#define __BKE_MESH_RUNTIME_H__
+#pragma once
/** \file
* \ingroup bke
@@ -111,5 +110,3 @@ bool BKE_mesh_runtime_is_valid(struct Mesh *me_eval);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_RUNTIME_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_tangent.h b/source/blender/blenkernel/BKE_mesh_tangent.h
index 7b686f112aa..96eaa23ce71 100644
--- a/source/blender/blenkernel/BKE_mesh_tangent.h
+++ b/source/blender/blenkernel/BKE_mesh_tangent.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MESH_TANGENT_H__
-#define __BKE_MESH_TANGENT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -87,5 +86,3 @@ void BKE_mesh_calc_loop_tangent_step_0(const struct CustomData *loopData,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_TANGENT_H__ */
diff --git a/source/blender/blenkernel/BKE_mesh_wrapper.h b/source/blender/blenkernel/BKE_mesh_wrapper.h
index 00e2dd08726..2fe264fd0f7 100644
--- a/source/blender/blenkernel/BKE_mesh_wrapper.h
+++ b/source/blender/blenkernel/BKE_mesh_wrapper.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MESH_WRAPPER_H__
-#define __BKE_MESH_WRAPPER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -55,5 +54,3 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const struct Mesh *me,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_MESH_WRAPPER_H__ */
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index e16a9284425..f9590696c2e 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_MODIFIER_H__
-#define __BKE_MODIFIER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -543,5 +542,3 @@ struct Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index dbd6eb15bf2..958fbef1f97 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MOVIECLIP_H__
-#define __BKE_MOVIECLIP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -113,6 +112,11 @@ bool BKE_movieclip_put_frame_if_possible(struct MovieClip *clip,
struct MovieClipUser *user,
struct ImBuf *ibuf);
+struct GPUTexture *BKE_movieclip_get_gpu_texture(struct MovieClip *clip,
+ struct MovieClipUser *cuser);
+
+void BKE_movieclip_free_gputexture(struct MovieClip *clip);
+
/* Dependency graph evaluation. */
void BKE_movieclip_eval_update(struct Depsgraph *depsgraph,
@@ -132,5 +136,3 @@ void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, struct Mov
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index 15ba72ef5b5..db2dc7ec87f 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_MULTIRES_H__
-#define __BKE_MULTIRES_H__
+#pragma once
/** \file
* \ingroup bke
@@ -235,5 +234,3 @@ BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3]
#endif
#include "intern/multires_inline.h"
-
-#endif /* __BKE_MULTIRES_H__ */
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 2be8d657bf4..8b3231e5302 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_NLA_H__
-#define __BKE_NLA_H__
+#pragma once
/** \file
* \ingroup bke
@@ -149,5 +148,3 @@ float BKE_nla_tweakedit_remap(struct AnimData *adt, float cframe, short mode);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index bdcbe2129c8..ef46bc0f202 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_NODE_H__
-#define __BKE_NODE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -101,6 +100,30 @@ typedef struct bNodeSocketTemplate {
char identifier[64]; /* generated from name */
} bNodeSocketTemplate;
+/* Use `void *` for callbacks that require C++. This is rather ugly, but works well for now. This
+ * would not be necessary if we would use bNodeSocketType and bNodeType only in C++ code.
+ * However, achieving this requires quite a few changes currently. */
+#ifdef __cplusplus
+namespace blender {
+namespace nodes {
+class SocketMFNetworkBuilder;
+class NodeMFNetworkBuilder;
+} // namespace nodes
+namespace fn {
+class MFDataType;
+}
+} // namespace blender
+
+using NodeExpandInMFNetworkFunction = void (*)(blender::nodes::NodeMFNetworkBuilder &builder);
+using SocketGetMFDataTypeFunction = blender::fn::MFDataType (*)();
+using SocketExpandInMFNetworkFunction = void (*)(blender::nodes::SocketMFNetworkBuilder &builder);
+
+#else
+typedef void *NodeExpandInMFNetworkFunction;
+typedef void *SocketGetMFDataTypeFunction;
+typedef void *SocketExpandInMFNetworkFunction;
+#endif
+
/**
* \brief Defines a socket type.
*
@@ -153,6 +176,11 @@ typedef struct bNodeSocketType {
/* Callback to free the socket type. */
void (*free_self)(struct bNodeSocketType *stype);
+
+ /* Returns the multi-function data type of this socket type. */
+ SocketGetMFDataTypeFunction get_mf_data_type;
+ /* Expands the socket into a multi-function node that outputs the socket value. */
+ SocketExpandInMFNetworkFunction expand_in_mf_network;
} bNodeSocketType;
typedef void *(*NodeInitExecFunction)(struct bNodeExecContext *context,
@@ -267,6 +295,9 @@ typedef struct bNodeType {
/* gpu */
NodeGPUExecFunction gpufunc;
+ /* Expands the bNode into nodes in a multi-function network, which will be evaluated later on. */
+ NodeExpandInMFNetworkFunction expand_in_mf_network;
+
/* RNA integration */
ExtensionRNA rna_ext;
} bNodeType;
@@ -1299,6 +1330,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define SIM_NODE_EMIT_PARTICLES 1009
#define SIM_NODE_TIME 1010
#define SIM_NODE_PARTICLE_ATTRIBUTE 1011
+#define SIM_NODE_AGE_REACHED_EVENT 1012
+#define SIM_NODE_KILL_PARTICLE 1013
/** \} */
@@ -1311,6 +1344,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define FN_NODE_FLOAT_COMPARE 1202
#define FN_NODE_GROUP_INSTANCE_ID 1203
#define FN_NODE_COMBINE_STRINGS 1204
+#define FN_NODE_OBJECT_TRANSFORMS 1205
+#define FN_NODE_RANDOM_FLOAT 1206
/** \} */
@@ -1332,5 +1367,3 @@ extern struct bNodeSocketType NodeSocketTypeUndefined;
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_NODE_H__ */
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index d830a35dda0..215f4043e34 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OBJECT_H__
-#define __BKE_OBJECT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -139,26 +138,26 @@ bool BKE_object_obdata_is_libdata(const struct Object *ob);
struct Object *BKE_object_duplicate(struct Main *bmain,
struct Object *ob,
- const uint dupflag,
+ uint dupflag,
const uint duplicate_options);
void BKE_object_obdata_size_init(struct Object *ob, const float scale);
-void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]);
-void BKE_object_rot_to_mat3(const struct Object *ob, float mat[3][3], bool use_drot);
-void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], bool use_compat);
-void BKE_object_to_mat3(struct Object *ob, float mat[3][3]);
-void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);
+void BKE_object_scale_to_mat3(struct Object *ob, float r_mat[3][3]);
+void BKE_object_rot_to_mat3(const struct Object *ob, float r_mat[3][3], bool use_drot);
+void BKE_object_mat3_to_rot(struct Object *ob, float r_mat[3][3], bool use_compat);
+void BKE_object_to_mat3(struct Object *ob, float r_mat[3][3]);
+void BKE_object_to_mat4(struct Object *ob, float r_mat[4][4]);
void BKE_object_apply_mat4(struct Object *ob,
- float mat[4][4],
+ const float mat[4][4],
const bool use_compat,
const bool use_parent);
void BKE_object_apply_mat4_ex(struct Object *ob,
- float mat[4][4],
+ const float mat[4][4],
struct Object *parent,
- float parentinv[4][4],
+ const float parentinv[4][4],
const bool use_compat);
-void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4]);
+void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4]);
bool BKE_object_pose_context_check(const struct Object *ob);
struct Object *BKE_object_pose_armature_get(struct Object *ob);
@@ -188,7 +187,7 @@ struct Base **BKE_object_pose_base_array_get(struct ViewLayer *view_layer,
struct View3D *v3d,
unsigned int *r_bases_len);
-void BKE_object_get_parent_matrix(struct Object *ob, struct Object *par, float parentmat[4][4]);
+void BKE_object_get_parent_matrix(struct Object *ob, struct Object *par, float r_parentmat[4][4]);
void BKE_object_where_is_calc(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
void BKE_object_where_is_calc_ex(struct Depsgraph *depsgraph,
struct Scene *scene,
@@ -199,7 +198,7 @@ void BKE_object_where_is_calc_time(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
float ctime);
-void BKE_object_where_is_calc_mat4(struct Object *ob, float obmat[4][4]);
+void BKE_object_where_is_calc_mat4(struct Object *ob, float r_obmat[4][4]);
/* possibly belong in own moduke? */
struct BoundBox *BKE_boundbox_alloc_unit(void);
@@ -207,12 +206,12 @@ void BKE_boundbox_init_from_minmax(struct BoundBox *bb, const float min[3], cons
void BKE_boundbox_calc_center_aabb(const struct BoundBox *bb, float r_cent[3]);
void BKE_boundbox_calc_size_aabb(const struct BoundBox *bb, float r_size[3]);
void BKE_boundbox_minmax(const struct BoundBox *bb,
- float obmat[4][4],
+ const float obmat[4][4],
float r_min[3],
float r_max[3]);
struct BoundBox *BKE_object_boundbox_get(struct Object *ob);
-void BKE_object_dimensions_get(struct Object *ob, float vec[3]);
+void BKE_object_dimensions_get(struct Object *ob, float r_vec[3]);
void BKE_object_dimensions_set_ex(struct Object *ob,
const float value[3],
int axis_mask,
@@ -233,7 +232,7 @@ bool BKE_object_minmax_dupli(struct Depsgraph *depsgraph,
/* sometimes min-max isn't enough, we need to loop over each point */
void BKE_object_foreach_display_point(struct Object *ob,
- float obmat[4][4],
+ const float obmat[4][4],
void (*func_cb)(const float[3], void *),
void *user_data);
void BKE_scene_foreach_display_point(struct Depsgraph *depsgraph,
@@ -413,5 +412,3 @@ void BKE_object_to_mesh_clear(struct Object *object);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_object_deform.h b/source/blender/blenkernel/BKE_object_deform.h
index 410cb862aa7..a10158254c2 100644
--- a/source/blender/blenkernel/BKE_object_deform.h
+++ b/source/blender/blenkernel/BKE_object_deform.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OBJECT_DEFORM_H__
-#define __BKE_OBJECT_DEFORM_H__
+#pragma once
/** \file
* \ingroup bke
@@ -33,7 +32,7 @@ struct Object;
struct bDeformGroup;
/* General vgroup operations */
-void BKE_object_defgroup_remap_update_users(struct Object *ob, int *map);
+void BKE_object_defgroup_remap_update_users(struct Object *ob, const int *map);
bool BKE_object_defgroup_array_get(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
@@ -95,5 +94,3 @@ void BKE_object_defgroup_mirror_selection(struct Object *ob,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_OBJECT_DEFORM_H__ */
diff --git a/source/blender/blenkernel/BKE_object_facemap.h b/source/blender/blenkernel/BKE_object_facemap.h
index 83780d8fad5..10cb4a54bde 100644
--- a/source/blender/blenkernel/BKE_object_facemap.h
+++ b/source/blender/blenkernel/BKE_object_facemap.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OBJECT_FACEMAP_H__
-#define __BKE_OBJECT_FACEMAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -48,5 +47,3 @@ void BKE_object_facemap_index_map_apply(int *fmap, int fmap_len, const int *map,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_OBJECT_FACEMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_ocean.h b/source/blender/blenkernel/BKE_ocean.h
index 6ce2e13cf18..1f8cdf27eb1 100644
--- a/source/blender/blenkernel/BKE_ocean.h
+++ b/source/blender/blenkernel/BKE_ocean.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OCEAN_H__
-#define __BKE_OCEAN_H__
+#pragma once
#include <stdbool.h>
@@ -70,8 +69,10 @@ typedef struct OceanCache {
struct Ocean *BKE_ocean_add(void);
void BKE_ocean_free_data(struct Ocean *oc);
void BKE_ocean_free(struct Ocean *oc);
-bool BKE_ocean_ensure(struct OceanModifierData *omd);
-void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd);
+bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution);
+void BKE_ocean_init_from_modifier(struct Ocean *ocean,
+ struct OceanModifierData const *omd,
+ const int resolution);
void BKE_ocean_init(struct Ocean *o,
int M,
@@ -135,5 +136,3 @@ float BLI_ocean_spectrum_jonswap(const struct Ocean *oc, const float kx, const f
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_outliner_treehash.h b/source/blender/blenkernel/BKE_outliner_treehash.h
index 9f4ebffdcf4..94bf0f622d6 100644
--- a/source/blender/blenkernel/BKE_outliner_treehash.h
+++ b/source/blender/blenkernel/BKE_outliner_treehash.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OUTLINER_TREEHASH_H__
-#define __BKE_OUTLINER_TREEHASH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -59,5 +58,3 @@ void BKE_outliner_treehash_free(void *treehash);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index fb2578b81b0..1e8721045cd 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_PACKEDFILE_H__
-#define __BKE_PACKEDFILE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -125,5 +124,3 @@ void BKE_packedfile_id_unpack(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index e08d3fe26fb..4e520948bcb 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -17,13 +17,13 @@
* All rights reserved.
*/
-#ifndef __BKE_PAINT_H__
-#define __BKE_PAINT_H__
+#pragma once
/** \file
* \ingroup bke
*/
+#include "BLI_bitmap.h"
#include "BLI_utildefines.h"
#include "DNA_object_enums.h"
@@ -41,6 +41,7 @@ struct EdgeSet;
struct GHash;
struct GridPaintMask;
struct ImagePool;
+struct ListBase;
struct MLoop;
struct MLoopTri;
struct MVert;
@@ -259,10 +260,20 @@ typedef struct SculptPoseIKChain {
/* Cloth Brush */
typedef struct SculptClothLengthConstraint {
- int v1;
- int v2;
+ /* Elements that are affected by the constraint. */
+ /* Element a should always be a mesh vertex with the index stored in elem_index_a as it is always
+ * deformed. Element b could be another vertex of the same mesh or any other position (arbitrary
+ * point, position for a previous state). In that case, elem_index_a and elem_index_b should be
+ * the same to avoid affecting two different vertices when solving the constraints.
+ * *elem_position points to the position which is owned by the element. */
+ int elem_index_a;
+ float *elem_position_a;
+
+ int elem_index_b;
+ float *elem_position_b;
float length;
+ float strength;
} SculptClothLengthConstraint;
typedef struct SculptClothSimulation {
@@ -272,6 +283,11 @@ typedef struct SculptClothSimulation {
int capacity_length_constraints;
float *length_constraint_tweak;
+ /* Position anchors for deformation brushes. These positions are modified by the brush and the
+ * final positions of the simulated vertices are updated with constraints that use these points
+ * as targets. */
+ float (*deformation_pos)[3];
+
float mass;
float damping;
@@ -279,7 +295,9 @@ typedef struct SculptClothSimulation {
float (*pos)[3];
float (*init_pos)[3];
float (*prev_pos)[3];
+ float (*last_iteration_pos)[3];
+ struct ListBase *collider_list;
} SculptClothSimulation;
typedef struct SculptPersistentBase {
@@ -291,6 +309,9 @@ typedef struct SculptPersistentBase {
typedef struct SculptVertexInfo {
/* Idexed by vertex, stores and ID of its topologycally connected component. */
int *connected_component;
+
+ /* Indexed by base mesh vertex index, stores if that vertex is a boundary. */
+ BLI_bitmap *boundary;
} SculptVertexInfo;
typedef struct SculptFakeNeighbors {
@@ -314,6 +335,9 @@ typedef struct SculptSession {
int level;
} multires;
+ /* Depsgraph for the Cloth Brush solver to get the colliders. */
+ struct Depsgraph *depsgraph;
+
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
struct MVert *mvert;
struct MPoly *mpoly;
@@ -447,6 +471,10 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss);
void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder);
void BKE_sculptsession_bm_to_me_for_render(struct Object *object);
+/* Create new color layer on object if it doesn't have one and if experimental feature set has
+ * sculpt vertex color enabled. Returns truth if new layer has been added, false otherwise. */
+void BKE_sculpt_color_layer_create_if_needed(struct Object *object);
+
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph,
struct Object *ob_orig,
bool need_pmap,
@@ -463,6 +491,10 @@ struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct O
void BKE_sculpt_bvh_update_from_ccg(struct PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
+/* This ensure that all elements in the mesh (both vertices and grids) have their visibility
+ * updated according to the face sets. */
+void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg);
+
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d);
enum {
@@ -473,5 +505,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index a22cb9ef126..7d317538f44 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -20,8 +20,7 @@
* Copyright 2011-2012 AutoCRC
*/
-#ifndef __BKE_PARTICLE_H__
-#define __BKE_PARTICLE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -217,7 +216,7 @@ typedef struct ParticleCollision {
/** Collision modifier for current object. */
struct CollisionModifierData *md;
- /** Time factor of previous collision, needed for substracting face velocity. */
+ /** Time factor of previous collision, needed for subtracting face velocity. */
float f;
float fac1, fac2;
@@ -365,6 +364,10 @@ struct ModifierData *object_add_particle_system(struct Main *bmain,
struct Scene *scene,
struct Object *ob,
const char *name);
+struct ModifierData *object_copy_particle_system(struct Main *bmain,
+ struct Scene *scene,
+ struct Object *ob,
+ const struct ParticleSystem *psys_orig);
void object_remove_particle_system(struct Main *bmain, struct Scene *scene, struct Object *ob);
struct ParticleSettings *BKE_particlesettings_add(struct Main *bmain, const char *name);
struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain,
@@ -576,7 +579,7 @@ void psys_particle_on_dm(struct Mesh *mesh_final,
/* particle_system.c */
void distribute_particles(struct ParticleSimulationData *sim, int from);
-void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
+void init_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
void psys_calc_dmcache(struct Object *ob,
struct Mesh *mesh_final,
struct Mesh *mesh_original,
@@ -627,5 +630,3 @@ extern void (*BKE_particle_batch_cache_free_cb)(struct ParticleSystem *psys);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_PARTICLE_H__ */
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 87875314aec..9826dfaa4a5 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_PBVH_H__
-#define __BKE_PBVH_H__
+#pragma once
/** \file
* \ingroup bke
@@ -224,7 +223,7 @@ void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3]);
unsigned int **BKE_pbvh_grid_hidden(const PBVH *pbvh);
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
- int *grid_indices,
+ const int *grid_indices,
int totgrid,
int gridsize);
@@ -264,6 +263,7 @@ void BKE_pbvh_node_mark_redraw(PBVHNode *node);
void BKE_pbvh_node_mark_normals_update(PBVHNode *node);
void BKE_pbvh_node_mark_topology_update(PBVHNode *node);
void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
+bool BKE_pbvh_node_fully_hidden_get(PBVHNode *node);
void BKE_pbvh_node_fully_masked_set(PBVHNode *node, int fully_masked);
bool BKE_pbvh_node_fully_masked_get(PBVHNode *node);
void BKE_pbvh_node_fully_unmasked_set(PBVHNode *node, int fully_masked);
@@ -488,5 +488,3 @@ void BKE_pbvh_node_color_buffer_free(PBVH *pbvh);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_PBVH_H__ */
diff --git a/source/blender/blenkernel/BKE_persistent_data_handle.hh b/source/blender/blenkernel/BKE_persistent_data_handle.hh
new file mode 100644
index 00000000000..bcc84f9c9d0
--- /dev/null
+++ b/source/blender/blenkernel/BKE_persistent_data_handle.hh
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bke
+ *
+ * A PersistentDataHandle is a weak reference to some data in a Blender file. The handle itself is
+ * just a number. A PersistentDataHandleMap is used to convert between handles and the actual data.
+ */
+
+#include "BLI_map.hh"
+
+#include "DNA_ID.h"
+
+struct Object;
+
+namespace blender::bke {
+
+class PersistentDataHandleMap;
+
+class PersistentDataHandle {
+ private:
+ /* Negative values indicate that the handle is "empty". */
+ int32_t handle_;
+
+ friend PersistentDataHandleMap;
+
+ protected:
+ PersistentDataHandle(int handle) : handle_(handle)
+ {
+ }
+
+ public:
+ PersistentDataHandle() : handle_(-1)
+ {
+ }
+
+ friend bool operator==(const PersistentDataHandle &a, const PersistentDataHandle &b)
+ {
+ return a.handle_ == b.handle_;
+ }
+
+ friend bool operator!=(const PersistentDataHandle &a, const PersistentDataHandle &b)
+ {
+ return !(a == b);
+ }
+
+ friend std::ostream &operator<<(std::ostream &stream, const PersistentDataHandle &a)
+ {
+ stream << a.handle_;
+ return stream;
+ }
+
+ uint64_t hash() const
+ {
+ return (uint64_t)handle_;
+ }
+};
+
+class PersistentIDHandle : public PersistentDataHandle {
+ friend PersistentDataHandleMap;
+ using PersistentDataHandle::PersistentDataHandle;
+};
+
+class PersistentObjectHandle : public PersistentIDHandle {
+ friend PersistentDataHandleMap;
+ using PersistentIDHandle::PersistentIDHandle;
+};
+
+class PersistentDataHandleMap {
+ private:
+ Map<int32_t, ID *> id_by_handle_;
+ Map<ID *, int32_t> handle_by_id_;
+
+ public:
+ void add(int32_t handle, ID &id)
+ {
+ BLI_assert(handle >= 0);
+ handle_by_id_.add(&id, handle);
+ id_by_handle_.add(handle, &id);
+ }
+
+ PersistentIDHandle lookup(ID *id) const
+ {
+ const int handle = handle_by_id_.lookup_default(id, -1);
+ return PersistentIDHandle(handle);
+ }
+
+ PersistentObjectHandle lookup(Object *object) const
+ {
+ const int handle = handle_by_id_.lookup_default((ID *)object, -1);
+ return PersistentObjectHandle(handle);
+ }
+
+ ID *lookup(const PersistentIDHandle &handle) const
+ {
+ ID *id = id_by_handle_.lookup_default(handle.handle_, nullptr);
+ return id;
+ }
+
+ Object *lookup(const PersistentObjectHandle &handle) const
+ {
+ ID *id = this->lookup((const PersistentIDHandle &)handle);
+ if (id == nullptr) {
+ return nullptr;
+ }
+ if (GS(id->name) != ID_OB) {
+ return nullptr;
+ }
+ return (Object *)id;
+ }
+};
+
+} // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index b0973ed458c..c5bf94cc0c8 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_POINTCACHE_H__
-#define __BKE_POINTCACHE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -86,12 +85,10 @@ struct ListBase;
struct Main;
struct Object;
struct ParticleKey;
-struct ParticleSimulationState;
struct ParticleSystem;
struct PointCache;
struct RigidBodyWorld;
struct Scene;
-struct Simulation;
struct SoftBody;
struct ViewLayer;
@@ -147,7 +144,7 @@ typedef struct PTCacheID {
/* copies point data to cache data */
int (*write_point)(int index, void *calldata, void **data, int cfra);
/* copies cache cata to point data */
- void (*read_point)(int index, void *calldata, void **data, float cfra, float *old_data);
+ void (*read_point)(int index, void *calldata, void **data, float cfra, const float *old_data);
/* interpolated between previously read point data and cache data */
void (*interpolate_point)(int index,
void *calldata,
@@ -155,7 +152,7 @@ typedef struct PTCacheID {
float cfra,
float cfra1,
float cfra2,
- float *old_data);
+ const float *old_data);
/* copies point data to cache data */
int (*write_stream)(PTCacheFile *pf, void *calldata);
@@ -296,7 +293,6 @@ void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid,
struct Object *ob,
struct DynamicPaintSurface *surface);
void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, struct Object *ob, struct RigidBodyWorld *rbw);
-void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, struct ParticleSimulationState *state);
PTCacheID BKE_ptcache_id_find(struct Object *ob, struct Scene *scene, struct PointCache *cache);
void BKE_ptcache_ids_from_object(struct ListBase *lb,
@@ -390,5 +386,3 @@ void BKE_ptcache_invalidate(struct PointCache *cache);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_pointcloud.h b/source/blender/blenkernel/BKE_pointcloud.h
index d641d3feb62..b2e7e1d23ee 100644
--- a/source/blender/blenkernel/BKE_pointcloud.h
+++ b/source/blender/blenkernel/BKE_pointcloud.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_POINTCLOUD_H__
-#define __BKE_POINTCLOUD_H__
+#pragma once
/** \file
* \ingroup bke
@@ -64,5 +63,3 @@ extern void (*BKE_pointcloud_batch_cache_free_cb)(struct PointCloud *pointcloud)
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h
index 063c0831a0d..5b22918e84c 100644
--- a/source/blender/blenkernel/BKE_report.h
+++ b/source/blender/blenkernel/BKE_report.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_REPORT_H__
-#define __BKE_REPORT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -69,5 +68,3 @@ bool BKE_report_write_file(const char *filepath, ReportList *reports, const char
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index b4aa0ac2b93..c2059144388 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -22,8 +22,7 @@
* \brief API for Blender-side Rigid Body stuff
*/
-#ifndef __BKE_RIGIDBODY_H__
-#define __BKE_RIGIDBODY_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -162,5 +161,3 @@ void BKE_rigidbody_object_sync_transforms(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_RIGIDBODY_H__ */
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 800370318c4..8cd86593873 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_SCENE_H__
-#define __BKE_SCENE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -260,5 +259,3 @@ void BKE_scene_eval_sequencer_sequences(struct Depsgraph *depsgraph, struct Scen
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 91f241018ec..edab543fc37 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_SCREEN_H__
-#define __BKE_SCREEN_H__
+#pragma once
/** \file
* \ingroup bke
@@ -73,7 +72,7 @@ typedef struct SpaceType {
/* 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 *area, const struct Scene *scene);
+ struct SpaceLink *(*create)(const struct ScrArea *area, const struct Scene *scene);
/* not free spacelink itself */
void (*free)(struct SpaceLink *sl);
@@ -142,7 +141,13 @@ typedef struct ARegionType {
void (*exit)(struct wmWindowManager *wm, struct ARegion *region);
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *C, struct ARegion *region);
- /* Handler to draw overlays. This handler is called every draw loop. */
+ /**
+ * Handler to draw overlays. This handler is called every draw loop.
+ *
+ * \note Some editors should return early if the interface is locked
+ * (check with #CTX_wm_interface_locked) to avoid accessing scene data
+ * that another thread may be modifying
+ */
void (*draw_overlay)(const struct bContext *C, struct ARegion *region);
/* optional, compute button layout before drawing for dynamic size */
void (*layout)(const struct bContext *C, struct ARegion *region);
@@ -430,5 +435,3 @@ void BKE_screen_header_alignment_reset(struct bScreen *screen);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index a50f9b24c61..b6d901c8ef2 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_SEQUENCER_H__
-#define __BKE_SEQUENCER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -285,6 +284,11 @@ void BKE_sequence_reload_new_file(struct Main *bmain,
struct Scene *scene,
struct Sequence *seq,
const bool lock_range);
+void BKE_sequence_movie_reload_if_needed(struct Main *bmain,
+ struct Scene *scene,
+ struct Sequence *seq,
+ bool *r_was_reloaded,
+ bool *r_can_produce_frames);
int BKE_sequencer_evaluate_frame(struct Scene *scene, int cfra);
int BKE_sequencer_get_shown_sequences(struct ListBase *seqbasep,
int cfra,
@@ -522,6 +526,9 @@ typedef struct Sequence *(*SeqLoadFn)(struct bContext *, ListBase *, struct SeqL
struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine, int type);
+/* Generate new UUID for the given sequence. */
+void BKE_sequence_session_uuid_generate(struct Sequence *sequence);
+
void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
void BKE_sequence_init_colorspace(struct Sequence *seq);
@@ -619,9 +626,16 @@ void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb,
void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra);
bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports);
+bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq);
+void BKE_sequencer_flag_for_removal(struct Scene *scene,
+ struct ListBase *seqbase,
+ struct Sequence *seq);
+void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase);
+
+/* A debug and development function which checks whether sequences have unique UUIDs.
+ * Errors will be reported to the console. */
+void BKE_sequencer_check_uuids_unique_and_report(const struct Scene *scene);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SEQUENCER_H__ */
diff --git a/source/blender/blenkernel/BKE_sequencer_offscreen.h b/source/blender/blenkernel/BKE_sequencer_offscreen.h
index cc822e97270..90d3f80320a 100644
--- a/source/blender/blenkernel/BKE_sequencer_offscreen.h
+++ b/source/blender/blenkernel/BKE_sequencer_offscreen.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_SEQUENCER_OFFSCREEN_H__
-#define __BKE_SEQUENCER_OFFSCREEN_H__
+#pragma once
/** \file
* \ingroup bke
@@ -52,5 +51,3 @@ extern SequencerDrawView sequencer_view3d_fn;
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SEQUENCER_H__ */
diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h
index 31e14c6c884..1eb52b389d1 100644
--- a/source/blender/blenkernel/BKE_shader_fx.h
+++ b/source/blender/blenkernel/BKE_shader_fx.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_SHADER_FX_H__
-#define __BKE_SHADER_FX_H__
+#pragma once
/** \file
* \ingroup bke
@@ -189,5 +188,3 @@ bool BKE_shaderfx_has_gpencil(struct Object *ob);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SHADER_FX_H__ */
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index 83129bed5f7..bcf702ea797 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_SHRINKWRAP_H__
-#define __BKE_SHRINKWRAP_H__
+#pragma once
/** \file
* \ingroup bke
@@ -192,5 +191,3 @@ void BKE_shrinkwrap_snap_point_to_surface(const struct ShrinkwrapTreeData *tree,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SHRINKWRAP_H__ */
diff --git a/source/blender/blenkernel/BKE_simulation.h b/source/blender/blenkernel/BKE_simulation.h
index ff6aaa5e30e..2c436f2bff8 100644
--- a/source/blender/blenkernel/BKE_simulation.h
+++ b/source/blender/blenkernel/BKE_simulation.h
@@ -14,8 +14,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_SIMULATION_H__
-#define __BKE_SIMULATION_H__
+#pragma once
+
+#include "DNA_simulation_types.h"
#ifdef __cplusplus
extern "C" {
@@ -23,16 +24,34 @@ extern "C" {
struct Depsgraph;
struct Main;
-struct Simulation;
+struct Scene;
void *BKE_simulation_add(struct Main *bmain, const char *name);
void BKE_simulation_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Simulation *simulation);
+void BKE_simulation_update_dependencies(struct Simulation *simulation, struct Main *bmain);
+
+SimulationState *BKE_simulation_state_add(Simulation *simulation,
+ const char *type,
+ const char *name);
+void BKE_simulation_state_remove(Simulation *simulation, SimulationState *state);
+void BKE_simulation_state_remove_all(Simulation *simulation);
+void BKE_simulation_state_reset(Simulation *simulation, SimulationState *state);
+void BKE_simulation_state_reset_all(Simulation *simulation);
+SimulationState *BKE_simulation_state_try_find_by_name(Simulation *simulation, const char *name);
+SimulationState *BKE_simulation_state_try_find_by_name_and_type(Simulation *simulation,
+ const char *name,
+ const char *type);
+void BKE_simulation_state_copy_data(const SimulationState *src_state, SimulationState *dst_state);
#ifdef __cplusplus
}
#endif
-#endif /* __BKE_SIMULATION_H__ */
+#ifdef __cplusplus
+
+template<typename StateType> const char *BKE_simulation_get_state_type_name();
+
+#endif
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index e4012094b74..28d299679ed 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) Blender Foundation.
* All rights reserved.
*/
-#ifndef __BKE_SOFTBODY_H__
-#define __BKE_SOFTBODY_H__
+#pragma once
/** \file
* \ingroup bke
@@ -76,5 +75,3 @@ extern void SB_estimate_transform(Object *ob, float lloc[3], float lrot[3][3], f
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index b93591b7b60..57ce33a239f 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_SOUND_H__
-#define __BKE_SOUND_H__
+#pragma once
/** \file
* \ingroup bke
@@ -194,5 +193,3 @@ void BKE_sound_evaluate(struct Depsgraph *depsgraph, struct Main *bmain, struct
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SOUND_H__ */
diff --git a/source/blender/blenkernel/BKE_speaker.h b/source/blender/blenkernel/BKE_speaker.h
index 54bb7274e4b..b01824dd794 100644
--- a/source/blender/blenkernel/BKE_speaker.h
+++ b/source/blender/blenkernel/BKE_speaker.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_SPEAKER_H__
-#define __BKE_SPEAKER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -35,5 +34,3 @@ struct Speaker *BKE_speaker_copy(struct Main *bmain, const struct Speaker *spk);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h
index ff11f581cc4..32c571e5f91 100644
--- a/source/blender/blenkernel/BKE_studiolight.h
+++ b/source/blender/blenkernel/BKE_studiolight.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_STUDIOLIGHT_H__
-#define __BKE_STUDIOLIGHT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -168,5 +167,3 @@ void BKE_studiolight_unset_icon_id(StudioLight *sl, int icon_id);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_STUDIOLIGHT_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index 1323938e479..96a79d753cf 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_H__
-#define __BKE_SUBDIV_H__
+#pragma once
#include "BLI_compiler_compat.h"
#include "BLI_sys_types.h"
@@ -302,5 +301,3 @@ BLI_INLINE float BKE_subdiv_edge_crease_to_sharpness_char(char edge_crease);
#endif
#include "intern/subdiv_inline.h"
-
-#endif /* __BKE_SUBDIV_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_ccg.h b/source/blender/blenkernel/BKE_subdiv_ccg.h
index 78e91d3ad2f..2277eb27ef1 100644
--- a/source/blender/blenkernel/BKE_subdiv_ccg.h
+++ b/source/blender/blenkernel/BKE_subdiv_ccg.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_CCG_H__
-#define __BKE_SUBDIV_CCG_H__
+#pragma once
#include "BKE_DerivedMesh.h"
#include "BKE_customdata.h"
@@ -313,6 +312,22 @@ void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG *subdiv_ccg,
int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int grid_index);
+typedef enum SubdivCCGAdjacencyType {
+ SUBDIV_CCG_ADJACENT_NONE,
+ SUBDIV_CCG_ADJACENT_VERTEX,
+ SUBDIV_CCG_ADJACENT_EDGE,
+} SubdivCCGAdjacencyType;
+
+/* Returns if a grid coordinates is adjacent to a coarse mesh edge, vertex or nothing. If it is
+ * adjacent to an edge, r_v1 and r_v2 will be set to the two vertices of that edge. If it is
+ * adjacent to a vertex, r_v1 and r_v2 will be the index of that vertex. */
+SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG *subdiv_ccg,
+ const SubdivCCGCoord *coord,
+ const MLoop *mloop,
+ const MPoly *mpoly,
+ int *r_v1,
+ int *r_v2);
+
/* Get array which is indexed by face index and contains index of a first grid of the face.
*
* The "ensure" version allocates the mapping if it's not know yet and stores it in the subdiv_ccg
@@ -322,8 +337,8 @@ int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int gri
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg);
const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg);
+void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_CCG_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_deform.h b/source/blender/blenkernel/BKE_subdiv_deform.h
index 735cd20a6c8..1cdb8d2c794 100644
--- a/source/blender/blenkernel/BKE_subdiv_deform.h
+++ b/source/blender/blenkernel/BKE_subdiv_deform.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_DEFORM_H__
-#define __BKE_SUBDIV_DEFORM_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -48,5 +47,3 @@ void BKE_subdiv_deform_coarse_vertices(struct Subdiv *subdiv,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_DEFORM_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_eval.h b/source/blender/blenkernel/BKE_subdiv_eval.h
index aa27df88be8..204e802da6e 100644
--- a/source/blender/blenkernel/BKE_subdiv_eval.h
+++ b/source/blender/blenkernel/BKE_subdiv_eval.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_EVAL_H__
-#define __BKE_SUBDIV_EVAL_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -149,5 +148,3 @@ void BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal(struct Subdiv
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_EVAL_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_foreach.h b/source/blender/blenkernel/BKE_subdiv_foreach.h
index bef141b5ac5..a351b9a3d11 100644
--- a/source/blender/blenkernel/BKE_subdiv_foreach.h
+++ b/source/blender/blenkernel/BKE_subdiv_foreach.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_FOREACH_H__
-#define __BKE_SUBDIV_FOREACH_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -178,5 +177,3 @@ bool BKE_subdiv_foreach_subdiv_geometry(struct Subdiv *subdiv,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_FOREACH_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_mesh.h b/source/blender/blenkernel/BKE_subdiv_mesh.h
index 9928c41a92b..73a3e8ed02e 100644
--- a/source/blender/blenkernel/BKE_subdiv_mesh.h
+++ b/source/blender/blenkernel/BKE_subdiv_mesh.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_MESH_H__
-#define __BKE_SUBDIV_MESH_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -53,5 +52,3 @@ struct Mesh *BKE_subdiv_to_mesh(struct Subdiv *subdiv,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV)MESH_H__ */
diff --git a/source/blender/blenkernel/BKE_subdiv_topology.h b/source/blender/blenkernel/BKE_subdiv_topology.h
index cc32b4c03b3..42bd9392aa4 100644
--- a/source/blender/blenkernel/BKE_subdiv_topology.h
+++ b/source/blender/blenkernel/BKE_subdiv_topology.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_SUBDIV_TOPOLOGY_H__
-#define __BKE_SUBDIV_TOPOLOGY_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -35,5 +34,3 @@ int BKE_subdiv_topology_num_fvar_layers_get(const struct Subdiv *subdiv);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_SUBDIV_TOPOLOGY_H__ */
diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h
index 0ed58180ffa..07bbeafb1ae 100644
--- a/source/blender/blenkernel/BKE_subsurf.h
+++ b/source/blender/blenkernel/BKE_subsurf.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_SUBSURF_H__
-#define __BKE_SUBSURF_H__
+#pragma once
/** \file
* \ingroup bke
@@ -158,5 +157,3 @@ typedef struct CCGDerivedMesh {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 51d589e61c3..289ad351429 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_TEXT_H__
-#define __BKE_TEXT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -118,5 +117,3 @@ void txt_from_buf_for_undo(struct Text *text, const char *buf, int buf_len);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_text_suggestions.h b/source/blender/blenkernel/BKE_text_suggestions.h
index d618fcd6d11..f54e45b6c2f 100644
--- a/source/blender/blenkernel/BKE_text_suggestions.h
+++ b/source/blender/blenkernel/BKE_text_suggestions.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2008, Blender Foundation
* All rights reserved.
*/
-#ifndef __BKE_TEXT_SUGGESTIONS_H__
-#define __BKE_TEXT_SUGGESTIONS_H__
+#pragma once
/** \file
* \ingroup bke
@@ -85,5 +84,3 @@ void texttool_docs_clear(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_TEXT_SUGGESTIONS_H__ */
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 43ef2b1ba7f..c4c2498c2b1 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_TEXTURE_H__
-#define __BKE_TEXTURE_H__
+#pragma once
/** \file
* \ingroup bke
@@ -102,5 +101,3 @@ void BKE_texture_fetch_images_for_pool(struct Tex *texture, struct ImagePool *po
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index bb88fbf863b..2d763132923 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_TRACKING_H__
-#define __BKE_TRACKING_H__
+#pragma once
/** \file
* \ingroup bke
@@ -493,5 +492,3 @@ void BKE_tracking_get_rna_path_prefix_for_plane_track(
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index b32c3e315ff..4f933ca7a87 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_UNDO_SYSTEM_H__
-#define __BKE_UNDO_SYSTEM_H__
+#pragma once
/** \file
* \ingroup bke
@@ -212,5 +211,3 @@ void BKE_undosys_print(UndoStack *ustack);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_UNDO_SYSTEM_H__ */
diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h
index 4f9ff61c9a6..a797c5555ff 100644
--- a/source/blender/blenkernel/BKE_unit.h
+++ b/source/blender/blenkernel/BKE_unit.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_UNIT_H__
-#define __BKE_UNIT_H__
+#pragma once
/** \file
* \ingroup bke
@@ -93,5 +92,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_UNIT_H__ */
diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 224f3ede45d..b3437454f31 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_VOLUME_H__
-#define __BKE_VOLUME_H__
+#pragma once
/** \file
* \ingroup bke
@@ -159,5 +158,3 @@ openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const struct Volume *vo
struct VolumeGrid *grid,
const bool clear);
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_volume_render.h b/source/blender/blenkernel/BKE_volume_render.h
index 5c3cd0102cf..a42f24a5312 100644
--- a/source/blender/blenkernel/BKE_volume_render.h
+++ b/source/blender/blenkernel/BKE_volume_render.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_VOLUME_RENDER_H__
-#define __BKE_VOLUME_RENDER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -66,5 +65,3 @@ float BKE_volume_density_scale(const struct Volume *volume, const float matrix[4
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 8a6afd8a753..5ff1ba2c6f5 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __BKE_WORKSPACE_H__
-#define __BKE_WORKSPACE_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -112,5 +111,3 @@ void BKE_workspace_id_tag_all_visible(struct Main *bmain, int tag) ATTR_NONNULL(
#ifdef __cplusplus
}
#endif
-
-#endif /* __BKE_WORKSPACE_H__ */
diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h
index 3c8f8547b46..82830facccc 100644
--- a/source/blender/blenkernel/BKE_world.h
+++ b/source/blender/blenkernel/BKE_world.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BKE_WORLD_H__
-#define __BKE_WORLD_H__
+#pragma once
/** \file
* \ingroup bke
@@ -39,5 +38,3 @@ void BKE_world_eval(struct Depsgraph *depsgraph, struct World *world);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_writeavi.h b/source/blender/blenkernel/BKE_writeavi.h
index 79605e99306..97f998cc1c1 100644
--- a/source/blender/blenkernel/BKE_writeavi.h
+++ b/source/blender/blenkernel/BKE_writeavi.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_WRITEAVI_H__
-#define __BKE_WRITEAVI_H__
+#pragma once
/** \file
* \ingroup bke
@@ -73,5 +72,3 @@ void BKE_movie_filepath_get(char *string,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h
index 467e6ab7242..4c966c55e41 100644
--- a/source/blender/blenkernel/BKE_writeffmpeg.h
+++ b/source/blender/blenkernel/BKE_writeffmpeg.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BKE_WRITEFFMPEG_H__
-#define __BKE_WRITEFFMPEG_H__
+#pragma once
/** \file
* \ingroup bke
@@ -100,5 +99,3 @@ void BKE_ffmpeg_context_free(void *context_v);
# endif
#endif
-
-#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index b9054d29752..ada341ff570 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -27,6 +27,7 @@ set(INC
../bmesh
../depsgraph
../draw
+ ../functions
../gpencil_modifiers
../gpu
../ikplugin
@@ -35,7 +36,7 @@ set(INC
../makesrna
../modifiers
../nodes
- ../physics
+ ../simulation
../shader_fx
../render/extern/include
../../../intern/ghost
@@ -99,6 +100,7 @@ set(SRC
intern/context.c
intern/crazyspace.c
intern/curve.c
+ intern/curve_bevel.c
intern/curve_decimate.c
intern/curve_deform.c
intern/curveprofile.c
@@ -106,7 +108,6 @@ set(SRC
intern/customdata_file.c
intern/data_transfer.c
intern/deform.c
- intern/derived_node_tree.cc
intern/displist.c
intern/displist_tangent.c
intern/dynamicpaint.c
@@ -134,6 +135,7 @@ set(SRC
intern/idtype.c
intern/image.c
intern/image_gen.c
+ intern/image_gpu.c
intern/image_save.c
intern/ipo.c
intern/kelvinlet.c
@@ -187,7 +189,6 @@ set(SRC
intern/multires_unsubdivide.c
intern/nla.c
intern/node.c
- intern/node_tree_ref.cc
intern/object.c
intern/object_deform.c
intern/object_dupli.c
@@ -296,7 +297,6 @@ set(SRC
BKE_customdata_file.h
BKE_data_transfer.h
BKE_deform.h
- BKE_derived_node_tree.hh
BKE_displist.h
BKE_displist_tangent.h
BKE_duplilist.h
@@ -322,6 +322,7 @@ set(SRC
BKE_idprop.h
BKE_idtype.h
BKE_image.h
+ BKE_image_save.h
BKE_ipo.h
BKE_kelvinlet.h
BKE_key.h
@@ -356,7 +357,6 @@ set(SRC
BKE_multires.h
BKE_nla.h
BKE_node.h
- BKE_node_tree_ref.hh
BKE_object.h
BKE_object_deform.h
BKE_object_facemap.h
@@ -365,6 +365,7 @@ set(SRC
BKE_packedFile.h
BKE_paint.h
BKE_particle.h
+ BKE_persistent_data_handle.hh
BKE_pbvh.h
BKE_pointcache.h
BKE_pointcloud.h
@@ -373,6 +374,7 @@ set(SRC
BKE_scene.h
BKE_screen.h
BKE_sequencer.h
+ BKE_sequencer_offscreen.h
BKE_shader_fx.h
BKE_shrinkwrap.h
BKE_simulation.h
@@ -411,6 +413,7 @@ set(SRC
intern/multires_inline.h
intern/multires_reshape.h
intern/multires_unsubdivide.h
+ intern/ocean_intern.h
intern/pbvh_intern.h
intern/subdiv_converter.h
intern/subdiv_inline.h
@@ -424,6 +427,7 @@ set(LIB
bf_bmesh
bf_depsgraph
bf_draw
+ bf_functions
bf_gpencil_modifiers
bf_gpu
bf_ikplugin
@@ -436,7 +440,7 @@ set(LIB
bf_intern_opensubdiv # Uses stub when disabled.
bf_modifiers
bf_nodes
- bf_physics
+ bf_simulation
bf_rna
bf_shader_fx
)
@@ -694,3 +698,16 @@ blender_add_lib(bf_blenkernel "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# Needed so we can use dna_type_offsets.h for defaults initialization.
add_dependencies(bf_blenkernel bf_dna)
+
+
+if(WITH_GTESTS)
+ set(TEST_SRC
+ intern/armature_test.cc
+ intern/fcurve_test.cc
+ )
+ set(TEST_INC
+ ../editors/include
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_blenkernel_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB}")
+endif()
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 98deddb4316..8d8301362b3 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -32,8 +32,6 @@
#include "CCGSubSurf.h"
#include "CCGSubSurf_intern.h"
-#include "GPU_glew.h"
-
/***/
int BKE_ccg_gridsize(int level)
@@ -177,9 +175,7 @@ static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSiz
if (v == e->v0) {
return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
}
- else {
- return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
- }
+ return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
}
static void _edge_free(CCGEdge *e, CCGSubSurf *ss)
@@ -260,46 +256,45 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc,
if (subdivLevels < 1) {
return NULL;
}
- else {
- CCGSubSurf *ss = allocatorIFC->alloc(allocator, sizeof(*ss));
- ss->allocatorIFC = *allocatorIFC;
- ss->allocator = allocator;
+ CCGSubSurf *ss = allocatorIFC->alloc(allocator, sizeof(*ss));
- ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
- ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
- ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
+ ss->allocatorIFC = *allocatorIFC;
+ ss->allocator = allocator;
- ss->meshIFC = *ifc;
+ ss->vMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
+ ss->eMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
+ ss->fMap = ccg_ehash_new(0, &ss->allocatorIFC, ss->allocator);
- ss->subdivLevels = subdivLevels;
- ss->numGrids = 0;
- ss->allowEdgeCreation = 0;
- ss->defaultCreaseValue = 0;
- ss->defaultEdgeUserData = NULL;
+ ss->meshIFC = *ifc;
- ss->useAgeCounts = 0;
- ss->vertUserAgeOffset = ss->edgeUserAgeOffset = ss->faceUserAgeOffset = 0;
+ ss->subdivLevels = subdivLevels;
+ ss->numGrids = 0;
+ ss->allowEdgeCreation = 0;
+ ss->defaultCreaseValue = 0;
+ ss->defaultEdgeUserData = NULL;
- ss->calcVertNormals = 0;
- ss->normalDataOffset = 0;
+ ss->useAgeCounts = 0;
+ ss->vertUserAgeOffset = ss->edgeUserAgeOffset = ss->faceUserAgeOffset = 0;
- ss->allocMask = 0;
+ ss->calcVertNormals = 0;
+ ss->normalDataOffset = 0;
- ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
- ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
+ ss->allocMask = 0;
- ss->currentAge = 0;
+ ss->q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
+ ss->r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize);
- ss->syncState = eSyncState_None;
+ ss->currentAge = 0;
- ss->oldVMap = ss->oldEMap = ss->oldFMap = NULL;
- ss->lenTempArrays = 0;
- ss->tempVerts = NULL;
- ss->tempEdges = NULL;
+ ss->syncState = eSyncState_None;
- return ss;
- }
+ ss->oldVMap = ss->oldEMap = ss->oldFMap = NULL;
+ ss->lenTempArrays = 0;
+ ss->tempVerts = NULL;
+ ss->tempEdges = NULL;
+
+ return ss;
}
void ccgSubSurf_free(CCGSubSurf *ss)
@@ -378,7 +373,7 @@ CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
if (subdivisionLevels <= 0) {
return eCCGError_InvalidValue;
}
- else if (subdivisionLevels != ss->subdivLevels) {
+ if (subdivisionLevels != ss->subdivLevels) {
ss->numGrids = 0;
ss->subdivLevels = subdivisionLevels;
ccg_ehash_free(ss->vMap, (EHEntryFreeFP)_vert_free, ss);
@@ -420,12 +415,10 @@ CCGError ccgSubSurf_setUseAgeCounts(
(faceUserOffset + 4 > ss->meshIFC.faceUserSize)) {
return eCCGError_InvalidValue;
}
- else {
- ss->useAgeCounts = 1;
- ss->vertUserAgeOffset = vertUserOffset;
- ss->edgeUserAgeOffset = edgeUserOffset;
- ss->faceUserAgeOffset = faceUserOffset;
- }
+ ss->useAgeCounts = 1;
+ ss->vertUserAgeOffset = vertUserOffset;
+ ss->edgeUserAgeOffset = edgeUserOffset;
+ ss->faceUserAgeOffset = faceUserOffset;
}
else {
ss->useAgeCounts = 0;
@@ -441,10 +434,8 @@ CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int
if (normalDataOffset < 0 || normalDataOffset + 12 > ss->meshIFC.vertDataSize) {
return eCCGError_InvalidValue;
}
- else {
- ss->calcVertNormals = 1;
- ss->normalDataOffset = normalDataOffset;
- }
+ ss->calcVertNormals = 1;
+ ss->normalDataOffset = normalDataOffset;
}
else {
ss->calcVertNormals = 0;
@@ -512,19 +503,17 @@ CCGError ccgSubSurf_syncVertDel(CCGSubSurf *ss, CCGVertHDL vHDL)
if (ss->syncState != eSyncState_Partial) {
return eCCGError_InvalidSyncState;
}
- else {
- void **prevp;
- CCGVert *v = ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
- if (!v || v->numFaces || v->numEdges) {
- return eCCGError_InvalidValue;
- }
- else {
- *prevp = v->next;
- _vert_free(v, ss);
- }
+ void **prevp;
+ CCGVert *v = ccg_ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
+
+ if (!v || v->numFaces || v->numEdges) {
+ return eCCGError_InvalidValue;
}
+ *prevp = v->next;
+ _vert_free(v, ss);
+
return eCCGError_None;
}
@@ -533,19 +522,17 @@ CCGError ccgSubSurf_syncEdgeDel(CCGSubSurf *ss, CCGEdgeHDL eHDL)
if (ss->syncState != eSyncState_Partial) {
return eCCGError_InvalidSyncState;
}
- else {
- void **prevp;
- CCGEdge *e = ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp);
- if (!e || e->numFaces) {
- return eCCGError_InvalidValue;
- }
- else {
- *prevp = e->next;
- _edge_unlinkMarkAndFree(e, ss);
- }
+ void **prevp;
+ CCGEdge *e = ccg_ehash_lookupWithPrev(ss->eMap, eHDL, &prevp);
+
+ if (!e || e->numFaces) {
+ return eCCGError_InvalidValue;
}
+ *prevp = e->next;
+ _edge_unlinkMarkAndFree(e, ss);
+
return eCCGError_None;
}
@@ -554,19 +541,17 @@ CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL)
if (ss->syncState != eSyncState_Partial) {
return eCCGError_InvalidSyncState;
}
- else {
- void **prevp;
- CCGFace *f = ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp);
- if (!f) {
- return eCCGError_InvalidValue;
- }
- else {
- *prevp = f->next;
- _face_unlinkMarkAndFree(f, ss);
- }
+ void **prevp;
+ CCGFace *f = ccg_ehash_lookupWithPrev(ss->fMap, fHDL, &prevp);
+
+ if (!f) {
+ return eCCGError_InvalidValue;
}
+ *prevp = f->next;
+ _face_unlinkMarkAndFree(f, ss);
+
return eCCGError_None;
}
@@ -1264,9 +1249,7 @@ int ccgSubSurf_getEdgeLevelSize(const CCGSubSurf *ss, int level)
if (level < 1 || level > ss->subdivLevels) {
return -1;
}
- else {
- return ccg_edgesize(level);
- }
+ return ccg_edgesize(level);
}
int ccgSubSurf_getGridSize(const CCGSubSurf *ss)
{
@@ -1277,9 +1260,7 @@ int ccgSubSurf_getGridLevelSize(const CCGSubSurf *ss, int level)
if (level < 1 || level > ss->subdivLevels) {
return -1;
}
- else {
- return ccg_gridsize(level);
- }
+ return ccg_gridsize(level);
}
int ccgSubSurf_getSimpleSubdiv(const CCGSubSurf *ss)
@@ -1299,9 +1280,7 @@ int ccgSubSurf_getVertAge(CCGSubSurf *ss, CCGVert *v)
byte *userData = ccgSubSurf_getVertUserData(ss, v);
return ss->currentAge - *((int *)&userData[ss->vertUserAgeOffset]);
}
- else {
- return 0;
- }
+ return 0;
}
void *ccgSubSurf_getVertUserData(CCGSubSurf *ss, CCGVert *v)
{
@@ -1316,9 +1295,7 @@ CCGFace *ccgSubSurf_getVertFace(CCGVert *v, int index)
if (index < 0 || index >= v->numFaces) {
return NULL;
}
- else {
- return v->faces[index];
- }
+ return v->faces[index];
}
int ccgSubSurf_getVertNumEdges(CCGVert *v)
{
@@ -1329,9 +1306,7 @@ CCGEdge *ccgSubSurf_getVertEdge(CCGVert *v, int index)
if (index < 0 || index >= v->numEdges) {
return NULL;
}
- else {
- return v->edges[index];
- }
+ return v->edges[index];
}
void *ccgSubSurf_getVertData(CCGSubSurf *ss, CCGVert *v)
{
@@ -1342,9 +1317,7 @@ void *ccgSubSurf_getVertLevelData(CCGSubSurf *ss, CCGVert *v, int level)
if (level < 0 || level > ss->subdivLevels) {
return NULL;
}
- else {
- return ccg_vert_getCo(v, level, ss->meshIFC.vertDataSize);
- }
+ return ccg_vert_getCo(v, level, ss->meshIFC.vertDataSize);
}
/* Edge accessors */
@@ -1359,9 +1332,7 @@ int ccgSubSurf_getEdgeAge(CCGSubSurf *ss, CCGEdge *e)
byte *userData = ccgSubSurf_getEdgeUserData(ss, e);
return ss->currentAge - *((int *)&userData[ss->edgeUserAgeOffset]);
}
- else {
- return 0;
- }
+ return 0;
}
void *ccgSubSurf_getEdgeUserData(CCGSubSurf *ss, CCGEdge *e)
{
@@ -1376,9 +1347,7 @@ CCGFace *ccgSubSurf_getEdgeFace(CCGEdge *e, int index)
if (index < 0 || index >= e->numFaces) {
return NULL;
}
- else {
- return e->faces[index];
- }
+ return e->faces[index];
}
CCGVert *ccgSubSurf_getEdgeVert0(CCGEdge *e)
{
@@ -1401,9 +1370,7 @@ void *ccgSubSurf_getEdgeLevelData(CCGSubSurf *ss, CCGEdge *e, int x, int level)
if (level < 0 || level > ss->subdivLevels) {
return NULL;
}
- else {
- return ccg_edge_getCo(e, level, x, ss->meshIFC.vertDataSize);
- }
+ return ccg_edge_getCo(e, level, x, ss->meshIFC.vertDataSize);
}
float ccgSubSurf_getEdgeCrease(CCGEdge *e)
{
@@ -1422,9 +1389,7 @@ int ccgSubSurf_getFaceAge(CCGSubSurf *ss, CCGFace *f)
byte *userData = ccgSubSurf_getFaceUserData(ss, f);
return ss->currentAge - *((int *)&userData[ss->faceUserAgeOffset]);
}
- else {
- return 0;
- }
+ return 0;
}
void *ccgSubSurf_getFaceUserData(CCGSubSurf *ss, CCGFace *f)
{
@@ -1442,18 +1407,14 @@ CCGVert *ccgSubSurf_getFaceVert(CCGFace *f, int index)
if (index < 0 || index >= f->numVerts) {
return NULL;
}
- else {
- return FACE_getVerts(f)[index];
- }
+ return FACE_getVerts(f)[index];
}
CCGEdge *ccgSubSurf_getFaceEdge(CCGFace *f, int index)
{
if (index < 0 || index >= f->numVerts) {
return NULL;
}
- else {
- return FACE_getEdges(f)[index];
- }
+ return FACE_getEdges(f)[index];
}
int ccgSubSurf_getFaceEdgeIndex(CCGFace *f, CCGEdge *e)
{
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 2e5100db6de..e1805a9c512 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __CCGSUBSURF_H__
-#define __CCGSUBSURF_H__
+#pragma once
/** \file
* \ingroup bke
@@ -210,5 +209,3 @@ void ccgEdgeIterator_next(CCGEdgeIterator *ei);
CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *fi);
int ccgFaceIterator_isStopped(CCGFaceIterator *fi);
void ccgFaceIterator_next(CCGFaceIterator *fi);
-
-#endif /* __CCGSUBSURF_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_inline.h b/source/blender/blenkernel/intern/CCGSubSurf_inline.h
index 86012bd2a43..8aa1fede57d 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_inline.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf_inline.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __CCGSUBSURF_INLINE_H__
-#define __CCGSUBSURF_INLINE_H__
+#pragma once
BLI_INLINE int ccg_gridsize(int level)
{
@@ -274,5 +273,3 @@ BLI_INLINE void VertDataAvg4(float v[],
v[i] = (a[i] + b[i] + c[i] + d[i]) * 0.25f;
}
}
-
-#endif /* __CCGSUBSURF_INLINE_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
index 7c35d2ccfce..82ca22e193a 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h
@@ -18,8 +18,7 @@
* \ingroup bke
*/
-#ifndef __CCGSUBSURF_INTERN_H__
-#define __CCGSUBSURF_INTERN_H__
+#pragma once
/**
* Definitions which defines internal behavior of CCGSubSurf.
@@ -286,5 +285,3 @@ void ccgSubSurf__dumpCoords(CCGSubSurf *ss);
#endif
#include "CCGSubSurf_inline.h"
-
-#endif /* __CCGSUBSURF_INTERN_H__ */
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
index f3f681baa01..8fc9afd58f1 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c
@@ -38,9 +38,7 @@ static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSiz
if (v == e->v0) {
return &EDGE_getLevelData(e)[dataSize * (levelBase + x)];
}
- else {
- return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
- }
+ return &EDGE_getLevelData(e)[dataSize * (levelBase + (1 << lvl) - x)];
}
/* *************************************************** */
@@ -65,9 +63,8 @@ static CCGVert *_edge_getOtherVert(CCGEdge *e, CCGVert *vQ)
if (vQ == e->v0) {
return e->v1;
}
- else {
- return e->v0;
- }
+
+ return e->v0;
}
static float *_face_getIFNoEdge(CCGFace *f,
@@ -111,15 +108,13 @@ static float EDGE_getSharpness(CCGEdge *e, int lvl)
if (!lvl) {
return e->crease;
}
- else if (!e->crease) {
+ if (!e->crease) {
return 0.0f;
}
- else if (e->crease - lvl < 0.0f) {
+ if (e->crease - lvl < 0.0f) {
return 0.0f;
}
- else {
- return e->crease - lvl;
- }
+ return e->crease - lvl;
}
typedef struct CCGSubSurfCalcSubdivData {
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_util.c b/source/blender/blenkernel/intern/CCGSubSurf_util.c
index 58d5f2e0495..bc63d8b97f7 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_util.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_util.c
@@ -304,7 +304,7 @@ void ccgSubSurf__dumpCoords(CCGSubSurf *ss)
}
for (x = 0; x < gridSize; x++) {
float *co = FACE_getIECo(f, subdivLevels, S, x);
- printf("face index=%d. cornder=%d, ie_index=%d, coord=(%f, %f, %f)\n",
+ printf("face index=%d. corner=%d, ie_index=%d, coord=(%f, %f, %f)\n",
index,
S,
x,
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 8a5be6b9cb3..af4829691c2 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -80,11 +80,9 @@
//#define USE_MODIFIER_VALIDATE
#ifdef USE_MODIFIER_VALIDATE
-# define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true)))
# define ASSERT_IS_VALID_MESH(mesh) \
(BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true)))
#else
-# define ASSERT_IS_VALID_DM(dm)
# define ASSERT_IS_VALID_MESH(mesh)
#endif
@@ -424,15 +422,14 @@ int DM_release(DerivedMesh *dm)
return 1;
}
- else {
- CustomData_free_temporary(&dm->vertData, dm->numVertData);
- CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
- CustomData_free_temporary(&dm->faceData, dm->numTessFaceData);
- CustomData_free_temporary(&dm->loopData, dm->numLoopData);
- CustomData_free_temporary(&dm->polyData, dm->numPolyData);
- return 0;
- }
+ CustomData_free_temporary(&dm->vertData, dm->numVertData);
+ CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
+ CustomData_free_temporary(&dm->faceData, dm->numTessFaceData);
+ CustomData_free_temporary(&dm->loopData, dm->numLoopData);
+ CustomData_free_temporary(&dm->polyData, dm->numPolyData);
+
+ return 0;
}
void DM_DupPolys(DerivedMesh *source, DerivedMesh *target)
@@ -693,11 +690,9 @@ static float (*get_orco_coords(Object *ob, BMEditMesh *em, int layer, int *free)
if (em) {
return get_editbmesh_orco_verts(em);
}
- else {
- return BKE_mesh_orco_verts_get(ob);
- }
+ return BKE_mesh_orco_verts_get(ob);
}
- else if (layer == CD_CLOTH_ORCO) {
+ if (layer == CD_CLOTH_ORCO) {
/* apply shape key for cloth, this should really be solved
* by a more flexible customdata system, but not simple */
if (!em) {
@@ -1060,9 +1055,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
}
continue;
}
- else {
- BKE_modifier_set_error(md, "Sculpt: Hide, Mask and optimized display disabled");
- }
+ BKE_modifier_set_error(md, "Sculpt: Hide, Mask and optimized display disabled");
}
if (need_mapping && !BKE_modifier_supports_mapping(md)) {
@@ -2363,32 +2356,6 @@ void DM_debug_print(DerivedMesh *dm)
MEM_freeN(str);
}
-void DM_debug_print_cdlayers(CustomData *data)
-{
- int i;
- const CustomDataLayer *layer;
-
- printf("{\n");
-
- for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) {
-
- const char *name = CustomData_layertype_name(layer->type);
- const int size = CustomData_sizeof(layer->type);
- const char *structname;
- int structnum;
- CustomData_file_write_info(layer->type, &structname, &structnum);
- printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
- name,
- structname,
- layer->type,
- (const void *)layer->data,
- size,
- (int)(MEM_allocN_len(layer->data) / size));
- }
-
- printf("}\n");
-}
-
bool DM_is_valid(DerivedMesh *dm)
{
const bool do_verbose = true;
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index b35d2183408..85ac2c693cb 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -37,6 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
+#include "BLI_session_uuid.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
@@ -482,6 +483,11 @@ void action_groups_clear_tempflags(bAction *act)
/* *************** Pose channels *************** */
+void BKE_pose_channel_session_uuid_generate(bPoseChannel *pchan)
+{
+ pchan->runtime.session_uuid = BLI_session_uuid_generate();
+}
+
/**
* Return a pointer to the pose channel of the given name
* from this pose.
@@ -524,6 +530,8 @@ bPoseChannel *BKE_pose_channel_verify(bPose *pose, const char *name)
/* If not, create it and add it */
chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
+ BKE_pose_channel_session_uuid_generate(chan);
+
BLI_strncpy(chan->name, name, sizeof(chan->name));
chan->custom_scale = 1.0f;
@@ -698,6 +706,10 @@ void BKE_pose_copy_data_ex(bPose **dst,
id_us_plus((ID *)pchan->custom);
}
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ BKE_pose_channel_session_uuid_generate(pchan);
+ }
+
/* warning, O(n2) here, if done without the hash, but these are rarely used features. */
if (pchan->custom_tx) {
pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name);
@@ -726,7 +738,7 @@ void BKE_pose_copy_data_ex(bPose **dst,
pchan->draw_data = NULL; /* Drawing cache, no need to copy. */
/* Runtime data, no need to copy. */
- memset(&pchan->runtime, 0, sizeof(pchan->runtime));
+ BKE_pose_channel_runtime_reset_on_copy(&pchan->runtime);
}
/* for now, duplicate Bone Groups too when doing this */
@@ -956,6 +968,14 @@ void BKE_pose_channel_runtime_reset(bPoseChannel_Runtime *runtime)
memset(runtime, 0, sizeof(*runtime));
}
+/* Reset all non-persistent fields. */
+void BKE_pose_channel_runtime_reset_on_copy(bPoseChannel_Runtime *runtime)
+{
+ const SessionUUID uuid = runtime->session_uuid;
+ memset(runtime, 0, sizeof(*runtime));
+ runtime->session_uuid = uuid;
+}
+
/** Deallocates runtime cache of a pose channel */
void BKE_pose_channel_runtime_free(bPoseChannel_Runtime *runtime)
{
@@ -1512,8 +1532,10 @@ short action_get_item_transforms(bAction *act, Object *ob, bPoseChannel *pchan,
/* ************** Pose Management Tools ****************** */
-/* for do_all_pose_actions, clears the pose. Now also exported for proxy and tools */
-void BKE_pose_rest(bPose *pose)
+/**
+ * Zero the pose transforms for the entire pose or only for selected bones.
+ */
+void BKE_pose_rest(bPose *pose, bool selected_bones_only)
{
bPoseChannel *pchan;
@@ -1525,6 +1547,9 @@ void BKE_pose_rest(bPose *pose)
memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset));
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ if (selected_bones_only && pchan->bone != NULL && (pchan->bone->flag & BONE_SELECTED) == 0) {
+ continue;
+ }
zero_v3(pchan->loc);
zero_v3(pchan->eul);
unit_qt(pchan->quat);
@@ -1612,8 +1637,12 @@ void BKE_pose_tag_recalc(Main *bmain, bPose *pose)
/* For the calculation of the effects of an Action at the given frame on an object
* This is currently only used for the Action Constraint
*/
-void what_does_obaction(
- Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe)
+void what_does_obaction(Object *ob,
+ Object *workob,
+ bPose *pose,
+ bAction *act,
+ char groupname[],
+ const AnimationEvalContext *anim_eval_context)
{
bActionGroup *agrp = BKE_action_group_find_name(act, groupname);
@@ -1669,7 +1698,7 @@ void what_does_obaction(
RNA_id_pointer_create(&workob->id, &id_ptr);
/* execute action for this group only */
- animsys_evaluate_action_group(&id_ptr, act, agrp, cframe);
+ animsys_evaluate_action_group(&id_ptr, act, agrp, anim_eval_context);
}
else {
AnimData adt = {NULL};
@@ -1680,6 +1709,33 @@ void what_does_obaction(
adt.action = act;
/* execute effects of Action on to workob (or it's PoseChannels) */
- BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM, false);
+ BKE_animsys_evaluate_animdata(&workob->id, &adt, anim_eval_context, ADT_RECALC_ANIM, false);
+ }
+}
+
+void BKE_pose_check_uuids_unique_and_report(const bPose *pose)
+{
+ if (pose == NULL) {
+ return;
}
+
+ struct GSet *used_uuids = BLI_gset_new(
+ BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids");
+
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
+ const SessionUUID *session_uuid = &pchan->runtime.session_uuid;
+ if (!BLI_session_uuid_is_generated(session_uuid)) {
+ printf("Pose channel %s does not have UUID generated.\n", pchan->name);
+ continue;
+ }
+
+ if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
+ printf("Pose channel %s has duplicate UUID generated.\n", pchan->name);
+ continue;
+ }
+
+ BLI_gset_insert(used_uuids, (void *)session_uuid);
+ }
+
+ BLI_gset_free(used_uuids, NULL);
}
diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c
index 841fdaa3b2c..038a0d14ddb 100644
--- a/source/blender/blenkernel/intern/anim_data.c
+++ b/source/blender/blenkernel/intern/anim_data.c
@@ -130,9 +130,7 @@ AnimData *BKE_animdata_from_id(ID *id)
IdAdtTemplate *iat = (IdAdtTemplate *)id;
return iat->adt;
}
- else {
- return NULL;
- }
+ return NULL;
}
/* Add AnimData to the given ID-block. In order for this to work, we assume that
@@ -161,9 +159,7 @@ AnimData *BKE_animdata_add_id(ID *id)
return iat->adt;
}
- else {
- return NULL;
- }
+ return NULL;
}
/* Action Setter --------------------------------------- */
@@ -379,17 +375,19 @@ bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const int flag)
return true;
}
-void BKE_animdata_copy_id_action(Main *bmain, ID *id, const bool set_newid)
+static void animdata_copy_id_action(Main *bmain,
+ ID *id,
+ const bool set_newid,
+ const bool do_linked_id)
{
- const bool is_id_liboverride = ID_IS_OVERRIDE_LIBRARY(id);
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
- if (adt->action && (!is_id_liboverride || !ID_IS_LINKED(adt->action))) {
+ if (adt->action && (do_linked_id || !ID_IS_LINKED(adt->action))) {
id_us_min((ID *)adt->action);
adt->action = set_newid ? ID_NEW_SET(adt->action, BKE_action_copy(bmain, adt->action)) :
BKE_action_copy(bmain, adt->action);
}
- if (adt->tmpact && (!is_id_liboverride || !ID_IS_LINKED(adt->tmpact))) {
+ if (adt->tmpact && (do_linked_id || !ID_IS_LINKED(adt->tmpact))) {
id_us_min((ID *)adt->tmpact);
adt->tmpact = set_newid ? ID_NEW_SET(adt->tmpact, BKE_action_copy(bmain, adt->tmpact)) :
BKE_action_copy(bmain, adt->tmpact);
@@ -397,12 +395,27 @@ void BKE_animdata_copy_id_action(Main *bmain, ID *id, const bool set_newid)
}
bNodeTree *ntree = ntreeFromID(id);
if (ntree) {
- BKE_animdata_copy_id_action(bmain, &ntree->id, set_newid);
+ animdata_copy_id_action(bmain, &ntree->id, set_newid, do_linked_id);
}
/* Note that collections are not animatable currently, so no need to handle scenes' master
* collection here. */
}
+void BKE_animdata_copy_id_action(Main *bmain, ID *id)
+{
+ const bool is_id_liboverride = ID_IS_OVERRIDE_LIBRARY(id);
+ animdata_copy_id_action(bmain, id, false, !is_id_liboverride);
+}
+
+void BKE_animdata_duplicate_id_action(struct Main *bmain,
+ struct ID *id,
+ const eDupli_ID_Flags duplicate_flags)
+{
+ if (duplicate_flags & USER_DUP_ACT) {
+ animdata_copy_id_action(bmain, id, true, (duplicate_flags & USER_DUP_LINKED_ID) != 0);
+ }
+}
+
/* Merge copies of the data from the src AnimData into the destination AnimData */
void BKE_animdata_merge_copy(
Main *bmain, ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
@@ -492,24 +505,43 @@ static bool animpath_matches_basepath(const char path[], const char basepath[])
return (path && basepath) && STRPREFIX(path, basepath);
}
+static void animpath_update_basepath(FCurve *fcu,
+ const char *old_basepath,
+ const char *new_basepath)
+{
+ BLI_assert(animpath_matches_basepath(fcu->rna_path, old_basepath));
+ if (STREQ(old_basepath, new_basepath)) {
+ return;
+ }
+
+ char *new_path = BLI_sprintfN("%s%s", new_basepath, fcu->rna_path + strlen(old_basepath));
+ MEM_freeN(fcu->rna_path);
+ fcu->rna_path = new_path;
+}
+
/* Move F-Curves in src action to dst action, setting up all the necessary groups
* for this to happen, but only if the F-Curves being moved have the appropriate
* "base path".
* - This is used when data moves from one data-block to another, causing the
* F-Curves to need to be moved over too
*/
-void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const char basepath[])
+static void action_move_fcurves_by_basepath(bAction *srcAct,
+ bAction *dstAct,
+ const char *src_basepath,
+ const char *dst_basepath)
{
FCurve *fcu, *fcn = NULL;
/* sanity checks */
- if (ELEM(NULL, srcAct, dstAct, basepath)) {
+ if (ELEM(NULL, srcAct, dstAct, src_basepath, dst_basepath)) {
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
- "srcAct: %p, dstAct: %p, basepath: %p has insufficient info to work with",
+ "srcAct: %p, dstAct: %p, src_basepath: %p, dst_basepath: %p has insufficient "
+ "info to work with",
(void *)srcAct,
(void *)dstAct,
- (void *)basepath);
+ (void *)src_basepath,
+ (void *)dst_basepath);
}
return;
}
@@ -527,7 +559,7 @@ void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const cha
/* should F-Curve be moved over?
* - we only need the start of the path to match basepath
*/
- if (animpath_matches_basepath(fcu->rna_path, basepath)) {
+ if (animpath_matches_basepath(fcu->rna_path, src_basepath)) {
bActionGroup *agrp = NULL;
/* if grouped... */
@@ -549,6 +581,8 @@ void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const cha
/* perform the migration now */
action_groups_remove_channel(srcAct, fcu);
+ animpath_update_basepath(fcu, src_basepath, dst_basepath);
+
if (agrp) {
action_groups_add_channel(dstAct, agrp, fcu);
}
@@ -581,14 +615,31 @@ void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const cha
}
}
+static void animdata_move_drivers_by_basepath(AnimData *srcAdt,
+ AnimData *dstAdt,
+ const char *src_basepath,
+ const char *dst_basepath)
+{
+ LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &srcAdt->drivers) {
+ if (animpath_matches_basepath(fcu->rna_path, src_basepath)) {
+ animpath_update_basepath(fcu, src_basepath, dst_basepath);
+ BLI_remlink(&srcAdt->drivers, fcu);
+ BLI_addtail(&dstAdt->drivers, fcu);
+
+ /* TODO: add depsgraph flushing calls? */
+ }
+ }
+}
+
/* Transfer the animation data from srcID to dstID where the srcID
* animation data is based off "basepath", creating new AnimData and
- * associated data as necessary
+ * associated data as necessary.
+ *
+ * basepaths is a list of AnimationBasePathChange.
*/
-void BKE_animdata_separate_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBase *basepaths)
+void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBase *basepaths)
{
AnimData *srcAdt = NULL, *dstAdt = NULL;
- LinkData *ld;
/* sanity checks */
if (ELEM(NULL, srcID, dstID)) {
@@ -630,35 +681,19 @@ void BKE_animdata_separate_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBa
}
/* loop over base paths, trying to fix for each one... */
- for (ld = basepaths->first; ld; ld = ld->next) {
- const char *basepath = (const char *)ld->data;
- action_move_fcurves_by_basepath(srcAdt->action, dstAdt->action, basepath);
+ LISTBASE_FOREACH (const AnimationBasePathChange *, basepath_change, basepaths) {
+ action_move_fcurves_by_basepath(srcAdt->action,
+ dstAdt->action,
+ basepath_change->src_basepath,
+ basepath_change->dst_basepath);
}
}
/* drivers */
if (srcAdt->drivers.first) {
- FCurve *fcu, *fcn = NULL;
-
- /* check each driver against all the base paths to see if any should go */
- for (fcu = srcAdt->drivers.first; fcu; fcu = fcn) {
- fcn = fcu->next;
-
- /* try each basepath in turn, but stop on the first one which works */
- for (ld = basepaths->first; ld; ld = ld->next) {
- const char *basepath = (const char *)ld->data;
-
- if (animpath_matches_basepath(fcu->rna_path, basepath)) {
- /* just need to change lists */
- BLI_remlink(&srcAdt->drivers, fcu);
- BLI_addtail(&dstAdt->drivers, fcu);
-
- /* TODO: add depsgraph flushing calls? */
-
- /* can stop now, as moved already */
- break;
- }
- }
+ LISTBASE_FOREACH (const AnimationBasePathChange *, basepath_change, basepaths) {
+ animdata_move_drivers_by_basepath(
+ srcAdt, dstAdt, basepath_change->src_basepath, basepath_change->dst_basepath);
}
}
}
@@ -775,10 +810,9 @@ static char *rna_path_rename_fix(ID *owner_id,
MEM_freeN(oldpath);
return newPath;
}
- else {
- /* still couldn't resolve the path... so, might as well just leave it alone */
- MEM_freeN(newPath);
- }
+
+ /* still couldn't resolve the path... so, might as well just leave it alone */
+ MEM_freeN(newPath);
}
}
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 5e4b280d0d0..5b5e32f1d81 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -538,7 +538,7 @@ static void animsys_write_orig_anim_rna(PointerRNA *ptr,
*/
static void animsys_evaluate_fcurves(PointerRNA *ptr,
ListBase *list,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
bool flush_to_original)
{
/* Calculate then execute each curve. */
@@ -557,7 +557,7 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
}
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
BKE_animsys_write_rna_setting(&anim_rna, curval);
if (flush_to_original) {
animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval);
@@ -569,8 +569,26 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
/* ***************************************** */
/* Driver Evaluation */
+AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph,
+ float eval_time)
+{
+ AnimationEvalContext ctx = {
+ .depsgraph = depsgraph,
+ .eval_time = eval_time,
+ };
+ return ctx;
+}
+
+AnimationEvalContext BKE_animsys_eval_context_construct_at(
+ const AnimationEvalContext *anim_eval_context, float eval_time)
+{
+ return BKE_animsys_eval_context_construct(anim_eval_context->depsgraph, eval_time);
+}
+
/* Evaluate Drivers */
-static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime)
+static void animsys_evaluate_drivers(PointerRNA *ptr,
+ AnimData *adt,
+ const AnimationEvalContext *anim_eval_context)
{
FCurve *fcu;
@@ -591,7 +609,7 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
* before adding new to only be done when drivers only changed. */
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
}
@@ -619,9 +637,8 @@ static void action_idcode_patch_check(ID *id, bAction *act)
if (ELEM(NULL, id, act)) {
return;
}
- else {
- idcode = GS(id->name);
- }
+
+ idcode = GS(id->name);
/* the actual checks... hopefully not too much of a performance hit in the long run... */
if (act->idroot == 0) {
@@ -648,7 +665,10 @@ static void action_idcode_patch_check(ID *id, bAction *act)
/* ----------------------------------------- */
/* Evaluate Action Group */
-void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *agrp, float ctime)
+void animsys_evaluate_action_group(PointerRNA *ptr,
+ bAction *act,
+ bActionGroup *agrp,
+ const AnimationEvalContext *anim_eval_context)
{
FCurve *fcu;
@@ -670,7 +690,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0 && !BKE_fcurve_is_empty(fcu)) {
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
BKE_animsys_write_rna_setting(&anim_rna, curval);
}
}
@@ -680,7 +700,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
/* Evaluate Action (F-Curve Bag) */
static void animsys_evaluate_action_ex(PointerRNA *ptr,
bAction *act,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
/* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
@@ -691,15 +711,15 @@ static void animsys_evaluate_action_ex(PointerRNA *ptr,
action_idcode_patch_check(ptr->owner_id, act);
/* calculate then execute each curve */
- animsys_evaluate_fcurves(ptr, &act->curves, ctime, flush_to_original);
+ animsys_evaluate_fcurves(ptr, &act->curves, anim_eval_context, flush_to_original);
}
void animsys_evaluate_action(PointerRNA *ptr,
bAction *act,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
- animsys_evaluate_action_ex(ptr, act, ctime, flush_to_original);
+ animsys_evaluate_action_ex(ptr, act, anim_eval_context, flush_to_original);
}
/* ***************************************** */
@@ -717,18 +737,19 @@ static float nlastrip_get_influence(NlaStrip *strip, float cframe)
/* there is some blend-in */
return fabsf(cframe - strip->start) / (strip->blendin);
}
- else if (IS_EQF(strip->blendout, 0.0f) == false && (cframe >= (strip->end - strip->blendout))) {
+ if (IS_EQF(strip->blendout, 0.0f) == false && (cframe >= (strip->end - strip->blendout))) {
/* there is some blend-out */
return fabsf(strip->end - cframe) / (strip->blendout);
}
- else {
- /* in the middle of the strip, we should be full strength */
- return 1.0f;
- }
+
+ /* in the middle of the strip, we should be full strength */
+ return 1.0f;
}
/* evaluate the evaluation time and influence for the strip, storing the results in the strip */
-static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool flush_to_original)
+static void nlastrip_evaluate_controls(NlaStrip *strip,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
/* now strip's evaluate F-Curves for these settings (if applicable) */
if (strip->fcurves.first) {
@@ -738,7 +759,7 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
/* execute these settings as per normal */
- animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, ctime, flush_to_original);
+ animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, anim_eval_context, flush_to_original);
}
/* analytically generate values for influence and time (if applicable)
@@ -746,17 +767,18 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool
* in case the override has been turned off.
*/
if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0) {
- strip->influence = nlastrip_get_influence(strip, ctime);
+ strip->influence = nlastrip_get_influence(strip, anim_eval_context->eval_time);
}
/* Bypass evaluation time computation if time mapping is disabled. */
if ((strip->flag & NLASTRIP_FLAG_NO_TIME_MAP) != 0) {
- strip->strip_time = ctime;
+ strip->strip_time = anim_eval_context->eval_time;
return;
}
if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0) {
- strip->strip_time = nlastrip_get_frame(strip, ctime, NLATIME_CONVERT_EVAL);
+ strip->strip_time = nlastrip_get_frame(
+ strip, anim_eval_context->eval_time, NLATIME_CONVERT_EVAL);
}
/* if user can control the evaluation time (using F-Curves), consider the option which allows
@@ -770,12 +792,16 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool
}
/* gets the strip active at the current time for a list of strips for evaluation purposes */
-NlaEvalStrip *nlastrips_ctime_get_strip(
- ListBase *list, ListBase *strips, short index, float ctime, const bool flush_to_original)
+NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
+ ListBase *strips,
+ short index,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
NlaStrip *strip, *estrip = NULL;
NlaEvalStrip *nes;
short side = 0;
+ float ctime = anim_eval_context->eval_time;
/* loop over strips, checking if they fall within the range */
for (strip = strips->first; strip; strip = strip->next) {
@@ -854,7 +880,9 @@ NlaEvalStrip *nlastrips_ctime_get_strip(
*/
/* TODO: this sounds a bit hacky having a few isolated F-Curves
* stuck on some data it operates on... */
- nlastrip_evaluate_controls(estrip, ctime, flush_to_original);
+ AnimationEvalContext clamped_eval_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, ctime);
+ nlastrip_evaluate_controls(estrip, &clamped_eval_context, flush_to_original);
if (estrip->influence <= 0.0f) {
return NULL;
}
@@ -876,8 +904,12 @@ NlaEvalStrip *nlastrips_ctime_get_strip(
}
/* evaluate controls for the relevant extents of the bordering strips... */
- nlastrip_evaluate_controls(estrip->prev, estrip->start, flush_to_original);
- nlastrip_evaluate_controls(estrip->next, estrip->end, flush_to_original);
+ AnimationEvalContext start_eval_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, estrip->start);
+ AnimationEvalContext end_eval_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, estrip->end);
+ nlastrip_evaluate_controls(estrip->prev, &start_eval_context, flush_to_original);
+ nlastrip_evaluate_controls(estrip->next, &end_eval_context, flush_to_original);
break;
}
@@ -1115,12 +1147,10 @@ static int nlaevalchan_validate_index(NlaEvalChannel *nec, int index)
return -1;
}
- else {
- return 0;
- }
+ return 0;
}
-/* Initialise default values for NlaEvalChannel from the property data. */
+/* Initialize default values for NlaEvalChannel from the property data. */
static void nlaevalchan_get_default_values(NlaEvalChannel *nec, float *r_values)
{
PointerRNA *ptr = &nec->key.ptr;
@@ -1209,15 +1239,13 @@ static char nlaevalchan_detect_mix_mode(NlaEvalChannelKey *key, int length)
if (subtype == PROP_QUATERNION && length == 4) {
return NEC_MIX_QUATERNION;
}
- else if (subtype == PROP_AXISANGLE && length == 4) {
+ if (subtype == PROP_AXISANGLE && length == 4) {
return NEC_MIX_AXIS_ANGLE;
}
- else if (RNA_property_flag(key->prop) & PROP_PROPORTIONAL) {
+ if (RNA_property_flag(key->prop) & PROP_PROPORTIONAL) {
return NEC_MIX_MULTIPLY;
}
- else {
- return NEC_MIX_ADD;
- }
+ return NEC_MIX_ADD;
}
/* Verify that an appropriate NlaEvalChannel for this property exists. */
@@ -1454,10 +1482,9 @@ static bool nla_invert_combine_value(int mix_mode,
/* Division by zero. */
return false;
}
- else {
- *r_value = base_value * powf(target_value / old_value, 1.0f / influence);
- return true;
- }
+
+ *r_value = base_value * powf(target_value / old_value, 1.0f / influence);
+ return true;
case NEC_MIX_QUATERNION:
default:
@@ -1802,6 +1829,7 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
ListBase tmp_modifiers = {NULL, NULL};
@@ -1843,13 +1871,15 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr,
tmp_nes.strip_mode = NES_TIME_TRANSITION_START;
tmp_nes.strip = s1;
nlaeval_snapshot_init(&snapshot1, channels, snapshot);
- nlastrip_evaluate(ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, flush_to_original);
+ nlastrip_evaluate(
+ ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, anim_eval_context, flush_to_original);
/* second strip */
tmp_nes.strip_mode = NES_TIME_TRANSITION_END;
tmp_nes.strip = s2;
nlaeval_snapshot_init(&snapshot2, channels, snapshot);
- nlastrip_evaluate(ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, flush_to_original);
+ nlastrip_evaluate(
+ ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, anim_eval_context, flush_to_original);
/* accumulate temp-buffer and full-buffer, using the 'real' strip */
nlaeval_snapshot_mix_and_free(channels, snapshot, &snapshot1, &snapshot2, nes->strip_time);
@@ -1864,6 +1894,7 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
ListBase tmp_modifiers = {NULL, NULL};
@@ -1884,13 +1915,16 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr,
/* find the child-strip to evaluate */
evaltime = (nes->strip_time * (strip->end - strip->start)) + strip->start;
- tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, evaltime, flush_to_original);
+ AnimationEvalContext child_context = BKE_animsys_eval_context_construct_at(anim_eval_context,
+ evaltime);
+ tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, &child_context, flush_to_original);
/* directly evaluate child strip into accumulation buffer...
* - there's no need to use a temporary buffer (as it causes issues [T40082])
*/
if (tmp_nes) {
- nlastrip_evaluate(ptr, channels, &tmp_modifiers, tmp_nes, snapshot, flush_to_original);
+ nlastrip_evaluate(
+ ptr, channels, &tmp_modifiers, tmp_nes, snapshot, &child_context, flush_to_original);
/* free temp eval-strip */
MEM_freeN(tmp_nes);
@@ -1906,6 +1940,7 @@ void nlastrip_evaluate(PointerRNA *ptr,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
NlaStrip *strip = nes->strip;
@@ -1928,10 +1963,12 @@ void nlastrip_evaluate(PointerRNA *ptr,
nlastrip_evaluate_actionclip(ptr, channels, modifiers, nes, snapshot);
break;
case NLASTRIP_TYPE_TRANSITION: /* transition */
- nlastrip_evaluate_transition(ptr, channels, modifiers, nes, snapshot, flush_to_original);
+ nlastrip_evaluate_transition(
+ ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original);
break;
case NLASTRIP_TYPE_META: /* meta */
- nlastrip_evaluate_meta(ptr, channels, modifiers, nes, snapshot, flush_to_original);
+ nlastrip_evaluate_meta(
+ ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original);
break;
default: /* do nothing */
@@ -2079,7 +2116,7 @@ static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels,
static bool animsys_evaluate_nla(NlaEvalData *echannels,
PointerRNA *ptr,
AnimData *adt,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original,
NlaKeyframingContext *r_context)
{
@@ -2127,7 +2164,8 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
}
/* otherwise, get strip to evaluate for this channel */
- nes = nlastrips_ctime_get_strip(&estrips, &nlt->strips, track_index, ctime, flush_to_original);
+ nes = nlastrips_ctime_get_strip(
+ &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original);
if (nes) {
nes->track = nlt;
}
@@ -2193,7 +2231,8 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
/* add this to our list of evaluation strips */
if (r_context == NULL) {
- nlastrips_ctime_get_strip(&estrips, &dummy_trackslist, -1, ctime, flush_to_original);
+ nlastrips_ctime_get_strip(
+ &estrips, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
}
/* If computing the context for keyframing, store data there instead of the list. */
else {
@@ -2203,7 +2242,7 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
NLASTRIP_EXTEND_HOLD;
r_context->eval_strip = nes = nlastrips_ctime_get_strip(
- NULL, &dummy_trackslist, -1, ctime, flush_to_original);
+ NULL, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
/* These setting combinations require no data from strips below, so exit immediately. */
if ((nes == NULL) ||
@@ -2228,7 +2267,13 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
/* 2. for each strip, evaluate then accumulate on top of existing channels,
* but don't set values yet. */
for (nes = estrips.first; nes; nes = nes->next) {
- nlastrip_evaluate(ptr, echannels, NULL, nes, &echannels->eval_snapshot, flush_to_original);
+ nlastrip_evaluate(ptr,
+ echannels,
+ NULL,
+ nes,
+ &echannels->eval_snapshot,
+ anim_eval_context,
+ flush_to_original);
}
/* 3. free temporary evaluation data that's not used elsewhere */
@@ -2242,7 +2287,7 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
*/
static void animsys_calculate_nla(PointerRNA *ptr,
AnimData *adt,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
NlaEvalData echannels;
@@ -2250,7 +2295,7 @@ static void animsys_calculate_nla(PointerRNA *ptr,
nlaeval_init(&echannels);
/* evaluate the NLA stack, obtaining a set of values to flush */
- if (animsys_evaluate_nla(&echannels, ptr, adt, ctime, flush_to_original, NULL)) {
+ if (animsys_evaluate_nla(&echannels, ptr, adt, anim_eval_context, flush_to_original, NULL)) {
/* reset any channels touched by currently inactive actions to default value */
animsys_evaluate_nla_domain(ptr, &echannels, adt);
@@ -2264,7 +2309,7 @@ static void animsys_calculate_nla(PointerRNA *ptr,
CLOG_WARN(&LOG, "NLA Eval: Stopgap for active action on NLA Stack - no strips case");
}
- animsys_evaluate_action(ptr, adt->action, ctime, flush_to_original);
+ animsys_evaluate_action(ptr, adt->action, anim_eval_context, flush_to_original);
}
/* free temp data */
@@ -2282,11 +2327,12 @@ static void animsys_calculate_nla(PointerRNA *ptr,
* \param ptr: RNA pointer to the Object with the animation.
* \return Keyframing context, or NULL if not necessary.
*/
-NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache,
- struct PointerRNA *ptr,
- struct AnimData *adt,
- float ctime,
- const bool flush_to_original)
+NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
+ struct ListBase *cache,
+ struct PointerRNA *ptr,
+ struct AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
/* No remapping needed if NLA is off or no action. */
if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) ||
@@ -2309,7 +2355,7 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *ca
ctx->adt = adt;
nlaeval_init(&ctx->nla_channels);
- animsys_evaluate_nla(&ctx->nla_channels, ptr, adt, ctime, flush_to_original, ctx);
+ animsys_evaluate_nla(&ctx->nla_channels, ptr, adt, anim_eval_context, flush_to_original, ctx);
BLI_assert(ELEM(ctx->strip.act, NULL, adt->action));
BLI_addtail(cache, ctx);
@@ -2499,8 +2545,11 @@ static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
* and that the flags for which parts of the anim-data settings need to be recalculated
* have been set already by the depsgraph. Now, we use the recalc
*/
-void BKE_animsys_evaluate_animdata(
- ID *id, AnimData *adt, float ctime, eAnimData_Recalc recalc, const bool flush_to_original)
+void BKE_animsys_evaluate_animdata(ID *id,
+ AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ eAnimData_Recalc recalc,
+ const bool flush_to_original)
{
PointerRNA id_ptr;
@@ -2523,11 +2572,11 @@ void BKE_animsys_evaluate_animdata(
/* evaluate NLA-stack
* - active action is evaluated as part of the NLA stack as the last item
*/
- animsys_calculate_nla(&id_ptr, adt, ctime, flush_to_original);
+ animsys_calculate_nla(&id_ptr, adt, anim_eval_context, flush_to_original);
}
/* evaluate Active Action only */
else if (adt->action) {
- animsys_evaluate_action_ex(&id_ptr, adt->action, ctime, flush_to_original);
+ animsys_evaluate_action_ex(&id_ptr, adt->action, anim_eval_context, flush_to_original);
}
}
@@ -2537,7 +2586,7 @@ void BKE_animsys_evaluate_animdata(
* - Drivers should be in the appropriate order to be evaluated without problems...
*/
if (recalc & ADT_RECALC_DRIVERS) {
- animsys_evaluate_drivers(&id_ptr, adt, ctime);
+ animsys_evaluate_drivers(&id_ptr, adt, anim_eval_context);
}
/* always execute 'overrides'
@@ -2565,6 +2614,8 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
}
const bool flush_to_original = DEG_is_active(depsgraph);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
/* macros for less typing
* - only evaluate animation data for id if it has users (and not just fake ones)
@@ -2575,7 +2626,7 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
for (id = first; id; id = id->next) { \
if (ID_REAL_USERS(id) > 0) { \
AnimData *adt = BKE_animdata_from_id(id); \
- BKE_animsys_evaluate_animdata(id, adt, ctime, aflag, flush_to_original); \
+ BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
} \
} \
(void)0
@@ -2594,9 +2645,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
if (ntp->nodetree) { \
AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
BKE_animsys_evaluate_animdata( \
- &ntp->nodetree->id, adt2, ctime, ADT_RECALC_ANIM, flush_to_original); \
+ &ntp->nodetree->id, adt2, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); \
} \
- BKE_animsys_evaluate_animdata(id, adt, ctime, aflag, flush_to_original); \
+ BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
} \
} \
(void)0
@@ -2713,7 +2764,10 @@ void BKE_animsys_eval_animdata(Depsgraph *depsgraph, ID *id)
* which should get handled as part of the dependency graph instead. */
DEG_debug_print_eval_time(depsgraph, __func__, id->name, id, ctime);
const bool flush_to_original = DEG_is_active(depsgraph);
- BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM, flush_to_original);
+
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
+ BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
}
void BKE_animsys_update_driver_array(ID *id)
@@ -2775,7 +2829,9 @@ void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCu
if (BKE_animsys_store_rna_setting(&id_ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
/* Evaluate driver, and write results to COW-domain destination */
const float ctime = DEG_get_ctime(depsgraph);
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, &anim_eval_context);
ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
/* Flush results & status codes to original data for UI (T59984) */
diff --git a/source/blender/blenkernel/intern/anim_visualization.c b/source/blender/blenkernel/intern/anim_visualization.c
index 04dbe4102cc..a6f63c2ba95 100644
--- a/source/blender/blenkernel/intern/anim_visualization.c
+++ b/source/blender/blenkernel/intern/anim_visualization.c
@@ -184,10 +184,8 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports,
/* return/use this as it is already valid length */
return mpath;
}
- else {
- /* clear the existing path (as the range has changed), and reallocate below */
- animviz_free_motionpath_cache(mpath);
- }
+ /* clear the existing path (as the range has changed), and reallocate below */
+ animviz_free_motionpath_cache(mpath);
}
}
else {
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 8189385a69d..2cc715464ad 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -56,7 +56,7 @@
# ifdef WITH_BINRELOC
# include "binreloc.h"
# endif
-/* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
+/* #mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
# include <unistd.h>
#endif /* WIN32 */
@@ -120,7 +120,7 @@ static char *blender_version_decimal(const int ver)
}
/**
- * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath,
+ * Concatenates path_base, (optional) path_sep and (optional) folder_name into \a targetpath,
* returning true if result points to a directory.
*/
static bool test_path(char *targetpath,
@@ -138,14 +138,14 @@ static bool test_path(char *targetpath,
BLI_strncpy(tmppath, path_base, sizeof(tmppath));
}
- /* rare cases folder_name is omitted (when looking for ~/.config/blender/2.xx dir only) */
+ /* Rare cases folder_name is omitted (when looking for `~/.config/blender/2.xx` dir only). */
if (folder_name) {
BLI_join_dirfile(targetpath, targetpath_len, tmppath, folder_name);
}
else {
BLI_strncpy(targetpath, tmppath, targetpath_len);
}
- /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
+ /* FIXME: why is "//" on front of \a tmppath expanded to "/" (by BLI_join_dirfile)
* if folder_name is specified but not otherwise? */
if (BLI_is_dir(targetpath)) {
@@ -154,13 +154,12 @@ static bool test_path(char *targetpath,
#endif
return true;
}
- else {
+
#ifdef PATH_DEBUG
- printf("\t%s missing: %s\n", __func__, targetpath);
+ printf("\t%s missing: %s\n", __func__, targetpath);
#endif
- // targetpath[0] = '\0';
- return false;
- }
+ // targetpath[0] = '\0';
+ return false;
}
/**
@@ -181,18 +180,17 @@ static bool test_env_path(char *path, const char *envvar)
#endif
return true;
}
- else {
- path[0] = '\0';
+
+ path[0] = '\0';
#ifdef PATH_DEBUG
- printf("\t%s env %s missing: %s\n", __func__, envvar, env);
+ printf("\t%s env %s missing: %s\n", __func__, envvar, env);
#endif
- return false;
- }
+ return false;
}
/**
* Constructs in \a targetpath the name of a directory relative to a version-specific
- * subdirectory in the parent directory of the Blender executable.
+ * sub-directory in the parent directory of the Blender executable.
*
* \param targetpath: String to return path
* \param folder_name: Optional folder name within version-specific directory
@@ -272,10 +270,8 @@ static bool get_path_environment(char *targetpath,
if (subfolder_name) {
return test_path(targetpath, targetpath_len, user_path, NULL, subfolder_name);
}
- else {
- BLI_strncpy(targetpath, user_path, FILE_MAX);
- return true;
- }
+ BLI_strncpy(targetpath, user_path, FILE_MAX);
+ return true;
}
return false;
}
@@ -300,10 +296,8 @@ static bool get_path_environment_notest(char *targetpath,
BLI_join_dirfile(targetpath, targetpath_len, user_path, subfolder_name);
return true;
}
- else {
- BLI_strncpy(targetpath, user_path, FILE_MAX);
- return true;
- }
+ BLI_strncpy(targetpath, user_path, FILE_MAX);
+ return true;
}
return false;
}
@@ -313,7 +307,7 @@ static bool get_path_environment_notest(char *targetpath,
* \param targetpath: String to return path
* \param folder_name: default name of folder within user area
* \param subfolder_name: optional name of subfolder within folder
- * \param ver: Blender version, used to construct a subdirectory name
+ * \param ver: Blender version, used to construct a sub-directory name
* \return true if it was able to construct such a path.
*/
static bool get_path_user(char *targetpath,
@@ -347,9 +341,8 @@ static bool get_path_user(char *targetpath,
if (subfolder_name) {
return test_path(targetpath, targetpath_len, user_path, folder_name, subfolder_name);
}
- else {
- return test_path(targetpath, targetpath_len, user_path, NULL, folder_name);
- }
+
+ return test_path(targetpath, targetpath_len, user_path, NULL, folder_name);
}
/**
@@ -357,8 +350,8 @@ static bool get_path_user(char *targetpath,
*
* \param targetpath: String to return path
* \param folder_name: default name of folder within installation area
- * \param subfolder_name: optional name of subfolder within folder
- * \param ver: Blender version, used to construct a subdirectory name
+ * \param subfolder_name: optional name of sub-folder within folder
+ * \param ver: Blender version, used to construct a sub-directory name
* \return true if it was able to construct such a path.
*/
static bool get_path_system(char *targetpath,
@@ -401,10 +394,9 @@ static bool get_path_system(char *targetpath,
/* try $BLENDERPATH/folder_name/subfolder_name */
return test_path(targetpath, targetpath_len, system_path, folder_name, subfolder_name);
}
- else {
- /* try $BLENDERPATH/folder_name */
- return test_path(targetpath, targetpath_len, system_path, NULL, folder_name);
- }
+
+ /* try $BLENDERPATH/folder_name */
+ return test_path(targetpath, targetpath_len, system_path, NULL, folder_name);
}
/**
@@ -643,7 +635,7 @@ const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, con
* adds the correct extension (.com .exe etc) from
* $PATHEXT if necessary. Also on Windows it translates
* the name to its 8.3 version to prevent problems with
- * spaces and stuff. Final result is returned in fullname.
+ * spaces and stuff. Final result is returned in \a fullname.
*
* \param fullname: The full path and full name of the executable
* (must be FILE_MAX minimum)
@@ -983,7 +975,7 @@ static void where_is_temp(char *fullname, char *basename, const size_t maxlen, c
/**
* Sets btempdir_base to userdir if specified and is a valid directory, otherwise
* chooses a suitable OS-specific temporary directory.
- * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base.
+ * Sets btempdir_session to a #mkdtemp generated sub-dir of btempdir_base.
*
* \note On Window userdir will be set to the temporary directory!
*/
@@ -1027,7 +1019,11 @@ void BKE_tempdir_session_purge(void)
}
/* Gets a good default directory for fonts */
-bool BKE_appdir_font_folder_default(char *dir)
+
+bool BKE_appdir_font_folder_default(
+ /* This parameter can only be `const` on non-windows platforms.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ char *dir)
{
bool success = false;
#ifdef WIN32
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 007062abb5b..631ce4edd20 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -512,12 +512,10 @@ bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag)
if (bone->flag & flag) {
return true;
}
- else if (bone->parent) {
+ if (bone->parent) {
return BKE_armature_bone_flag_test_recursive(bone->parent, flag);
}
- else {
- return false;
- }
+ return false;
}
/** \} */
@@ -687,10 +685,7 @@ int bone_autoside_name(
return 1;
}
-
- else {
- return 0;
- }
+ return 0;
}
/** \} */
@@ -1387,7 +1382,7 @@ void get_objectspace_bone_matrix(struct Bone *bone,
}
/* Convert World-Space Matrix to Pose-Space Matrix */
-void BKE_armature_mat_world_to_pose(Object *ob, float inmat[4][4], float outmat[4][4])
+void BKE_armature_mat_world_to_pose(Object *ob, const float inmat[4][4], float outmat[4][4])
{
float obmat[4][4];
@@ -1679,7 +1674,9 @@ void BKE_bone_parent_transform_apply(const struct BoneParentTransform *bpt,
/* Convert Pose-Space Matrix to Bone-Space Matrix.
* NOTE: this cannot be used to convert to pose-space transforms of the supplied
* pose-channel into its local space (i.e. 'visual'-keyframing) */
-void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
+void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan,
+ const float inmat[4][4],
+ float outmat[4][4])
{
BoneParentTransform bpt;
@@ -1689,7 +1686,9 @@ void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[4][4], float
}
/* Convert Bone-Space Matrix to Pose-Space Matrix. */
-void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
+void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan,
+ const float inmat[4][4],
+ float outmat[4][4])
{
BoneParentTransform bpt;
@@ -1725,7 +1724,7 @@ void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], fl
void BKE_armature_mat_pose_to_bone_ex(struct Depsgraph *depsgraph,
Object *ob,
bPoseChannel *pchan,
- float inmat[4][4],
+ const float inmat[4][4],
float outmat[4][4])
{
bPoseChannel work_pchan = *pchan;
@@ -1746,7 +1745,7 @@ void BKE_armature_mat_pose_to_bone_ex(struct Depsgraph *depsgraph,
/**
* Same as #BKE_object_mat3_to_rot().
*/
-void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], bool use_compat)
+void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, const float mat[3][3], bool use_compat)
{
BLI_ASSERT_UNIT_M3(mat);
@@ -1771,17 +1770,17 @@ void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], bool use_compat
/**
* Same as #BKE_object_rot_to_mat3().
*/
-void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float mat[3][3])
+void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float r_mat[3][3])
{
/* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
if (pchan->rotmode > 0) {
/* euler rotations (will cause gimble lock,
* but this can be alleviated a bit with rotation orders) */
- eulO_to_mat3(mat, pchan->eul, pchan->rotmode);
+ eulO_to_mat3(r_mat, pchan->eul, pchan->rotmode);
}
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
/* axis-angle - not really that great for 3D-changing orientations */
- axis_angle_to_mat3(mat, pchan->rotAxis, pchan->rotAngle);
+ axis_angle_to_mat3(r_mat, pchan->rotAxis, pchan->rotAngle);
}
else {
/* quats are normalized before use to eliminate scaling issues */
@@ -1791,7 +1790,7 @@ void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float mat[3][3])
* since this was kindof evil in some cases but if this proves to be too problematic,
* switch back to the old system of operating directly on the stored copy. */
normalize_qt_qt(quat, pchan->quat);
- quat_to_mat3(mat, quat);
+ quat_to_mat3(r_mat, quat);
}
}
@@ -1799,7 +1798,7 @@ void BKE_pchan_rot_to_mat3(const bPoseChannel *pchan, float mat[3][3])
* Apply a 4x4 matrix to the pose bone,
* similar to #BKE_object_apply_mat4().
*/
-void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[4][4], bool use_compat)
+void BKE_pchan_apply_mat4(bPoseChannel *pchan, const float mat[4][4], bool use_compat)
{
float rot[3][3];
mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat);
@@ -2003,7 +2002,7 @@ void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll)
* └ -2 * x * z, x^2 - z^2 ┘
* </pre>
*/
-void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float mat[3][3])
+void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float r_mat[3][3])
{
#define THETA_THRESHOLD_NEGY 1.0e-9f
#define THETA_THRESHOLD_NEGY_CLOSE 1.0e-5f
@@ -2057,18 +2056,18 @@ void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float mat
axis_angle_normalized_to_mat3(rMatrix, nor, roll);
/* Combine and output result */
- mul_m3_m3m3(mat, rMatrix, bMatrix);
+ mul_m3_m3m3(r_mat, rMatrix, bMatrix);
#undef THETA_THRESHOLD_NEGY
#undef THETA_THRESHOLD_NEGY_CLOSE
}
-void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3])
+void vec_roll_to_mat3(const float vec[3], const float roll, float r_mat[3][3])
{
float nor[3];
normalize_v3_v3(nor, vec);
- vec_roll_to_mat3_normalized(nor, roll, mat);
+ vec_roll_to_mat3_normalized(nor, roll, r_mat);
}
/** \} */
@@ -2169,7 +2168,7 @@ static void pose_proxy_sync(Object *ob, Object *from, int layer_protected)
}
/* clear all transformation values from library */
- BKE_pose_rest(frompose);
+ BKE_pose_rest(frompose, false);
/* copy over all of the proxy's bone groups */
/* TODO for later
@@ -2206,7 +2205,7 @@ static void pose_proxy_sync(Object *ob, Object *from, int layer_protected)
pchan->mpath = NULL;
/* Reset runtime data, we don't want to share that with the proxy. */
- BKE_pose_channel_runtime_reset(&pchanw.runtime);
+ BKE_pose_channel_runtime_reset_on_copy(&pchanw.runtime);
/* this is freed so copy a copy, else undo crashes */
if (pchanw.prop) {
@@ -2423,8 +2422,10 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
/** \name Pose Solver
* \{ */
-/* loc/rot/size to given mat4 */
-void BKE_pchan_to_mat4(const bPoseChannel *pchan, float chan_mat[4][4])
+/**
+ * Convert the loc/rot/size to \a r_chanmat (typically #bPoseChannel.chan_mat).
+ */
+void BKE_pchan_to_mat4(const bPoseChannel *pchan, float r_chanmat[4][4])
{
float smat[3][3];
float rmat[3][3];
@@ -2438,12 +2439,12 @@ void BKE_pchan_to_mat4(const bPoseChannel *pchan, float chan_mat[4][4])
/* calculate matrix of bone (as 3x3 matrix, but then copy the 4x4) */
mul_m3_m3m3(tmat, rmat, smat);
- copy_m4_m3(chan_mat, tmat);
+ copy_m4_m3(r_chanmat, tmat);
/* prevent action channels breaking chains */
/* need to check for bone here, CONSTRAINT_TYPE_ACTION uses this call */
if ((pchan->bone == NULL) || !(pchan->bone->flag & BONE_CONNECTED)) {
- copy_v3_v3(chan_mat[3], pchan->loc);
+ copy_v3_v3(r_chanmat[3], pchan->loc);
}
}
@@ -2581,7 +2582,7 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
}
/* 2a. construct the IK tree (standard IK) */
- BIK_initialize_tree(depsgraph, scene, ob, ctime);
+ BIK_init_tree(depsgraph, scene, ob, ctime);
/* 2b. construct the Spline IK trees
* - this is not integrated as an IK plugin, since it should be able
diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c
index 44b50ab96d3..8711a001e32 100644
--- a/source/blender/blenkernel/intern/armature_deform.c
+++ b/source/blender/blenkernel/intern/armature_deform.c
@@ -163,17 +163,15 @@ float distfactor_to_bone(
if (dist_sq < a) {
return 1.0f;
}
- else {
- l = rad + rdist;
- l *= l;
- if (rdist == 0.0f || dist_sq >= l) {
- return 0.0f;
- }
- else {
- a = sqrtf(dist_sq) - rad;
- return 1.0f - (a * a) / (rdist * rdist);
- }
+
+ l = rad + rdist;
+ l *= l;
+ if (rdist == 0.0f || dist_sq >= l) {
+ return 0.0f;
}
+
+ a = sqrtf(dist_sq) - rad;
+ return 1.0f - (a * a) / (rdist * rdist);
}
static float dist_bone_deform(
diff --git a/source/blender/blenkernel/intern/armature_test.cc b/source/blender/blenkernel/intern/armature_test.cc
new file mode 100644
index 00000000000..cf17c37bc69
--- /dev/null
+++ b/source/blender/blenkernel/intern/armature_test.cc
@@ -0,0 +1,93 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation
+ * All rights reserved.
+ */
+
+#include "BKE_armature.h"
+
+#include "BLI_math.h"
+
+#include "testing/testing.h"
+
+namespace blender::bke::tests {
+
+static const float FLOAT_EPSILON = 1.2e-7;
+
+TEST(mat3_vec_to_roll, UnitMatrix)
+{
+ float unit_matrix[3][3];
+ float roll;
+
+ unit_m3(unit_matrix);
+
+ // Any vector with a unit matrix should return zero roll.
+ mat3_vec_to_roll(unit_matrix, unit_matrix[0], &roll);
+ EXPECT_FLOAT_EQ(0.0f, roll);
+
+ mat3_vec_to_roll(unit_matrix, unit_matrix[1], &roll);
+ EXPECT_FLOAT_EQ(0.0f, roll);
+
+ mat3_vec_to_roll(unit_matrix, unit_matrix[2], &roll);
+ EXPECT_FLOAT_EQ(0.0f, roll);
+
+ {
+ // Non-unit vector.
+ float vector[3] = {1.0f, 1.0f, 1.0f};
+ mat3_vec_to_roll(unit_matrix, vector, &roll);
+ EXPECT_NEAR(0.0f, roll, FLOAT_EPSILON);
+
+ // Normalized version of the above vector.
+ normalize_v3(vector);
+ mat3_vec_to_roll(unit_matrix, vector, &roll);
+ EXPECT_NEAR(0.0f, roll, FLOAT_EPSILON);
+ }
+}
+
+TEST(mat3_vec_to_roll, Rotationmatrix)
+{
+ float rotation_matrix[3][3];
+ float roll;
+
+ const float rot_around_x[3] = {1.234f, 0.0f, 0.0f};
+ eul_to_mat3(rotation_matrix, rot_around_x);
+
+ {
+ const float unit_axis_x[3] = {1.0f, 0.0f, 0.0f};
+ mat3_vec_to_roll(rotation_matrix, unit_axis_x, &roll);
+ EXPECT_NEAR(1.234f, roll, FLOAT_EPSILON);
+ }
+
+ {
+ const float unit_axis_y[3] = {0.0f, 1.0f, 0.0f};
+ mat3_vec_to_roll(rotation_matrix, unit_axis_y, &roll);
+ EXPECT_NEAR(0, roll, FLOAT_EPSILON);
+ }
+
+ {
+ const float unit_axis_z[3] = {0.0f, 0.0f, 1.0f};
+ mat3_vec_to_roll(rotation_matrix, unit_axis_z, &roll);
+ EXPECT_NEAR(0, roll, FLOAT_EPSILON);
+ }
+
+ {
+ const float between_x_and_y[3] = {1.0f, 1.0f, 0.0f};
+ mat3_vec_to_roll(rotation_matrix, between_x_and_y, &roll);
+ EXPECT_NEAR(0.57158958f, roll, FLOAT_EPSILON);
+ }
+}
+
+} // namespace blender::bke::tests
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index d0a5e4348b9..97c717572bc 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -119,9 +119,8 @@ static void splineik_init_tree_from_pchan(Scene *UNUSED(scene),
if (segcount == 0) {
return;
}
- else {
- pchanRoot = pchanChain[segcount - 1];
- }
+
+ pchanRoot = pchanChain[segcount - 1];
/* perform binding step if required */
if ((ikData->flag & CONSTRAINT_SPLINEIK_BOUND) == 0) {
@@ -659,7 +658,7 @@ void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *ob
return;
}
/* construct the IK tree (standard IK) */
- BIK_initialize_tree(depsgraph, scene, object, ctime);
+ BIK_init_tree(depsgraph, scene, object, ctime);
/* construct the Spline IK trees
* - this is not integrated as an IK plugin, since it should be able
* to function in conjunction with standard IK. */
@@ -717,7 +716,7 @@ void BKE_pose_constraints_evaluate(struct Depsgraph *depsgraph,
if (armature->flag & ARM_RESTPOS) {
return;
}
- else if (pchan->flag & POSE_IKTREE || pchan->flag & POSE_IKSPLINE) {
+ if (pchan->flag & POSE_IKTREE || pchan->flag & POSE_IKSPLINE) {
/* IK are being solved separately/ */
}
else {
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index d5064629451..a0da1b1677d 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -872,91 +872,90 @@ static Object *boid_find_ground(BoidBrainData *bbd,
return bpa->ground;
}
- else {
- float zvec[3] = {0.0f, 0.0f, 2000.0f};
- ParticleCollision col;
- ColliderCache *coll;
- BVHTreeRayHit hit;
- float radius = 0.0f, t, ray_dir[3];
-
- if (!bbd->sim->colliders) {
- return NULL;
- }
-
- memset(&col, 0, sizeof(ParticleCollision));
- /* first try to find below boid */
- copy_v3_v3(col.co1, pa->state.co);
- sub_v3_v3v3(col.co2, pa->state.co, zvec);
- sub_v3_v3v3(ray_dir, col.co2, col.co1);
- col.f = 0.0f;
- hit.index = -1;
- hit.dist = col.original_ray_length = normalize_v3(ray_dir);
- col.pce.inside = 0;
+ float zvec[3] = {0.0f, 0.0f, 2000.0f};
+ ParticleCollision col;
+ ColliderCache *coll;
+ BVHTreeRayHit hit;
+ float radius = 0.0f, t, ray_dir[3];
- for (coll = bbd->sim->colliders->first; coll; coll = coll->next) {
- col.current = coll->ob;
- col.md = coll->collmd;
- col.fac1 = col.fac2 = 0.f;
+ if (!bbd->sim->colliders) {
+ return NULL;
+ }
- if (col.md && col.md->bvhtree) {
- BLI_bvhtree_ray_cast_ex(col.md->bvhtree,
- col.co1,
- ray_dir,
- radius,
- &hit,
- BKE_psys_collision_neartest_cb,
- &col,
- raycast_flag);
- }
+ memset(&col, 0, sizeof(ParticleCollision));
+
+ /* first try to find below boid */
+ copy_v3_v3(col.co1, pa->state.co);
+ sub_v3_v3v3(col.co2, pa->state.co, zvec);
+ sub_v3_v3v3(ray_dir, col.co2, col.co1);
+ col.f = 0.0f;
+ hit.index = -1;
+ hit.dist = col.original_ray_length = normalize_v3(ray_dir);
+ col.pce.inside = 0;
+
+ for (coll = bbd->sim->colliders->first; coll; coll = coll->next) {
+ col.current = coll->ob;
+ col.md = coll->collmd;
+ col.fac1 = col.fac2 = 0.f;
+
+ if (col.md && col.md->bvhtree) {
+ BLI_bvhtree_ray_cast_ex(col.md->bvhtree,
+ col.co1,
+ ray_dir,
+ radius,
+ &hit,
+ BKE_psys_collision_neartest_cb,
+ &col,
+ raycast_flag);
}
- /* then use that object */
- if (hit.index >= 0) {
- t = hit.dist / col.original_ray_length;
- interp_v3_v3v3(ground_co, col.co1, col.co2, t);
- normalize_v3_v3(ground_nor, col.pce.nor);
- return col.hit;
- }
-
- /* couldn't find below, so find upmost deflector object */
- add_v3_v3v3(col.co1, pa->state.co, zvec);
- sub_v3_v3v3(col.co2, pa->state.co, zvec);
- sub_v3_v3(col.co2, zvec);
- sub_v3_v3v3(ray_dir, col.co2, col.co1);
- col.f = 0.0f;
- hit.index = -1;
- hit.dist = col.original_ray_length = normalize_v3(ray_dir);
-
- for (coll = bbd->sim->colliders->first; coll; coll = coll->next) {
- col.current = coll->ob;
- col.md = coll->collmd;
+ }
+ /* then use that object */
+ if (hit.index >= 0) {
+ t = hit.dist / col.original_ray_length;
+ interp_v3_v3v3(ground_co, col.co1, col.co2, t);
+ normalize_v3_v3(ground_nor, col.pce.nor);
+ return col.hit;
+ }
- if (col.md && col.md->bvhtree) {
- BLI_bvhtree_ray_cast_ex(col.md->bvhtree,
- col.co1,
- ray_dir,
- radius,
- &hit,
- BKE_psys_collision_neartest_cb,
- &col,
- raycast_flag);
- }
+ /* couldn't find below, so find upmost deflector object */
+ add_v3_v3v3(col.co1, pa->state.co, zvec);
+ sub_v3_v3v3(col.co2, pa->state.co, zvec);
+ sub_v3_v3(col.co2, zvec);
+ sub_v3_v3v3(ray_dir, col.co2, col.co1);
+ col.f = 0.0f;
+ hit.index = -1;
+ hit.dist = col.original_ray_length = normalize_v3(ray_dir);
+
+ for (coll = bbd->sim->colliders->first; coll; coll = coll->next) {
+ col.current = coll->ob;
+ col.md = coll->collmd;
+
+ if (col.md && col.md->bvhtree) {
+ BLI_bvhtree_ray_cast_ex(col.md->bvhtree,
+ col.co1,
+ ray_dir,
+ radius,
+ &hit,
+ BKE_psys_collision_neartest_cb,
+ &col,
+ raycast_flag);
}
- /* then use that object */
- if (hit.index >= 0) {
- t = hit.dist / col.original_ray_length;
- interp_v3_v3v3(ground_co, col.co1, col.co2, t);
- normalize_v3_v3(ground_nor, col.pce.nor);
- return col.hit;
- }
-
- /* default to z=0 */
- copy_v3_v3(ground_co, pa->state.co);
- ground_co[2] = 0;
- ground_nor[0] = ground_nor[1] = 0.0f;
- ground_nor[2] = 1.0f;
- return NULL;
}
+ /* then use that object */
+ if (hit.index >= 0) {
+ t = hit.dist / col.original_ray_length;
+ interp_v3_v3v3(ground_co, col.co1, col.co2, t);
+ normalize_v3_v3(ground_nor, col.pce.nor);
+ return col.hit;
+ }
+
+ /* default to z=0 */
+ copy_v3_v3(ground_co, pa->state.co);
+ ground_co[2] = 0;
+ ground_nor[0] = ground_nor[1] = 0.0f;
+ ground_nor[2] = 1.0f;
+ return NULL;
}
static int boid_rule_applies(ParticleData *pa, BoidSettings *UNUSED(boids), BoidRule *rule)
{
@@ -1046,9 +1045,7 @@ static int apply_boid_rule(
fuzziness * len_v3(pa->prev_state.vel)) == 0) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa)
{
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 44873c54469..e2d17f34992 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -147,19 +147,16 @@ static bool bpath_relative_rebase_visit_cb(void *userdata, char *path_dst, const
data->count_changed++;
return true;
}
- else {
- /* Failed to make relative path absolute. */
- BLI_assert(0);
- BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
- data->count_failed++;
- return false;
- }
- return false;
- }
- else {
- /* Absolute, leave this as-is. */
+
+ /* Failed to make relative path absolute. */
+ BLI_assert(0);
+ BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
+ data->count_failed++;
return false;
}
+
+ /* Absolute, leave this as-is. */
+ return false;
}
void BKE_bpath_relative_rebase(Main *bmain,
@@ -211,18 +208,17 @@ static bool bpath_relative_convert_visit_cb(void *userdata, char *path_dst, cons
if (BLI_path_is_rel(path_src)) {
return false; /* already relative */
}
+
+ strcpy(path_dst, path_src);
+ BLI_path_rel(path_dst, data->basedir);
+ if (BLI_path_is_rel(path_dst)) {
+ data->count_changed++;
+ }
else {
- strcpy(path_dst, path_src);
- BLI_path_rel(path_dst, data->basedir);
- if (BLI_path_is_rel(path_dst)) {
- data->count_changed++;
- }
- else {
- BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made relative", path_src);
- data->count_failed++;
- }
- return true;
+ BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made relative", path_src);
+ data->count_failed++;
}
+ return true;
}
void BKE_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports)
@@ -263,18 +259,17 @@ static bool bpath_absolute_convert_visit_cb(void *userdata, char *path_dst, cons
if (BLI_path_is_rel(path_src) == false) {
return false; /* already absolute */
}
+
+ strcpy(path_dst, path_src);
+ BLI_path_abs(path_dst, data->basedir);
+ if (BLI_path_is_rel(path_dst) == false) {
+ data->count_changed++;
+ }
else {
- strcpy(path_dst, path_src);
- BLI_path_abs(path_dst, data->basedir);
- if (BLI_path_is_rel(path_dst) == false) {
- data->count_changed++;
- }
- else {
- BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
- data->count_failed++;
- }
- return true;
+ BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
+ data->count_failed++;
}
+ return true;
}
/* similar to BKE_bpath_relative_convert - keep in sync! */
@@ -411,7 +406,7 @@ static bool missing_files_find__visit_cb(void *userdata, char *path_dst, const c
BLI_path_basename(data->searchdir));
return false;
}
- else if (found == false) {
+ if (found == false) {
BKE_reportf(data->reports,
RPT_WARNING,
"Could not find '%s' in '%s'",
@@ -419,18 +414,17 @@ static bool missing_files_find__visit_cb(void *userdata, char *path_dst, const c
data->searchdir);
return false;
}
- else {
- bool was_relative = BLI_path_is_rel(path_dst);
- BLI_strncpy(path_dst, filename_new, FILE_MAX);
+ bool was_relative = BLI_path_is_rel(path_dst);
- /* keep path relative if the previous one was relative */
- if (was_relative) {
- BLI_path_rel(path_dst, data->basedir);
- }
+ BLI_strncpy(path_dst, filename_new, FILE_MAX);
- return true;
+ /* keep path relative if the previous one was relative */
+ if (was_relative) {
+ BLI_path_rel(path_dst, data->basedir);
}
+
+ return true;
}
void BKE_bpath_missing_files_find(Main *bmain,
@@ -483,9 +477,8 @@ static bool rewrite_path_fixed(char *path,
BLI_strncpy(path, path_dst, FILE_MAX);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static bool rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR],
@@ -510,9 +503,8 @@ static bool rewrite_path_fixed_dirfile(char path_dir[FILE_MAXDIR],
BLI_split_dirfile(path_dst, path_dir, path_file, FILE_MAXDIR, FILE_MAXFILE);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static bool rewrite_path_alloc(char **path,
@@ -538,9 +530,8 @@ static bool rewrite_path_alloc(char **path,
(*path) = BLI_strdup(path_dst);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -827,10 +818,9 @@ bool BKE_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *pa
BLI_strncpy(path_dst, filepath, FILE_MAX);
return true;
}
- else {
- /* Path was not relative to begin with. */
- return false;
- }
+
+ /* Path was not relative to begin with. */
+ return false;
}
/** \} */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index a8f52593429..39fbea66637 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -372,8 +372,8 @@ bool BKE_brush_delete(Main *bmain, Brush *brush)
if (brush->id.tag & LIB_TAG_INDIRECT) {
return false;
}
- else if (BKE_library_ID_is_indirectly_used(bmain, brush) && ID_REAL_USERS(brush) <= 1 &&
- ID_EXTRA_USERS(brush) == 0) {
+ if (BKE_library_ID_is_indirectly_used(bmain, brush) && ID_REAL_USERS(brush) <= 1 &&
+ ID_EXTRA_USERS(brush) == 0) {
return false;
}
@@ -503,7 +503,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.4f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->input_samples = 10;
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
@@ -557,7 +557,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INK);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INK;
@@ -594,7 +594,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INKNOISE);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INKNOISE;
@@ -631,7 +631,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_MARKER);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_MARKER;
@@ -667,12 +667,12 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_CHISEL_SENSIVITY);
custom_curve = brush->gpencil_settings->curve_strength;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_CHISEL_STRENGTH);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_CHISEL;
@@ -686,7 +686,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag &= ~GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 1.0f;
- brush->gpencil_settings->flag &= ~GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag &= ~GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->input_samples = 10;
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
@@ -717,7 +717,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.4f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->input_samples = 10;
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
@@ -760,7 +760,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.6f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->input_samples = 10;
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
@@ -812,7 +812,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->draw_strength = 0.5f;
brush->gpencil_settings->flag |= GP_BRUSH_DEFAULT_ERASER;
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_SOFT;
brush->gpencil_tool = GPAINT_TOOL_ERASE;
brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_SOFT;
@@ -859,7 +859,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -872,7 +872,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -885,7 +885,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -898,7 +898,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -911,7 +911,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -924,7 +924,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
zero_v3(brush->secondary_rgb);
break;
@@ -937,7 +937,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_flag = GP_SCULPT_FLAG_SMOOTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
@@ -951,7 +951,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_flag = GP_SCULPT_FLAG_SMOOTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
@@ -965,7 +965,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.5f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -978,7 +978,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->size = 25.0f;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -991,7 +991,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1004,7 +1004,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.3f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1017,7 +1017,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.5f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1030,7 +1030,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.5f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1043,7 +1043,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->size = 25.0f;
brush->gpencil_settings->draw_strength = 1.0f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1056,7 +1056,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
brush->gpencil_settings->draw_strength = 0.8f;
- brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
+ brush->gpencil_settings->flag |= GP_BRUSH_USE_STRENGTH_PRESSURE;
brush->gpencil_settings->sculpt_mode_flag |= GP_SCULPT_FLAGMODE_APPLY_POSITION;
break;
@@ -1484,6 +1484,7 @@ void BKE_brush_sculpt_reset(Brush *br)
case SCULPT_TOOL_SLIDE_RELAX:
br->spacing = 10;
br->alpha = 1.0f;
+ br->slide_deform_type = BRUSH_SLIDE_DEFORM_DRAG;
break;
case SCULPT_TOOL_CLAY:
br->flag |= BRUSH_SIZE_PRESSURE;
@@ -1533,6 +1534,7 @@ void BKE_brush_sculpt_reset(Brush *br)
break;
case SCULPT_TOOL_SMOOTH:
br->flag &= ~BRUSH_SPACE_ATTEN;
+ br->automasking_flags |= BRUSH_AUTOMASKING_BOUNDARY_EDGES;
br->spacing = 5;
br->alpha = 0.7f;
br->surface_smooth_shape_preservation = 0.5f;
@@ -2180,10 +2182,9 @@ float BKE_brush_curve_strength(const Brush *br, float p, const float len)
if (p >= len) {
return 0;
}
- else {
- p = p / len;
- p = 1.0f - p;
- }
+
+ p = p / len;
+ p = 1.0f - p;
switch (br->curve_preset) {
case BRUSH_CURVE_CUSTOM:
@@ -2273,7 +2274,7 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool
int half = side / 2;
int i, j;
- BKE_curvemapping_initialize(br->curve);
+ BKE_curvemapping_init(br->curve);
texcache = BKE_brush_gen_texture_cache(br, half, secondary);
im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect");
im->x = im->y = side;
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 93794eb9709..bea8fdd5719 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -717,11 +717,14 @@ BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data,
/* printf("BVHTree built and saved on cache\n"); */
BVHCache *bvh_cache = *bvh_cache_p;
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
- bvhcache_unlock(bvh_cache, lock_started);
in_cache = true;
}
}
+ if (bvh_cache_p) {
+ bvhcache_unlock(*bvh_cache_p, lock_started);
+ }
+
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_verts_setup_data(data, tree, in_cache, vert, vert_allocated);
@@ -929,11 +932,14 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
/* Save on cache for later use */
/* printf("BVHTree built and saved on cache\n"); */
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
- bvhcache_unlock(bvh_cache, lock_started);
in_cache = true;
}
}
+ if (bvh_cache_p) {
+ bvhcache_unlock(*bvh_cache_p, lock_started);
+ }
+
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_edges_setup_data(
data, tree, in_cache, vert, vert_allocated, edge, edge_allocated);
@@ -1058,11 +1064,14 @@ BVHTree *bvhtree_from_mesh_faces_ex(BVHTreeFromMesh *data,
/* printf("BVHTree built and saved on cache\n"); */
BVHCache *bvh_cache = *bvh_cache_p;
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
- bvhcache_unlock(bvh_cache, lock_started);
in_cache = true;
}
}
+ if (bvh_cache_p) {
+ bvhcache_unlock(*bvh_cache_p, lock_started);
+ }
+
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_faces_setup_data(
data, tree, in_cache, vert, vert_allocated, face, face_allocated);
@@ -1298,11 +1307,14 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
if (bvh_cache_p) {
BVHCache *bvh_cache = *bvh_cache_p;
bvhcache_insert(bvh_cache, tree, bvh_cache_type);
- bvhcache_unlock(bvh_cache, lock_started);
in_cache = true;
}
}
+ if (bvh_cache_p) {
+ bvhcache_unlock(*bvh_cache_p, lock_started);
+ }
+
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_looptri_setup_data(data,
tree,
@@ -1428,8 +1440,6 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
mesh->medge, mesh->totedge, mesh->mvert, verts_len, &loose_vert_len);
}
- /* TODO: a global mutex lock held during the expensive operation of
- * building the BVH tree is really bad for performance. */
tree = bvhtree_from_mesh_verts_ex(data,
mesh->mvert,
verts_len,
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index da9dab36044..9ad6ae84c5c 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -61,6 +61,8 @@ static void cache_file_init_data(ID *id)
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(cache_file, id));
cache_file->scale = 1.0f;
+ cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND;
+ BLI_strncpy(cache_file->velocity_name, ".velocities", sizeof(cache_file->velocity_name));
}
static void cache_file_copy_data(Main *UNUSED(bmain),
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 566954fd5fa..467bd68c631 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -30,7 +30,6 @@
#include "DNA_scene_types.h"
#include "BLI_edgehash.h"
-#include "BLI_ghash.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_rand.h"
@@ -48,7 +47,7 @@
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
-#include "BPH_mass_spring.h"
+#include "SIM_mass_spring.h"
// #include "PIL_time.h" /* timing for debug prints */
@@ -345,12 +344,12 @@ static int do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int
return 0;
}
- BKE_cloth_solver_set_positions(clmd);
+ SIM_cloth_solver_set_positions(clmd);
ClothSimSettings *parms = clmd->sim_parms;
if (parms->flags & CLOTH_SIMSETTINGS_FLAG_PRESSURE &&
!(parms->flags & CLOTH_SIMSETTINGS_FLAG_PRESSURE_VOL)) {
- BKE_cloth_solver_set_volume(clmd);
+ SIM_cloth_solver_set_volume(clmd);
}
clmd->clothObject->last_frame = MINFRAME - 1;
@@ -405,7 +404,7 @@ static int do_step_cloth(
// TIMEIT_START(cloth_step)
/* call the solver. */
- ret = BPH_cloth_solve(depsgraph, ob, framenr, clmd, effectors);
+ ret = SIM_cloth_solve(depsgraph, ob, framenr, clmd, effectors);
// TIMEIT_END(cloth_step)
@@ -454,7 +453,7 @@ void clothModifier_do(ClothModifierData *clmd,
BKE_ptcache_invalidate(cache);
return;
}
- else if (framenr > endframe) {
+ if (framenr > endframe) {
framenr = endframe;
}
@@ -480,7 +479,7 @@ void clothModifier_do(ClothModifierData *clmd,
if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED ||
(!can_simulate && cache_result == PTCACHE_READ_OLD)) {
- BKE_cloth_solver_set_positions(clmd);
+ SIM_cloth_solver_set_positions(clmd);
cloth_to_object(ob, clmd, vertexCos);
BKE_ptcache_validate(cache, framenr);
@@ -493,8 +492,8 @@ void clothModifier_do(ClothModifierData *clmd,
return;
}
- else if (cache_result == PTCACHE_READ_OLD) {
- BKE_cloth_solver_set_positions(clmd);
+ if (cache_result == PTCACHE_READ_OLD) {
+ SIM_cloth_solver_set_positions(clmd);
}
else if (
/* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
@@ -538,7 +537,7 @@ void cloth_free_modifier(ClothModifierData *clmd)
cloth = clmd->clothObject;
if (cloth) {
- BPH_cloth_solver_free(clmd);
+ SIM_cloth_solver_free(clmd);
// Free the verts.
if (cloth->verts != NULL) {
@@ -587,7 +586,7 @@ void cloth_free_modifier(ClothModifierData *clmd)
}
if (cloth->sew_edge_graph) {
- BLI_ghash_free(cloth->sew_edge_graph, MEM_freeN, NULL);
+ BLI_edgeset_free(cloth->sew_edge_graph);
cloth->sew_edge_graph = NULL;
}
@@ -620,7 +619,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd)
printf("cloth_free_modifier_extern in\n");
}
- BPH_cloth_solver_free(clmd);
+ SIM_cloth_solver_free(clmd);
// Free the verts.
if (cloth->verts != NULL) {
@@ -669,7 +668,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd)
}
if (cloth->sew_edge_graph) {
- BLI_ghash_free(cloth->sew_edge_graph, MEM_freeN, NULL);
+ BLI_edgeset_free(cloth->sew_edge_graph);
cloth->sew_edge_graph = NULL;
}
@@ -920,10 +919,10 @@ static int cloth_from_object(
}
// init our solver
- BPH_cloth_solver_init(ob, clmd);
+ SIM_cloth_solver_init(ob, clmd);
if (!first) {
- BKE_cloth_solver_set_positions(clmd);
+ SIM_cloth_solver_set_positions(clmd);
}
clmd->clothObject->bvhtree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->epsilon);
@@ -1038,7 +1037,7 @@ static void cloth_free_errorsprings(Cloth *cloth,
}
BLI_INLINE void cloth_bend_poly_dir(
- ClothVertex *verts, int i, int j, int *inds, int len, float r_dir[3])
+ ClothVertex *verts, int i, int j, const int *inds, int len, float r_dir[3])
{
float cent[3] = {0};
float fact = 1.0f / len;
@@ -1557,9 +1556,8 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
*r_tar_v_idx = vert_idx;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
@@ -1693,8 +1691,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW) {
/* cloth->sew_edge_graph should not exist before this */
BLI_assert(cloth->sew_edge_graph == NULL);
- cloth->sew_edge_graph = BLI_ghash_new(
- BLI_ghashutil_inthash_v2_p, BLI_ghashutil_inthash_v2_cmp, "cloth_sewing_edges_graph");
+ cloth->sew_edge_graph = BLI_edgeset_new("cloth_sewing_edges_graph");
}
/* Structural springs. */
@@ -1709,18 +1706,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
spring->lin_stiffness = 1.0f;
spring->type = CLOTH_SPRING_TYPE_SEWING;
- /* set indices of verts of the sewing edge symmetrically in sew_edge_graph */
- unsigned int *vertex_index_pair = MEM_mallocN(sizeof(unsigned int) * 2,
- "sewing_edge_index_pair_01");
- if (medge[i].v1 < medge[i].v2) {
- vertex_index_pair[0] = medge[i].v1;
- vertex_index_pair[1] = medge[i].v2;
- }
- else {
- vertex_index_pair[0] = medge[i].v2;
- vertex_index_pair[1] = medge[i].v1;
- }
- BLI_ghash_insert(cloth->sew_edge_graph, vertex_index_pair, NULL);
+ BLI_edgeset_insert(cloth->sew_edge_graph, medge[i].v1, medge[i].v2);
}
else {
shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 080d61f1500..6118325c231 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -249,6 +249,34 @@ void BKE_collection_add_from_object(Main *bmain,
BKE_main_collection_sync(bmain);
}
+/**
+ * Add \a collection_dst to all scene collections that reference collection \a collection_src is
+ * in.
+ *
+ * Logic is very similar to #BKE_collection_object_add_from().
+ */
+void BKE_collection_add_from_collection(Main *bmain,
+ Scene *scene,
+ Collection *collection_src,
+ Collection *collection_dst)
+{
+ bool is_instantiated = false;
+
+ FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) {
+ if (!ID_IS_LINKED(collection) && BKE_collection_has_collection(collection, collection_src)) {
+ collection_child_add(collection, collection_dst, 0, true);
+ is_instantiated = true;
+ }
+ }
+ FOREACH_SCENE_COLLECTION_END;
+
+ if (!is_instantiated) {
+ collection_child_add(scene->master_collection, collection_dst, 0, true);
+ }
+
+ BKE_main_collection_sync(bmain);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -333,7 +361,6 @@ static Collection *collection_duplicate_recursive(Main *bmain,
Collection *collection_new;
bool do_full_process = false;
const bool is_collection_master = (collection_old->flag & COLLECTION_IS_MASTER) != 0;
- const bool is_collection_liboverride = ID_IS_OVERRIDE_LIBRARY(collection_old);
const bool do_objects = (duplicate_flags & USER_DUP_OBJECT) != 0;
@@ -346,7 +373,12 @@ static Collection *collection_duplicate_recursive(Main *bmain,
}
else if (collection_old->id.newid == NULL) {
collection_new = (Collection *)BKE_id_copy_for_duplicate(
- bmain, (ID *)collection_old, is_collection_liboverride, duplicate_flags);
+ bmain, (ID *)collection_old, duplicate_flags);
+
+ if (collection_new == collection_old) {
+ return collection_new;
+ }
+
do_full_process = true;
}
else {
@@ -382,17 +414,15 @@ static Collection *collection_duplicate_recursive(Main *bmain,
Object *ob_old = cob->ob;
Object *ob_new = (Object *)ob_old->id.newid;
- /* If collection is an override, we do not want to duplicate any linked data-block, as that
- * would generate a purely local data. */
- if (is_collection_liboverride && ID_IS_LINKED(ob_old)) {
- continue;
- }
-
if (ob_new == NULL) {
ob_new = BKE_object_duplicate(
bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS);
}
+ if (ob_new == ob_old) {
+ continue;
+ }
+
collection_object_add(bmain, collection_new, ob_new, 0, true);
collection_object_remove(bmain, collection_new, ob_old, false);
}
@@ -403,13 +433,11 @@ static Collection *collection_duplicate_recursive(Main *bmain,
LISTBASE_FOREACH_MUTABLE (CollectionChild *, child, &collection_old->children) {
Collection *child_collection_old = child->collection;
- if (is_collection_liboverride && ID_IS_LINKED(child_collection_old)) {
- continue;
- }
-
- collection_duplicate_recursive(
+ Collection *child_collection_new = collection_duplicate_recursive(
bmain, collection_new, child_collection_old, duplicate_flags, duplicate_options);
- collection_child_remove(collection_new, child_collection_old);
+ if (child_collection_new != child_collection_old) {
+ collection_child_remove(collection_new, child_collection_old);
+ }
}
return collection_new;
@@ -434,6 +462,11 @@ Collection *BKE_collection_duplicate(Main *bmain,
if (!is_subprocess) {
BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
BKE_main_id_clear_newpoins(bmain);
+ /* In case root duplicated ID is linked, assume we want to get a local copy of it and duplicate
+ * all expected linked data. */
+ if (ID_IS_LINKED(collection)) {
+ duplicate_flags |= USER_DUP_LINKED_ID;
+ }
}
Collection *collection_new = collection_duplicate_recursive(
@@ -1114,7 +1147,7 @@ void BKE_collections_after_lib_link(Main *bmain)
/** \name Collection Children
* \{ */
-static bool collection_find_instance_recursive(Collection *collection,
+static bool collection_instance_find_recursive(Collection *collection,
Collection *instance_collection)
{
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) {
@@ -1126,7 +1159,7 @@ static bool collection_find_instance_recursive(Collection *collection,
}
LISTBASE_FOREACH (CollectionChild *, collection_child, &collection->children) {
- if (collection_find_instance_recursive(collection_child->collection, instance_collection)) {
+ if (collection_instance_find_recursive(collection_child->collection, instance_collection)) {
return true;
}
}
@@ -1134,21 +1167,88 @@ static bool collection_find_instance_recursive(Collection *collection,
return false;
}
-bool BKE_collection_find_cycle(Collection *new_ancestor, Collection *collection)
+/**
+ * Find potential cycles in collections.
+ *
+ * \param new_ancestor the potential new owner of given \a collection, or the collection to check
+ * if the later is NULL.
+ * \param collection the collection we want to add to \a new_ancestor, may be NULL if we just want
+ * to ensure \a new_ancestor does not already have cycles.
+ * \return true if a cycle is found.
+ */
+bool BKE_collection_cycle_find(Collection *new_ancestor, Collection *collection)
{
if (collection == new_ancestor) {
return true;
}
+ if (collection == NULL) {
+ collection = new_ancestor;
+ }
+
LISTBASE_FOREACH (CollectionParent *, parent, &new_ancestor->parents) {
- if (BKE_collection_find_cycle(parent->collection, collection)) {
+ if (BKE_collection_cycle_find(parent->collection, collection)) {
return true;
}
}
/* Find possible objects in collection or its children, that would instantiate the given ancestor
* collection (that would also make a fully invalid cycle of dependencies) .*/
- return collection_find_instance_recursive(collection, new_ancestor);
+ return collection_instance_find_recursive(collection, new_ancestor);
+}
+
+static bool collection_instance_fix_recursive(Collection *parent_collection,
+ Collection *collection)
+{
+ bool cycles_found = false;
+
+ LISTBASE_FOREACH (CollectionObject *, collection_object, &parent_collection->gobject) {
+ if (collection_object->ob != NULL &&
+ collection_object->ob->instance_collection == collection) {
+ id_us_min(&collection->id);
+ collection_object->ob->instance_collection = NULL;
+ cycles_found = true;
+ }
+ }
+
+ LISTBASE_FOREACH (CollectionChild *, collection_child, &parent_collection->children) {
+ if (collection_instance_fix_recursive(collection_child->collection, collection)) {
+ cycles_found = true;
+ }
+ }
+
+ return cycles_found;
+}
+
+static bool collection_cycle_fix_recursive(Main *bmain,
+ Collection *parent_collection,
+ Collection *collection)
+{
+ bool cycles_found = false;
+
+ LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &parent_collection->parents) {
+ if (BKE_collection_cycle_find(parent->collection, collection)) {
+ BKE_collection_child_remove(bmain, parent->collection, parent_collection);
+ cycles_found = true;
+ }
+ else if (collection_cycle_fix_recursive(bmain, parent->collection, collection)) {
+ cycles_found = true;
+ }
+ }
+
+ return cycles_found;
+}
+
+/**
+ * Find and fix potential cycles in collections.
+ *
+ * \param collection the collection to check for existing cycles.
+ * \return true if cycles are found and fixed.
+ */
+bool BKE_collection_cycles_fix(Main *bmain, Collection *collection)
+{
+ return collection_cycle_fix_recursive(bmain, collection, collection) ||
+ collection_instance_fix_recursive(collection, collection);
}
static CollectionChild *collection_find_child(Collection *parent, Collection *collection)
@@ -1190,7 +1290,7 @@ static bool collection_child_add(Collection *parent,
if (child) {
return false;
}
- if (BKE_collection_find_cycle(parent, collection)) {
+ if (BKE_collection_cycle_find(parent, collection)) {
return false;
}
@@ -1268,7 +1368,7 @@ void BKE_collection_parent_relations_rebuild(Collection *collection)
child = child_next) {
child_next = child->next;
- if (child->collection == NULL || BKE_collection_find_cycle(collection, child->collection)) {
+ if (child->collection == NULL || BKE_collection_cycle_find(collection, child->collection)) {
BLI_freelinkN(&collection->children, child);
}
else {
@@ -1431,7 +1531,7 @@ bool BKE_collection_move(Main *bmain,
if (collection->flag & COLLECTION_IS_MASTER) {
return false;
}
- if (BKE_collection_find_cycle(to_parent, collection)) {
+ if (BKE_collection_cycle_find(to_parent, collection)) {
return false;
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index daf1602319f..31d49dd4508 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -32,7 +32,7 @@
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
-#include "BLI_ghash.h"
+#include "BLI_edgehash.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_task.h"
@@ -1153,17 +1153,7 @@ static bool cloth_bvh_selfcollision_is_active(const Cloth *cloth,
}
if (sewing_active) {
- unsigned int vertex_index_pair[2];
- /* The indices pair are ordered, thus must ensure the same here as well */
- if (tri_a->tri[i] < tri_b->tri[j]) {
- vertex_index_pair[0] = tri_a->tri[i];
- vertex_index_pair[1] = tri_b->tri[j];
- }
- else {
- vertex_index_pair[0] = tri_b->tri[j];
- vertex_index_pair[1] = tri_a->tri[i];
- }
- if (BLI_ghash_haskey(cloth->sew_edge_graph, vertex_index_pair)) {
+ if (BLI_edgeset_haskey(cloth->sew_edge_graph, tri_a->tri[i], tri_b->tri[j])) {
return false;
}
}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 4f4eb8f9f9d..fc326ffb390 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1202,7 +1202,7 @@ int BKE_curvemapping_RGBA_does_something(const CurveMapping *cumap)
return 0;
}
-void BKE_curvemapping_initialize(CurveMapping *cumap)
+void BKE_curvemapping_init(CurveMapping *cumap)
{
int a;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 06c28776840..2ef32895db9 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -53,6 +53,7 @@
#include "BKE_action.h"
#include "BKE_anim_path.h"
+#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_bvhutils.h"
#include "BKE_cachefile.h"
@@ -2625,7 +2626,7 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
+static void actcon_get_tarmat(struct Depsgraph *depsgraph,
bConstraint *con,
bConstraintOb *cob,
bConstraintTarget *ct,
@@ -2679,6 +2680,8 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
s = (vec[axis] - data->min) / (data->max - data->min);
CLAMP(s, 0, 1);
t = (s * (data->end - data->start)) + data->start;
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ t);
if (G.debug & G_DEBUG) {
printf("do Action Constraint %s - Ob %s Pchan %s\n",
@@ -2693,7 +2696,7 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
/* evaluate using workob */
/* FIXME: we don't have any consistent standards on limiting effects on object... */
- what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t);
+ what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, &anim_eval_context);
BKE_object_to_mat4(&workob, ct->matrix);
}
else if (cob->type == CONSTRAINT_OBTYPE_BONE) {
@@ -2710,7 +2713,7 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
tchan->rotmode = pchan->rotmode;
/* evaluate action using workob (it will only set the PoseChannel in question) */
- what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, t);
+ what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, &anim_eval_context);
/* convert animation to matrices for use here */
BKE_pchan_calc_mat(tchan);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 8de12139306..30f021b0e81 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -694,6 +694,11 @@ wmWindowManager *CTX_wm_manager(const bContext *C)
return C->wm.manager;
}
+bool CTX_wm_interface_locked(const bContext *C)
+{
+ return (bool)C->wm.manager->is_interface_locked;
+}
+
wmWindow *CTX_wm_window(const bContext *C)
{
return ctx_wm_python_context_get(C, "window", &RNA_Window, C->wm.window);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 6b28297622c..e126fb7f632 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -223,7 +223,7 @@ void BKE_curve_init(Curve *cu, const short curve_type)
cu->vfont->id.us += 4;
cu->str = MEM_malloc_arrayN(12, sizeof(unsigned char), "str");
BLI_strncpy(cu->str, "Text", 12);
- cu->len = cu->len_wchar = cu->pos = 4;
+ cu->len = cu->len_char32 = cu->pos = 4;
cu->strinfo = MEM_calloc_arrayN(12, sizeof(CharInfo), "strinfo new");
cu->totbox = cu->actbox = 1;
cu->tb = MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), "textbox");
@@ -1157,7 +1157,7 @@ void BKE_nurb_knot_calc_v(Nurb *nu)
}
static void basisNurb(
- float t, short order, int pnts, float *knots, float *basis, int *start, int *end)
+ float t, short order, int pnts, const float *knots, float *basis, int *start, int *end)
{
float d, e;
int i, i1 = 0, i2 = 0, j, orderpluspnts, opp2, o2;
@@ -1190,9 +1190,8 @@ static void basisNurb(
}
break;
}
- else {
- basis[i] = 0.0;
- }
+
+ basis[i] = 0.0;
}
basis[i] = 0.0;
@@ -1727,205 +1726,6 @@ static void forward_diff_bezier_cotangent(const float p0[3],
}
}
-/* ***************** BEVEL ****************** */
-
-void BKE_curve_bevel_make(Object *ob, ListBase *disp)
-{
- DispList *dl, *dlnew;
- Curve *bevcu, *cu;
- float *fp, facx, facy, angle, dangle;
- int nr, a;
-
- cu = ob->data;
- BLI_listbase_clear(disp);
-
- /* if a font object is being edited, then do nothing */
- // XXX if ( ob == obedit && ob->type == OB_FONT ) return;
-
- if (cu->bevobj) {
- if (cu->bevobj->type != OB_CURVE) {
- return;
- }
-
- bevcu = cu->bevobj->data;
- if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) {
- ListBase bevdisp = {NULL, NULL};
- facx = cu->bevobj->scale[0];
- facy = cu->bevobj->scale[1];
-
- if (cu->bevobj->runtime.curve_cache) {
- dl = cu->bevobj->runtime.curve_cache->disp.first;
- }
- else {
- BLI_assert(cu->bevobj->runtime.curve_cache != NULL);
- dl = NULL;
- }
-
- while (dl) {
- if (ELEM(dl->type, DL_POLY, DL_SEGM)) {
- dlnew = MEM_mallocN(sizeof(DispList), "makebevelcurve1");
- *dlnew = *dl;
- dlnew->verts = MEM_malloc_arrayN(
- dl->parts * dl->nr, 3 * sizeof(float), "makebevelcurve1");
- memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr);
-
- if (dlnew->type == DL_SEGM) {
- dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE);
- }
-
- BLI_addtail(disp, dlnew);
- fp = dlnew->verts;
- nr = dlnew->parts * dlnew->nr;
- while (nr--) {
- fp[2] = fp[1] * facy;
- fp[1] = -fp[0] * facx;
- fp[0] = 0.0;
- fp += 3;
- }
- }
- dl = dl->next;
- }
-
- BKE_displist_free(&bevdisp);
- }
- }
- else if (cu->ext1 == 0.0f && cu->ext2 == 0.0f) {
- /* pass */
- }
- else if (cu->ext2 == 0.0f) {
- dl = MEM_callocN(sizeof(DispList), "makebevelcurve2");
- dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), "makebevelcurve2");
- BLI_addtail(disp, dl);
- dl->type = DL_SEGM;
- dl->parts = 1;
- dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
- dl->nr = 2;
-
- fp = dl->verts;
- fp[0] = fp[1] = 0.0;
- fp[2] = -cu->ext1;
- fp[3] = fp[4] = 0.0;
- fp[5] = cu->ext1;
- }
- else if ((cu->flag & (CU_FRONT | CU_BACK)) == 0 && cu->ext1 == 0.0f) {
- /* We make a full round bevel in that case. */
-
- nr = 4 + 2 * cu->bevresol;
-
- dl = MEM_callocN(sizeof(DispList), "makebevelcurve p1");
- dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve p1");
- BLI_addtail(disp, dl);
- dl->type = DL_POLY;
- dl->parts = 1;
- dl->flag = DL_BACK_CURVE;
- dl->nr = nr;
-
- /* a circle */
- fp = dl->verts;
- dangle = (2.0f * (float)M_PI / (nr));
- angle = -(nr - 1) * dangle;
-
- for (a = 0; a < nr; a++) {
- fp[0] = 0.0;
- fp[1] = (cosf(angle) * (cu->ext2));
- fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1;
- angle += dangle;
- fp += 3;
- }
- }
- else {
- /* The general case for nonzero extrusion or an incomplete loop. */
- dl = MEM_callocN(sizeof(DispList), "makebevelcurve");
- if ((cu->flag & (CU_FRONT | CU_BACK)) == 0) {
- /* The full loop. */
- nr = 4 * cu->bevresol + 6;
- dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
- }
- else if ((cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) {
- /* Half the loop. */
- nr = 2 * (cu->bevresol + 1) + ((cu->ext1 == 0.0f) ? 1 : 2);
- dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
- }
- else {
- /* One quarter of the loop (just front or back). */
- nr = (cu->ext1 == 0.0f) ? cu->bevresol + 2 : cu->bevresol + 3;
- dl->flag = (cu->flag & CU_FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE;
- }
-
- dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve");
- BLI_addtail(disp, dl);
- /* Use a different type depending on whether the loop is complete or not. */
- dl->type = ((cu->flag & (CU_FRONT | CU_BACK)) == 0) ? DL_POLY : DL_SEGM;
- dl->parts = 1;
- dl->nr = nr;
-
- fp = dl->verts;
- dangle = (float)M_PI_2 / (cu->bevresol + 1);
- angle = 0.0;
-
- /* Build the back section. */
- if (cu->flag & CU_BACK || !(cu->flag & CU_FRONT)) {
- angle = (float)M_PI_2 * 3.0f;
- for (a = 0; a < cu->bevresol + 2; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
- angle += dangle;
- fp += 3;
- }
- if ((cu->ext1 != 0.0f) && !(cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) {
- /* Add the extrusion if we're only building the back. */
- fp[0] = 0.0;
- fp[1] = cu->ext2;
- fp[2] = cu->ext1;
- }
- }
-
- /* Build the front section. */
- if (cu->flag & CU_FRONT || !(cu->flag & CU_BACK)) {
- if ((cu->ext1 != 0.0f) && !(cu->flag & CU_BACK) && (cu->flag & CU_FRONT)) {
- /* Add the extrusion if we're only building the back. */
- fp[0] = 0.0;
- fp[1] = cu->ext2;
- fp[2] = -cu->ext1;
- fp += 3;
- }
- /* Don't duplicate the last back vertex. */
- angle = (cu->ext1 == 0.0f && (cu->flag & CU_BACK)) ? dangle : 0;
- int front_len = (cu->ext1 == 0.0f && ((cu->flag & CU_BACK) || !(cu->flag & CU_FRONT))) ?
- cu->bevresol + 1 :
- cu->bevresol + 2;
- for (a = 0; a < front_len; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
- angle += dangle;
- fp += 3;
- }
- }
-
- /* Build the other half only if we're building the full loop. */
- if (!(cu->flag & (CU_FRONT | CU_BACK))) {
- for (a = 0; a < cu->bevresol + 1; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
- angle += dangle;
- fp += 3;
- }
-
- angle = (float)M_PI;
- for (a = 0; a < cu->bevresol + 1; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
- angle += dangle;
- fp += 3;
- }
- }
- }
-}
-
static int cu_isectLL(const float v1[3],
const float v2[3],
const float v3[3],
@@ -2040,7 +1840,7 @@ static int vergxcobev(const void *a1, const void *a2)
if (x1->left > x2->left) {
return 1;
}
- else if (x1->left < x2->left) {
+ if (x1->left < x2->left) {
return -1;
}
return 0;
@@ -3113,8 +2913,9 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
if (bl->poly > 0) {
BevPoint *bevp;
- min = 300000.0;
bevp = bl->bevpoints;
+ bevp1 = bl->bevpoints;
+ min = bevp1->vec[0];
nr = bl->nr;
while (nr--) {
if (min > bevp->vec[0]) {
@@ -3561,8 +3362,13 @@ static void free_arrays(void *buffer)
}
/* computes in which direction to change h[i] to satisfy conditions better */
-static float bezier_relax_direction(
- float *a, float *b, float *c, float *d, float *h, int i, int count)
+static float bezier_relax_direction(const float *a,
+ const float *b,
+ const float *c,
+ const float *d,
+ const float *h,
+ int i,
+ int count)
{
/* current deviation between sides of the equation */
float state = a[i] * h[(i + count - 1) % count] + b[i] * h[i] + c[i] * h[(i + 1) % count] - d[i];
@@ -3578,8 +3384,15 @@ static void bezier_lock_unknown(float *a, float *b, float *c, float *d, int i, f
d[i] = value;
}
-static void bezier_restore_equation(
- float *a, float *b, float *c, float *d, float *a0, float *b0, float *c0, float *d0, int i)
+static void bezier_restore_equation(float *a,
+ float *b,
+ float *c,
+ float *d,
+ const float *a0,
+ const float *b0,
+ const float *c0,
+ const float *d0,
+ int i)
{
a[i] = a0[i];
b[i] = b0[i];
@@ -3587,8 +3400,14 @@ static void bezier_restore_equation(
d[i] = d0[i];
}
-static bool tridiagonal_solve_with_limits(
- float *a, float *b, float *c, float *d, float *h, float *hmin, float *hmax, int solve_count)
+static bool tridiagonal_solve_with_limits(float *a,
+ float *b,
+ float *c,
+ float *d,
+ float *h,
+ const float *hmin,
+ const float *hmax,
+ int solve_count)
{
float *a0, *b0, *c0, *d0;
float **arrays[] = {&a0, &b0, &c0, &d0, NULL};
@@ -3727,7 +3546,7 @@ static bool tridiagonal_solve_with_limits(
/* clang-format on */
static void bezier_eq_continuous(
- float *a, float *b, float *c, float *d, float *dy, float *l, int i)
+ float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
{
a[i] = l[i] * l[i];
b[i] = 2.0f * (l[i] + 1);
@@ -3736,7 +3555,7 @@ static void bezier_eq_continuous(
}
static void bezier_eq_noaccel_right(
- float *a, float *b, float *c, float *d, float *dy, float *l, int i)
+ float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
{
a[i] = 0.0f;
b[i] = 2.0f;
@@ -3745,7 +3564,7 @@ static void bezier_eq_noaccel_right(
}
static void bezier_eq_noaccel_left(
- float *a, float *b, float *c, float *d, float *dy, float *l, int i)
+ float *a, float *b, float *c, float *d, const float *dy, const float *l, int i)
{
a[i] = l[i] * l[i];
b[i] = 2.0f * l[i];
@@ -4612,7 +4431,7 @@ void BKE_nurb_direction_switch(Nurb *nu)
bp1++;
bp2--;
}
- /* If there're odd number of points no need to touch coord of middle one,
+ /* If there are odd number of points no need to touch coord of middle one,
* but still need to change it's tilt.
*/
if (nu->pntsu & 1) {
@@ -4824,7 +4643,7 @@ float (*BKE_curve_nurbs_key_vert_coords_alloc(ListBase *lb, float *key, int *r_v
return cos;
}
-void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, float *key)
+void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, const float *key)
{
Nurb *nu;
int i;
@@ -5064,32 +4883,31 @@ bool BKE_nurb_type_convert(Nurb *nu,
}
return false; /* conversion impossible */
}
- else {
- bezt = MEM_calloc_arrayN(nr, sizeof(BezTriple), "setsplinetype2");
- nu->bezt = bezt;
- a = nr;
- bp = nu->bp;
- while (a--) {
- copy_v3_v3(bezt->vec[0], bp->vec);
- bezt->f1 = bp->f1;
- bp++;
- copy_v3_v3(bezt->vec[1], bp->vec);
- bezt->f2 = bp->f1;
- bp++;
- copy_v3_v3(bezt->vec[2], bp->vec);
- bezt->f3 = bp->f1;
- bezt->radius = bp->radius;
- bezt->weight = bp->weight;
- bp++;
- bezt++;
- }
- MEM_freeN(nu->bp);
- nu->bp = NULL;
- MEM_freeN(nu->knotsu);
- nu->knotsu = NULL;
- nu->pntsu = nr;
- nu->type = CU_BEZIER;
+
+ bezt = MEM_calloc_arrayN(nr, sizeof(BezTriple), "setsplinetype2");
+ nu->bezt = bezt;
+ a = nr;
+ bp = nu->bp;
+ while (a--) {
+ copy_v3_v3(bezt->vec[0], bp->vec);
+ bezt->f1 = bp->f1;
+ bp++;
+ copy_v3_v3(bezt->vec[1], bp->vec);
+ bezt->f2 = bp->f1;
+ bp++;
+ copy_v3_v3(bezt->vec[2], bp->vec);
+ bezt->f3 = bp->f1;
+ bezt->radius = bp->radius;
+ bezt->weight = bp->weight;
+ bp++;
+ bezt++;
}
+ MEM_freeN(nu->bp);
+ nu->bp = NULL;
+ MEM_freeN(nu->knotsu);
+ nu->knotsu = NULL;
+ nu->pntsu = nr;
+ nu->type = CU_BEZIER;
}
}
@@ -5140,10 +4958,9 @@ int BKE_curve_nurb_vert_index_get(const Nurb *nu, const void *vert)
BLI_assert(ARRAY_HAS_ITEM((BezTriple *)vert, nu->bezt, nu->pntsu));
return (BezTriple *)vert - nu->bezt;
}
- else {
- BLI_assert(ARRAY_HAS_ITEM((BPoint *)vert, nu->bp, nu->pntsu * nu->pntsv));
- return (BPoint *)vert - nu->bp;
- }
+
+ BLI_assert(ARRAY_HAS_ITEM((BPoint *)vert, nu->bp, nu->pntsu * nu->pntsv));
+ return (BPoint *)vert - nu->bp;
}
/* Set active nurb and active vert for curve */
@@ -5293,8 +5110,11 @@ bool BKE_curve_center_bounds(Curve *cu, float cent[3])
return false;
}
-void BKE_curve_transform_ex(
- Curve *cu, float mat[4][4], const bool do_keys, const bool do_props, const float unit_scale)
+void BKE_curve_transform_ex(Curve *cu,
+ const float mat[4][4],
+ const bool do_keys,
+ const bool do_props,
+ const float unit_scale)
{
Nurb *nu;
BPoint *bp;
@@ -5357,13 +5177,13 @@ void BKE_curve_transform_ex(
}
}
-void BKE_curve_transform(Curve *cu, float mat[4][4], const bool do_keys, const bool do_props)
+void BKE_curve_transform(Curve *cu, const float mat[4][4], const bool do_keys, const bool do_props)
{
float unit_scale = mat4_to_scale(mat);
BKE_curve_transform_ex(cu, mat, do_keys, do_props, unit_scale);
}
-void BKE_curve_translate(Curve *cu, float offset[3], const bool do_keys)
+void BKE_curve_translate(Curve *cu, const float offset[3], const bool do_keys)
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
Nurb *nu;
@@ -5422,7 +5242,7 @@ void BKE_curve_material_index_remove(Curve *cu, int index)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
if (info->mat_nr && info->mat_nr >= index) {
info->mat_nr--;
}
@@ -5446,7 +5266,7 @@ bool BKE_curve_material_index_used(Curve *cu, int index)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
if (info->mat_nr == index) {
return true;
}
@@ -5472,7 +5292,7 @@ void BKE_curve_material_index_clear(Curve *cu)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
info->mat_nr = 0;
}
}
@@ -5494,7 +5314,7 @@ bool BKE_curve_material_index_validate(Curve *cu)
CharInfo *info = cu->strinfo;
const int max_idx = max_ii(0, cu->totcol); /* OB_FONT use 1 as first mat index, not 0!!! */
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
if (info->mat_nr > max_idx) {
info->mat_nr = 0;
is_valid = false;
@@ -5516,9 +5336,7 @@ bool BKE_curve_material_index_validate(Curve *cu)
DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
return true;
}
- else {
- return false;
- }
+ return false;
}
void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int remap_len)
@@ -5544,7 +5362,7 @@ void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int
}
else {
strinfo = cu->strinfo;
- charinfo_len = cu->len_wchar;
+ charinfo_len = cu->len_char32;
}
for (i = 0; i <= charinfo_len; i++) {
diff --git a/source/blender/blenkernel/intern/curve_bevel.c b/source/blender/blenkernel/intern/curve_bevel.c
new file mode 100644
index 00000000000..7f23f0215cc
--- /dev/null
+++ b/source/blender/blenkernel/intern/curve_bevel.c
@@ -0,0 +1,272 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bke
+ *
+ * Handle curve object data bevel options,
+ * both extruding
+ */
+
+#include <string.h>
+
+#include "BLI_listbase.h"
+#include "BLI_math_base.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_curve.h"
+#include "BKE_displist.h"
+
+typedef enum CurveBevelFillType {
+ BACK = 0,
+ FRONT,
+ HALF,
+ FULL,
+} CurveBevelFillType;
+
+static CurveBevelFillType curve_bevel_get_fill_type(const Curve *curve)
+{
+ if (!(curve->flag & (CU_FRONT | CU_BACK))) {
+ return FULL;
+ }
+ if ((curve->flag & CU_FRONT) && (curve->flag & CU_BACK)) {
+ return HALF;
+ }
+
+ return (curve->flag & CU_FRONT) ? FRONT : BACK;
+}
+
+static void curve_bevel_make_extrude_and_fill(Curve *cu,
+ ListBase *disp,
+ const bool use_extrude,
+ const CurveBevelFillType fill_type)
+{
+ DispList *dl = MEM_callocN(sizeof(DispList), __func__);
+
+ int nr;
+ if (fill_type == FULL) {
+ /* The full loop. */
+ nr = 4 * cu->bevresol + 6;
+ dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
+ }
+ else if (fill_type == HALF) {
+ /* Half the loop. */
+ nr = 2 * (cu->bevresol + 1) + (use_extrude ? 2 : 1);
+ dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
+ }
+ else {
+ /* One quarter of the loop (just front or back). */
+ nr = use_extrude ? cu->bevresol + 3 : cu->bevresol + 2;
+ dl->flag = (fill_type == FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE;
+ }
+
+ dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__);
+ BLI_addtail(disp, dl);
+ /* Use a different type depending on whether the loop is complete or not. */
+ dl->type = (fill_type == FULL) ? DL_POLY : DL_SEGM;
+ dl->parts = 1;
+ dl->nr = nr;
+
+ float *fp = dl->verts;
+ const float dangle = (float)M_PI_2 / (cu->bevresol + 1);
+ float angle = 0.0f;
+
+ /* Build the back section. */
+ if (ELEM(fill_type, BACK, HALF, FULL)) {
+ angle = (float)M_PI_2 * 3.0f;
+ for (int i = 0; i < cu->bevresol + 2; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+ if (use_extrude && fill_type == BACK) {
+ /* Add the extrusion if we're only building the back. */
+ fp[0] = 0.0f;
+ fp[1] = cu->ext2;
+ fp[2] = cu->ext1;
+ }
+ }
+
+ /* Build the front section. */
+ if (ELEM(fill_type, FRONT, HALF, FULL)) {
+ if (use_extrude && fill_type == FRONT) {
+ /* Add the extrusion if we're only building the front. */
+ fp[0] = 0.0f;
+ fp[1] = cu->ext2;
+ fp[2] = -cu->ext1;
+ fp += 3;
+ }
+ /* Don't duplicate the last back vertex. */
+ angle = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? dangle : 0;
+ int front_len = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? cu->bevresol + 1 :
+ cu->bevresol + 2;
+ for (int i = 0; i < front_len; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+ }
+
+ /* Build the other half only if we're building the full loop. */
+ if (fill_type == FULL) {
+ for (int i = 0; i < cu->bevresol + 1; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+
+ angle = (float)M_PI;
+ for (int i = 0; i < cu->bevresol + 1; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+ }
+}
+
+static void curve_bevel_make_full_circle(Curve *cu, ListBase *disp)
+{
+ const int nr = 4 + 2 * cu->bevresol;
+
+ DispList *dl = MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__);
+ BLI_addtail(disp, dl);
+ dl->type = DL_POLY;
+ dl->parts = 1;
+ dl->flag = DL_BACK_CURVE;
+ dl->nr = nr;
+
+ float *fp = dl->verts;
+ const float dangle = (2.0f * (float)M_PI / (nr));
+ float angle = -(nr - 1) * dangle;
+
+ for (int i = 0; i < nr; i++) {
+ fp[0] = 0.0;
+ fp[1] = (cosf(angle) * (cu->ext2));
+ fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+}
+
+static void curve_bevel_make_only_extrude(Curve *cu, ListBase *disp)
+{
+ DispList *dl = MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), __func__);
+ BLI_addtail(disp, dl);
+ dl->type = DL_SEGM;
+ dl->parts = 1;
+ dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
+ dl->nr = 2;
+
+ float *fp = dl->verts;
+ fp[0] = fp[1] = 0.0;
+ fp[2] = -cu->ext1;
+ fp[3] = fp[4] = 0.0;
+ fp[5] = cu->ext1;
+}
+
+static void curve_bevel_make_from_object(Curve *cu, ListBase *disp)
+{
+ if (cu->bevobj->type != OB_CURVE) {
+ return;
+ }
+
+ Curve *bevcu = cu->bevobj->data;
+ if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) {
+ ListBase bevdisp = {NULL, NULL};
+ float facx = cu->bevobj->scale[0];
+ float facy = cu->bevobj->scale[1];
+
+ DispList *dl;
+ if (cu->bevobj->runtime.curve_cache) {
+ dl = cu->bevobj->runtime.curve_cache->disp.first;
+ }
+ else {
+ BLI_assert(cu->bevobj->runtime.curve_cache != NULL);
+ dl = NULL;
+ }
+
+ while (dl) {
+ if (ELEM(dl->type, DL_POLY, DL_SEGM)) {
+ DispList *dlnew = MEM_mallocN(sizeof(DispList), __func__);
+ *dlnew = *dl;
+ dlnew->verts = MEM_malloc_arrayN(dl->parts * dl->nr, 3 * sizeof(float), __func__);
+ memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr);
+
+ if (dlnew->type == DL_SEGM) {
+ dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE);
+ }
+
+ BLI_addtail(disp, dlnew);
+ float *fp = dlnew->verts;
+ int nr = dlnew->parts * dlnew->nr;
+ while (nr--) {
+ fp[2] = fp[1] * facy;
+ fp[1] = -fp[0] * facx;
+ fp[0] = 0.0;
+ fp += 3;
+ }
+ }
+ dl = dl->next;
+ }
+
+ BKE_displist_free(&bevdisp);
+ }
+}
+
+void BKE_curve_bevel_make(Object *ob, ListBase *disp)
+{
+ Curve *curve = ob->data;
+
+ const bool use_extrude = curve->ext1 != 0.0f;
+ const bool use_bevel = curve->ext2 != 0.0f;
+
+ BLI_listbase_clear(disp);
+
+ if (curve->bevobj) {
+ curve_bevel_make_from_object(curve, disp);
+ }
+ else if (!(use_extrude || use_bevel)) {
+ /* Pass. */
+ }
+ else if (use_extrude && !use_bevel) {
+ curve_bevel_make_only_extrude(curve, disp);
+ }
+ else {
+ CurveBevelFillType fill_type = curve_bevel_get_fill_type(curve);
+
+ if (!use_extrude && fill_type == FULL) {
+ curve_bevel_make_full_circle(curve, disp);
+ }
+ else {
+ /* The general case for nonzero extrusion or an incomplete loop. */
+ curve_bevel_make_extrude_and_fill(curve, disp, use_extrude, fill_type);
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/curveprofile.c b/source/blender/blenkernel/intern/curveprofile.c
index 6919d4fa10f..0a41529aac1 100644
--- a/source/blender/blenkernel/intern/curveprofile.c
+++ b/source/blender/blenkernel/intern/curveprofile.c
@@ -886,7 +886,7 @@ void BKE_curveprofile_create_samples(CurveProfile *profile,
*/
static void curveprofile_make_table(CurveProfile *profile)
{
- int n_samples = PROF_N_TABLE(profile->path_len);
+ int n_samples = PROF_TABLE_LEN(profile->path_len);
CurveProfilePoint *new_table = MEM_callocN(sizeof(CurveProfilePoint) * (n_samples + 1),
"high-res table");
@@ -1040,7 +1040,7 @@ void BKE_curveprofile_update(CurveProfile *profile, const int update_flags)
* Also sets the number of segments used for the display preview of the locations
* of the sampled points.
*/
-void BKE_curveprofile_initialize(CurveProfile *profile, short segments_len)
+void BKE_curveprofile_init(CurveProfile *profile, short segments_len)
{
if (segments_len != profile->segments_len) {
profile->flag |= PROF_DIRTY_PRESET;
@@ -1055,11 +1055,11 @@ void BKE_curveprofile_initialize(CurveProfile *profile, short segments_len)
* Gives the distance to the next point in the widgets sampled table, in other words the length
* of the \a 'i' edge of the table.
*
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
*/
static float curveprofile_distance_to_next_table_point(const CurveProfile *profile, int i)
{
- BLI_assert(i < PROF_N_TABLE(profile->path_len));
+ BLI_assert(i < PROF_TABLE_LEN(profile->path_len));
return len_v2v2(&profile->table[i].x, &profile->table[i + 1].x);
}
@@ -1067,12 +1067,12 @@ static float curveprofile_distance_to_next_table_point(const CurveProfile *profi
/**
* Calculates the total length of the profile from the curves sampled in the table.
*
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
*/
float BKE_curveprofile_total_length(const CurveProfile *profile)
{
float total_length = 0;
- for (int i = 0; i < PROF_N_TABLE(profile->path_len) - 1; i++) {
+ for (int i = 0; i < PROF_TABLE_LEN(profile->path_len) - 1; i++) {
total_length += len_v2v2(&profile->table[i].x, &profile->table[i + 1].x);
}
return total_length;
@@ -1082,7 +1082,7 @@ float BKE_curveprofile_total_length(const CurveProfile *profile)
* Samples evenly spaced positions along the curve profile's table (generated from path). Fills
* an entire table at once for a speedup if all of the results are going to be used anyway.
*
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
* \note Working, but would conflict with "Sample Straight Edges" option, so this is unused for
* now.
*/
@@ -1145,7 +1145,7 @@ void BKE_curveprofile_create_samples_even_spacing(CurveProfile *profile,
* Travels down (length_portion * path) length and returns the position at that point.
*
* \param length_portion: The portion (0 to 1) of the path's full length to sample at.
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
*/
void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile,
float length_portion,
@@ -1160,7 +1160,7 @@ void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile,
float length_travelled = 0.0f;
while (length_travelled < requested_length) {
/* Check if we reached the last point before the final one. */
- if (i == PROF_N_TABLE(profile->path_len) - 2) {
+ if (i == PROF_TABLE_LEN(profile->path_len) - 2) {
break;
}
float new_length = curveprofile_distance_to_next_table_point(profile, i);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 2be61239ac6..7ddb0a6862d 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -300,7 +300,7 @@ static void layerInterp_mdeformvert(const void **sources,
/* now we know how many unique deform weights there are, so realloc */
if (dvert->dw && (dvert->totweight == totweight)) {
- /* pass (fastpath if we don't need to realloc) */
+ /* pass (fast-path if we don't need to realloc). */
}
else {
if (dvert->dw) {
@@ -1464,6 +1464,102 @@ static int layerMaxNum_propcol(void)
return MAX_MCOL;
}
+static void layerInterp_propfloat3(
+ const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+{
+ vec3f result = {0.0f, 0.0f, 0.0f};
+ for (int i = 0; i < count; i++) {
+ float weight = weights ? weights[i] : 1.0f;
+ const vec3f *src = sources[i];
+ if (sub_weights) {
+ madd_v3_v3fl(&result.x, &src->x, sub_weights[i] * weight);
+ }
+ else {
+ madd_v3_v3fl(&result.x, &src->x, weight);
+ }
+ }
+ copy_v3_v3((float *)dest, &result.x);
+}
+
+static void layerMultiply_propfloat3(void *data, float fac)
+{
+ vec3f *vec = data;
+ vec->x *= fac;
+ vec->y *= fac;
+ vec->z *= fac;
+}
+
+static void layerAdd_propfloat3(void *data1, const void *data2)
+{
+ vec3f *vec1 = data1;
+ const vec3f *vec2 = data2;
+ vec1->x += vec2->x;
+ vec1->y += vec2->y;
+ vec1->z += vec2->z;
+}
+
+static bool layerValidate_propfloat3(void *data, const uint totitems, const bool do_fixes)
+{
+ float *values = data;
+ bool has_errors = false;
+ for (int i = 0; i < totitems * 3; i++) {
+ if (!isfinite(values[i])) {
+ if (do_fixes) {
+ values[i] = 0.0f;
+ }
+ has_errors = true;
+ }
+ }
+ return has_errors;
+}
+
+static void layerInterp_propfloat2(
+ const void **sources, const float *weights, const float *sub_weights, int count, void *dest)
+{
+ vec2f result = {0.0f, 0.0f};
+ for (int i = 0; i < count; i++) {
+ float weight = weights ? weights[i] : 1.0f;
+ const vec2f *src = sources[i];
+ if (sub_weights) {
+ madd_v2_v2fl(&result.x, &src->x, sub_weights[i] * weight);
+ }
+ else {
+ madd_v2_v2fl(&result.x, &src->x, weight);
+ }
+ }
+ copy_v2_v2((float *)dest, &result.x);
+}
+
+static void layerMultiply_propfloat2(void *data, float fac)
+{
+ vec2f *vec = data;
+ vec->x *= fac;
+ vec->y *= fac;
+}
+
+static void layerAdd_propfloat2(void *data1, const void *data2)
+{
+ vec2f *vec1 = data1;
+ const vec2f *vec2 = data2;
+ vec1->x += vec2->x;
+ vec1->y += vec2->y;
+}
+
+static bool layerValidate_propfloat2(void *data, const uint totitems, const bool do_fixes)
+{
+ float *values = data;
+ bool has_errors = false;
+ for (int i = 0; i < totitems * 2; i++) {
+ if (!isfinite(values[i])) {
+ if (do_fixes) {
+ values[i] = 0.0f;
+ }
+ has_errors = true;
+ }
+ }
+ return has_errors;
+}
+
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 0: CD_MVERT */
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
@@ -1799,7 +1895,38 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
NULL,
NULL,
NULL,
- layerMaxNum_propcol}};
+ layerMaxNum_propcol},
+ /* 48: CD_PROP_FLOAT3 */
+ {sizeof(float[3]),
+ "vec3f",
+ 1,
+ N_("Float3"),
+ NULL,
+ NULL,
+ layerInterp_propfloat3,
+ NULL,
+ NULL,
+ layerValidate_propfloat3,
+ NULL,
+ layerMultiply_propfloat3,
+ NULL,
+ layerAdd_propfloat3},
+ /* 49: CD_PROP_FLOAT2 */
+ {sizeof(float[2]),
+ "vec2f",
+ 1,
+ N_("Float2"),
+ NULL,
+ NULL,
+ layerInterp_propfloat2,
+ NULL,
+ NULL,
+ layerValidate_propfloat2,
+ NULL,
+ layerMultiply_propfloat2,
+ NULL,
+ layerAdd_propfloat2},
+};
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* 0-4 */ "CDMVert",
@@ -1852,6 +1979,8 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDHairMapping",
"CDPoint",
"CDPropCol",
+ "CDPropFloat3",
+ "CDPropFloat2",
};
const CustomData_MeshMasks CD_MASK_BAREMESH = {
@@ -2514,11 +2643,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
}
if (alloctype == CD_DUPLICATE && layerdata) {
- if (typeInfo->copy) {
- typeInfo->copy(layerdata, newlayerdata, totelem);
- }
- else {
- memcpy(newlayerdata, layerdata, (size_t)totelem * typeInfo->size);
+ if (totelem > 0) {
+ if (typeInfo->copy) {
+ typeInfo->copy(layerdata, newlayerdata, totelem);
+ }
+ else {
+ memcpy(newlayerdata, layerdata, (size_t)totelem * typeInfo->size);
+ }
}
}
else if (alloctype == CD_DEFAULT) {
@@ -4440,6 +4571,32 @@ bool CustomData_layer_validate(CustomDataLayer *layer, const uint totitems, cons
return false;
}
+void CustomData_layers__print(CustomData *data)
+{
+ int i;
+ const CustomDataLayer *layer;
+
+ printf("{\n");
+
+ for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) {
+
+ const char *name = CustomData_layertype_name(layer->type);
+ const int size = CustomData_sizeof(layer->type);
+ const char *structname;
+ int structnum;
+ CustomData_file_write_info(layer->type, &structname, &structnum);
+ printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
+ name,
+ structname,
+ layer->type,
+ (const void *)layer->data,
+ size,
+ (int)(MEM_allocN_len(layer->data) / size));
+ }
+
+ printf("}\n");
+}
+
/****************************** External Files *******************************/
static void customdata_external_filename(char filename[FILE_MAX],
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 48e0ee50d43..7bf87d0e639 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -43,6 +43,7 @@
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_mesh_runtime.h"
+#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
@@ -562,7 +563,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map
CustomData *cd_dst,
const bool use_dupref_dst,
const int tolayers,
- bool *use_layers_src,
+ const bool *use_layers_src,
const int num_layers_src,
cd_datatransfer_interp interp,
void *interp_data)
@@ -1467,6 +1468,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
if (!me_src) {
return changed;
}
+ BKE_mesh_wrapper_ensure_mdata(me_src);
if (auto_transform) {
if (space_transform == NULL) {
diff --git a/source/blender/blenkernel/intern/data_transfer_intern.h b/source/blender/blenkernel/intern/data_transfer_intern.h
index 68ded6e2bc4..c5d7dd42cb8 100644
--- a/source/blender/blenkernel/intern/data_transfer_intern.h
+++ b/source/blender/blenkernel/intern/data_transfer_intern.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __DATA_TRANSFER_INTERN_H__
-#define __DATA_TRANSFER_INTERN_H__
+#pragma once
#include "BKE_customdata.h" /* For cd_datatransfer_interp */
@@ -75,5 +74,3 @@ void customdata_data_transfer_interp_normal_normals(const CustomDataTransferLaye
const float *weights,
const int count,
const float mix_factor);
-
-#endif /* __DATA_TRANSFER_INTERN_H__ */
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index b97935d57f2..98fc5f9a23a 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -249,7 +249,7 @@ void BKE_defvert_sync_mapped(MDeformVert *dvert_dst,
/**
* be sure all flip_map values are valid
*/
-void BKE_defvert_remap(MDeformVert *dvert, int *map, const int map_len)
+void BKE_defvert_remap(MDeformVert *dvert, const int *map, const int map_len)
{
MDeformWeight *dw = dvert->dw;
unsigned int i;
@@ -1184,7 +1184,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
CustomData *cd_dst,
const bool UNUSED(use_dupref_dst),
const int tolayers,
- bool *use_layers_src,
+ const bool *use_layers_src,
const int num_layers_src)
{
int idx_src;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 2e1fa519284..7b7b7ceb84b 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -588,7 +588,7 @@ static bool boundsIntersectDist(Bounds3D *b1, Bounds3D *b2, const float dist)
}
/* check whether bounds intersects a point with given radius */
-static bool boundIntersectPoint(Bounds3D *b, float point[3], const float radius)
+static bool boundIntersectPoint(Bounds3D *b, const float point[3], const float radius)
{
if (!b->valid) {
return false;
@@ -4203,7 +4203,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
brushVelocity[v3].v,
weights);
- /* substract canvas point velocity */
+ /* subtract canvas point velocity */
if (bData->velocity) {
sub_v3_v3v3(velocity, brushPointVelocity, bData->velocity[index].v);
}
@@ -4548,7 +4548,7 @@ static void dynamic_paint_paint_particle_cell_point_cb_ex(
ParticleData *pa = psys->particles + part_index;
mul_v3_v3fl(velocity, pa->state.vel, particle_timestep);
- /* substract canvas point velocity */
+ /* subtract canvas point velocity */
if (bData->velocity) {
sub_v3_v3(velocity, bData->velocity[index].v);
}
@@ -4739,7 +4739,7 @@ static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata,
if (brush->flags & MOD_DPAINT_USES_VELOCITY) {
float velocity[3];
- /* substract canvas point velocity */
+ /* subtract canvas point velocity */
if (bData->velocity) {
sub_v3_v3v3(velocity, brushVelocity->v, bData->velocity[index].v);
}
@@ -4780,13 +4780,16 @@ static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata,
}
}
-static int dynamicPaint_paintSinglePoint(Depsgraph *depsgraph,
- DynamicPaintSurface *surface,
- float *pointCoord,
- DynamicPaintBrushSettings *brush,
- Object *brushOb,
- Scene *scene,
- float timescale)
+static int dynamicPaint_paintSinglePoint(
+ Depsgraph *depsgraph,
+ DynamicPaintSurface *surface,
+ /* Cannot be const, because it is assigned to non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ float *pointCoord,
+ DynamicPaintBrushSettings *brush,
+ Object *brushOb,
+ Scene *scene,
+ float timescale)
{
PaintSurfaceData *sData = surface->data;
float brush_radius = brush->paint_distance * surface->radius_scale;
@@ -5456,11 +5459,14 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata,
}
}
-static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface,
- float *force,
- PaintPoint *prevPoint,
- float timescale,
- float steps)
+static void dynamicPaint_doEffectStep(
+ DynamicPaintSurface *surface,
+ /* Cannot be const, because it is assigned to non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ float *force,
+ PaintPoint *prevPoint,
+ float timescale,
+ float steps)
{
PaintSurfaceData *sData = surface->data;
diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c
index 6fcaf84d4ca..897fc7e692b 100644
--- a/source/blender/blenkernel/intern/editmesh_tangent.c
+++ b/source/blender/blenkernel/intern/editmesh_tangent.c
@@ -274,8 +274,8 @@ static void emDM_calc_loop_tangents_thread(TaskPool *__restrict UNUSED(pool), vo
/**
* \see #BKE_mesh_calc_loop_tangent, same logic but used arrays instead of #BMesh data.
*
- * \note This function is not so normal, its using `bm->ldata` as input,
- * but output's to `dm->loopData`.
+ * \note This function is not so normal, its using #BMesh.ldata as input,
+ * but output's to #Mesh.ldata.
* This is done because #CD_TANGENT is cache data used only for drawing.
*/
void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 235c834fde9..a43553ee89f 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -1094,11 +1094,11 @@ void BKE_effectors_apply(ListBase *effectors,
* Modifies the force on a particle according to its
* relation with the effector object
* Different kind of effectors include:
- * Forcefields: Gravity-like attractor
+ * Force-fields: Gravity-like attractor
* (force power is related to the inverse of distance to the power of a falloff value)
* Vortex fields: swirling effectors
* (particles rotate around Z-axis of the object. otherwise, same relation as)
- * (Forcefields, but this is not done through a force/acceleration)
+ * (Force-fields, but this is not done through a force/acceleration)
* Guide: particles on a path
* (particles are guided along a curve bezier or old nurbs)
* (is independent of other effectors)
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index bc14f525c2c..acbbf50701a 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1277,7 +1277,7 @@ short test_time_fcurve(FCurve *fcu)
* than the horizontal distance between (v1-v4).
* This is to prevent curve loops.
*/
-void correct_bezpart(float v1[2], float v2[2], float v3[2], float v4[2])
+void correct_bezpart(const float v1[2], float v2[2], float v3[2], const float v4[2])
{
float h1[2], h2[2], len1, len2, len, fac;
@@ -1872,17 +1872,18 @@ float evaluate_fcurve_only_curve(FCurve *fcu, float evaltime)
float evaluate_fcurve_driver(PathResolvedRNA *anim_rna,
FCurve *fcu,
ChannelDriver *driver_orig,
- float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
BLI_assert(fcu->driver != NULL);
float cvalue = 0.0f;
+ float evaltime = anim_eval_context->eval_time;
/* If there is a driver (only if this F-Curve is acting as 'driver'),
* evaluate it to find value to use as "evaltime" since drivers essentially act as alternative
* input (i.e. in place of 'time') for F-Curves. */
if (fcu->driver) {
/* evaltime now serves as input for the curve */
- evaltime = evaluate_driver(anim_rna, fcu->driver, driver_orig, evaltime);
+ evaltime = evaluate_driver(anim_rna, fcu->driver, driver_orig, anim_eval_context);
/* only do a default 1-1 mapping if it's unlikely that anything else will set a value... */
if (fcu->totvert == 0) {
@@ -1924,7 +1925,9 @@ bool BKE_fcurve_is_empty(FCurve *fcu)
}
/* Calculate the value of the given F-Curve at the given frame, and set its curval */
-float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime)
+float calculate_fcurve(PathResolvedRNA *anim_rna,
+ FCurve *fcu,
+ const AnimationEvalContext *anim_eval_context)
{
/* only calculate + set curval (overriding the existing value) if curve has
* any data which warrants this...
@@ -1936,10 +1939,10 @@ float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime)
/* calculate and set curval (evaluates driver too if necessary) */
float curval;
if (fcu->driver) {
- curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, evaltime);
+ curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, anim_eval_context);
}
else {
- curval = evaluate_fcurve(fcu, evaltime);
+ curval = evaluate_fcurve(fcu, anim_eval_context->eval_time);
}
fcu->curval = curval; /* debug display only, not thread safe! */
return curval;
diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c
index a0625918a62..87cb77930f5 100644
--- a/source/blender/blenkernel/intern/fcurve_driver.c
+++ b/source/blender/blenkernel/intern/fcurve_driver.c
@@ -21,12 +21,6 @@
* \ingroup bke
*/
-// #include <float.h>
-// #include <math.h>
-// #include <stddef.h>
-// #include <stdio.h>
-// #include <string.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
@@ -43,6 +37,7 @@
#include "BLT_translation.h"
#include "BKE_action.h"
+#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_fcurve_driver.h"
@@ -65,17 +60,19 @@ static ThreadMutex python_driver_lock = BLI_MUTEX_INITIALIZER;
static CLG_LogRef LOG = {"bke.fcurve"};
-/* Driver Variables --------------------------- */
+/* -------------------------------------------------------------------- */
+/** \name Driver Variables
+ * \{ */
/* TypeInfo for Driver Variables (dvti) */
typedef struct DriverVarTypeInfo {
- /* evaluation callback */
+ /* Evaluation callback. */
float (*get_value)(ChannelDriver *driver, DriverVar *dvar);
- /* allocation of target slots */
- int num_targets; /* number of target slots required */
- const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots */
- short target_flags[MAX_DRIVER_TARGETS]; /* flags defining the requirements for each slot */
+ /* Allocation of target slots. */
+ int num_targets; /* Number of target slots required. */
+ const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots. */
+ short target_flags[MAX_DRIVER_TARGETS]; /* Flags defining the requirements for each slot. */
} DriverVarTypeInfo;
/* Macro to begin definitions */
@@ -84,7 +81,11 @@ typedef struct DriverVarTypeInfo {
/* Macro to end definitions */
#define END_DVAR_TYPEDEF }
-/* ......... */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Target Utilities
+ * \{ */
static ID *dtar_id_ensure_proxy_from(ID *id)
{
@@ -106,14 +107,14 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
int index = -1;
float value = 0.0f;
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, driver, dtar)) {
return 0.0f;
}
id = dtar_id_ensure_proxy_from(dtar->id);
- /* error check for missing pointer... */
+ /* Error check for missing pointer. */
if (id == NULL) {
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path);
@@ -124,12 +125,12 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
return 0.0f;
}
- /* get RNA-pointer for the ID-block given in target */
+ /* Get RNA-pointer for the ID-block given in target. */
RNA_id_pointer_create(id, &id_ptr);
- /* get property to read from, and get value as appropriate */
+ /* Get property to read from, and get value as appropriate. */
if (!RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
- /* path couldn't be resolved */
+ /* Path couldn't be resolved. */
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
"Driver Evaluation Error: cannot resolve target for %s -> %s",
@@ -143,9 +144,9 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
}
if (RNA_property_array_check(prop)) {
- /* array */
+ /* Array. */
if (index < 0 || index >= RNA_property_array_length(&ptr, prop)) {
- /* out of bounds */
+ /* Out of bounds. */
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
"Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)",
@@ -174,7 +175,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
}
}
else {
- /* not an array */
+ /* Not an array. */
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
value = (float)RNA_property_boolean_get(&ptr, prop);
@@ -193,7 +194,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
}
}
- /* if we're still here, we should be ok... */
+ /* If we're still here, we should be ok. */
dtar->flag &= ~DTAR_FLAG_INVALID;
return value;
}
@@ -213,14 +214,14 @@ bool driver_get_variable_property(ChannelDriver *driver,
ID *id;
int index = -1;
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, driver, dtar)) {
return false;
}
id = dtar_id_ensure_proxy_from(dtar->id);
- /* error check for missing pointer... */
+ /* Error check for missing pointer. */
if (id == NULL) {
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path);
@@ -231,19 +232,19 @@ bool driver_get_variable_property(ChannelDriver *driver,
return false;
}
- /* get RNA-pointer for the ID-block given in target */
+ /* Get RNA-pointer for the ID-block given in target. */
RNA_id_pointer_create(id, &id_ptr);
- /* get property to read from, and get value as appropriate */
+ /* Get property to read from, and get value as appropriate. */
if (dtar->rna_path == NULL || dtar->rna_path[0] == '\0') {
ptr = PointerRNA_NULL;
- prop = NULL; /* ok */
+ prop = NULL; /* OK. */
}
else if (RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
- /* ok */
+ /* OK. */
}
else {
- /* path couldn't be resolved */
+ /* Path couldn't be resolved. */
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
"Driver Evaluation Error: cannot resolve target for %s -> %s",
@@ -264,7 +265,7 @@ bool driver_get_variable_property(ChannelDriver *driver,
*r_prop = prop;
*r_index = index;
- /* if we're still here, we should be ok... */
+ /* If we're still here, we should be ok. */
dtar->flag &= ~DTAR_FLAG_INVALID;
return true;
}
@@ -276,14 +277,14 @@ static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar)
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
- /* check if this target has valid data */
+ /* Check if this target has valid data. */
if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
- /* invalid target, so will not have enough targets */
+ /* Invalid target, so will not have enough targets. */
driver->flag |= DRIVER_FLAG_INVALID;
dtar->flag |= DTAR_FLAG_INVALID;
}
else {
- /* target seems to be OK now... */
+ /* Target seems to be OK now. */
dtar->flag &= ~DTAR_FLAG_INVALID;
valid_targets++;
}
@@ -293,21 +294,25 @@ static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar)
return valid_targets;
}
-/* ......... */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Variable Utilities
+ * \{ */
-/* evaluate 'single prop' driver variable */
+/* Evaluate 'single prop' driver variable. */
static float dvar_eval_singleProp(ChannelDriver *driver, DriverVar *dvar)
{
- /* just evaluate the first target slot */
+ /* Just evaluate the first target slot. */
return dtar_get_prop_val(driver, &dvar->targets[0]);
}
-/* evaluate 'rotation difference' driver variable */
+/* Evaluate 'rotation difference' driver variable. */
static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
{
short valid_targets = driver_check_valid_targets(driver, dvar);
- /* make sure we have enough valid targets to use - all or nothing for now... */
+ /* Make sure we have enough valid targets to use - all or nothing for now. */
if (driver_check_valid_targets(driver, dvar) != 2) {
if (G.debug & G_DEBUG) {
CLOG_WARN(&LOG,
@@ -323,31 +328,31 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
/* NOTE: for now, these are all just worldspace */
for (int i = 0; i < 2; i++) {
- /* get pointer to loc values to store in */
+ /* Get pointer to loc values to store in. */
DriverTarget *dtar = &dvar->targets[i];
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
- /* after the checks above, the targets should be valid here... */
+ /* After the checks above, the targets should be valid here. */
BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB));
- /* try to get posechannel */
+ /* Try to get pose-channel. */
pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
- /* check if object or bone */
+ /* Check if object or bone. */
if (pchan) {
- /* bone */
+ /* Bone. */
mat[i] = pchan->pose_mat;
}
else {
- /* object */
+ /* Object. */
mat[i] = ob->obmat;
}
}
float q1[4], q2[4], quat[4], angle;
- /* use the final posed locations */
+ /* Use the final posed locations. */
mat4_to_quat(q1, mat[0]);
mat4_to_quat(q2, mat[1]);
@@ -359,15 +364,18 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
return (angle > (float)M_PI) ? (float)((2.0f * (float)M_PI) - angle) : (float)(angle);
}
-/* evaluate 'location difference' driver variable */
-/* TODO: this needs to take into account space conversions... */
+/**
+ * Evaluate 'location difference' driver variable.
+ *
+ * TODO: this needs to take into account space conversions.
+ */
static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
{
float loc1[3] = {0.0f, 0.0f, 0.0f};
float loc2[3] = {0.0f, 0.0f, 0.0f};
short valid_targets = driver_check_valid_targets(driver, dvar);
- /* make sure we have enough valid targets to use - all or nothing for now... */
+ /* Make sure we have enough valid targets to use - all or nothing for now. */
if (valid_targets < dvar->num_targets) {
if (G.debug & G_DEBUG) {
CLOG_WARN(&LOG,
@@ -380,72 +388,72 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
}
/* SECOND PASS: get two location values */
- /* NOTE: for now, these are all just worldspace */
+ /* NOTE: for now, these are all just world-space */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
- /* get pointer to loc values to store in */
+ /* Get pointer to loc values to store in. */
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
float tmp_loc[3];
- /* after the checks above, the targets should be valid here... */
+ /* After the checks above, the targets should be valid here. */
BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB));
- /* try to get posechannel */
+ /* Try to get pose-channel. */
pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
- /* check if object or bone */
+ /* Check if object or bone. */
if (pchan) {
- /* bone */
+ /* Bone. */
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
float mat[4][4];
- /* extract transform just like how the constraints do it! */
+ /* Extract transform just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
BKE_constraint_mat_convertspace(
ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
- /* ... and from that, we get our transform */
+ /* ... and from that, we get our transform. */
copy_v3_v3(tmp_loc, mat[3]);
}
else {
- /* transform space (use transform values directly) */
+ /* Transform space (use transform values directly). */
copy_v3_v3(tmp_loc, pchan->loc);
}
}
else {
- /* convert to worldspace */
+ /* Convert to worldspace. */
copy_v3_v3(tmp_loc, pchan->pose_head);
mul_m4_v3(ob->obmat, tmp_loc);
}
}
else {
- /* object */
+ /* Object. */
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
- /* XXX: this should practically be the same as transform space... */
+ /* XXX: this should practically be the same as transform space. */
float mat[4][4];
- /* extract transform just like how the constraints do it! */
+ /* Extract transform just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
BKE_constraint_mat_convertspace(
ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
- /* ... and from that, we get our transform */
+ /* ... and from that, we get our transform. */
copy_v3_v3(tmp_loc, mat[3]);
}
else {
- /* transform space (use transform values directly) */
+ /* Transform space (use transform values directly). */
copy_v3_v3(tmp_loc, ob->loc);
}
}
else {
- /* worldspace */
+ /* World-space. */
copy_v3_v3(tmp_loc, ob->obmat[3]);
}
}
- /* copy the location to the right place */
+ /* Copy the location to the right place. */
if (tarIndex) {
copy_v3_v3(loc2, tmp_loc);
}
@@ -455,13 +463,14 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
}
DRIVER_TARGETS_LOOPER_END;
- /* if we're still here, there should now be two targets to use,
- * so just take the length of the vector between these points
- */
+ /* If we're still here, there should now be two targets to use,
+ * so just take the length of the vector between these points. */
return len_v3v3(loc1, loc2);
}
-/* evaluate 'transform channel' driver variable */
+/**
+ * Evaluate 'transform channel' driver variable.
+ */
static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
{
DriverTarget *dtar = &dvar->targets[0];
@@ -472,15 +481,15 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
bool use_eulers = false;
short rot_order = ROT_MODE_EUL;
- /* check if this target has valid data */
+ /* Check if this target has valid data. */
if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
- /* invalid target, so will not have enough targets */
+ /* Invalid target, so will not have enough targets. */
driver->flag |= DRIVER_FLAG_INVALID;
dtar->flag |= DTAR_FLAG_INVALID;
return 0.0f;
}
else {
- /* target should be valid now */
+ /* Target should be valid now. */
dtar->flag &= ~DTAR_FLAG_INVALID;
}
@@ -494,7 +503,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
* but #DTAR_FLAG_LOCAL_CONSTS is for all the common "corrective-shapes-for-limbs" situations.
*/
if (pchan) {
- /* bone */
+ /* Bone. */
if (pchan->rotmode > 0) {
copy_v3_v3(oldEul, pchan->eul);
rot_order = pchan->rotmode;
@@ -503,16 +512,15 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
- /* just like how the constraints do it! */
+ /* Just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
BKE_constraint_mat_convertspace(
ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
}
else {
- /* specially calculate local matrix, since chan_mat is not valid
+ /* Specially calculate local matrix, since chan_mat is not valid
* since it stores delta transform of pose_mat so that deforms work
- * so it cannot be used here for "transform" space
- */
+ * so it cannot be used here for "transform" space. */
BKE_pchan_to_mat4(pchan, mat);
}
}
@@ -522,7 +530,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
}
}
else {
- /* object */
+ /* Object. */
if (ob->rotmode > 0) {
copy_v3_v3(oldEul, ob->rot);
rot_order = ob->rotmode;
@@ -531,25 +539,25 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
- /* just like how the constraints do it! */
+ /* Just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
BKE_constraint_mat_convertspace(
ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
}
else {
- /* transforms to matrix */
+ /* Transforms to matrix. */
BKE_object_to_mat4(ob, mat);
}
}
else {
- /* worldspace matrix - just the good-old one */
+ /* World-space matrix - just the good-old one. */
copy_m4_m4(mat, ob->obmat);
}
}
- /* check which transform */
+ /* Check which transform. */
if (dtar->transChan >= MAX_DTAR_TRANSCHAN_TYPES) {
- /* not valid channel */
+ /* Not valid channel. */
return 0.0f;
}
else if (dtar->transChan == DTAR_TRANSCHAN_SCALE_AVG) {
@@ -566,7 +574,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
return len_v3(mat[dtar->transChan - DTAR_TRANSCHAN_SCALEX]);
}
else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
- /* extract rotation as eulers (if needed)
+ /* Extract rotation as eulers (if needed)
* - definitely if rotation order isn't eulers already
* - if eulers, then we have 2 options:
* a) decompose transform matrix as required, then try to make eulers from
@@ -595,7 +603,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
return quat[channel];
}
else {
- /* extract location and choose right axis */
+ /* Extract location and choose right axis. */
return mat[3][dtar->transChan];
}
}
@@ -665,41 +673,45 @@ void BKE_driver_target_matrix_to_rot_channels(
}
}
-/* ......... */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Variable Type Info
+ * \{ */
/* Table of Driver Variable Type Info Data */
static DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES] = {
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP) dvar_eval_singleProp, /* eval callback */
- 1, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP) dvar_eval_singleProp, /* Eval callback. */
+ 1, /* Number of targets used. */
{"Property"}, /* UI names for targets */
- {0} /* flags */
+ {0} /* Flags. */
END_DVAR_TYPEDEF,
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF) dvar_eval_rotDiff, /* eval callback */
- 2, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF) dvar_eval_rotDiff, /* Eval callback. */
+ 2, /* Number of targets used. */
{"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
{DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY,
- DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */
+ DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */
END_DVAR_TYPEDEF,
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF) dvar_eval_locDiff, /* eval callback */
- 2, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF) dvar_eval_locDiff, /* Eval callback. */
+ 2, /* Number of targets used. */
{"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
{DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY,
- DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */
+ DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */
END_DVAR_TYPEDEF,
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN) dvar_eval_transChan, /* eval callback */
- 1, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN) dvar_eval_transChan, /* Eval callback. */
+ 1, /* Number of targets used. */
{"Object/Bone"}, /* UI names for targets */
- {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */
+ {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */
END_DVAR_TYPEDEF,
};
/* Get driver variable typeinfo */
static const DriverVarTypeInfo *get_dvar_typeinfo(int type)
{
- /* check if valid type */
+ /* Check if valid type. */
if ((type >= 0) && (type < MAX_DVAR_TYPES)) {
return &dvar_types[type];
}
@@ -708,40 +720,44 @@ static const DriverVarTypeInfo *get_dvar_typeinfo(int type)
}
}
-/* Driver API --------------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver API
+ * \{ */
/* Perform actual freeing driver variable and remove it from the given list */
void driver_free_variable(ListBase *variables, DriverVar *dvar)
{
- /* sanity checks */
+ /* Sanity checks. */
if (dvar == NULL) {
return;
}
- /* free target vars
+ /* Free target vars:
* - need to go over all of them, not just up to the ones that are used
* currently, since there may be some lingering RNA paths from
* previous users needing freeing
*/
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
- /* free RNA path if applicable */
+ /* Free RNA path if applicable. */
if (dtar->rna_path) {
MEM_freeN(dtar->rna_path);
}
}
DRIVER_TARGETS_LOOPER_END;
- /* remove the variable from the driver */
+ /* Remove the variable from the driver. */
BLI_freelinkN(variables, dvar);
}
/* Free the driver variable and do extra updates */
void driver_free_variable_ex(ChannelDriver *driver, DriverVar *dvar)
{
- /* remove and free the driver variable */
+ /* Remove and free the driver variable. */
driver_free_variable(&driver->variables, dvar);
- /* since driver variables are cached, the expression needs re-compiling too */
+ /* Since driver variables are cached, the expression needs re-compiling too. */
BKE_driver_invalidate_expression(driver, false, true);
}
@@ -752,9 +768,9 @@ void driver_variables_copy(ListBase *dst_vars, const ListBase *src_vars)
BLI_duplicatelist(dst_vars, src_vars);
LISTBASE_FOREACH (DriverVar *, dvar, dst_vars) {
- /* need to go over all targets so that we don't leave any dangling paths */
+ /* Need to go over all targets so that we don't leave any dangling paths. */
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
- /* make a copy of target's rna path if available */
+ /* Make a copy of target's rna path if available. */
if (dtar->rna_path) {
dtar->rna_path = MEM_dupallocN(dtar->rna_path);
}
@@ -768,25 +784,24 @@ void driver_change_variable_type(DriverVar *dvar, int type)
{
const DriverVarTypeInfo *dvti = get_dvar_typeinfo(type);
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, dvar, dvti)) {
return;
}
- /* set the new settings */
+ /* Set the new settings. */
dvar->type = type;
dvar->num_targets = dvti->num_targets;
- /* make changes to the targets based on the defines for these types
- * NOTE: only need to make sure the ones we're using here are valid...
- */
+ /* Make changes to the targets based on the defines for these types.
+ * NOTE: only need to make sure the ones we're using here are valid. */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
short flags = dvti->target_flags[tarIndex];
- /* store the flags */
+ /* Store the flags. */
dtar->flag = flags;
- /* object ID types only, or idtype not yet initialized */
+ /* Object ID types only, or idtype not yet initialized. */
if ((flags & DTAR_FLAG_ID_OB_ONLY) || (dtar->idtype == 0)) {
dtar->idtype = ID_OB;
}
@@ -803,12 +818,12 @@ void driver_variable_name_validate(DriverVar *dvar)
'?', ':', ';', '<', '>', '{', '}', '[', ']', '|', ' ', '.', '\t', '\n', '\r',
};
- /* sanity checks */
+ /* Sanity checks. */
if (dvar == NULL) {
return;
}
- /* clear all invalid-name flags */
+ /* Clear all invalid-name flags. */
dvar->flag &= ~DVAR_ALL_INVALID_FLAGS;
/* 0) Zero-length identifiers are not allowed */
@@ -869,16 +884,16 @@ DriverVar *driver_add_new_variable(ChannelDriver *driver)
{
DriverVar *dvar;
- /* sanity checks */
+ /* Sanity checks. */
if (driver == NULL) {
return NULL;
}
- /* make a new variable */
+ /* Make a new variable. */
dvar = MEM_callocN(sizeof(DriverVar), "DriverVar");
BLI_addtail(&driver->variables, dvar);
- /* give the variable a 'unique' name */
+ /* Give the variable a 'unique' name. */
strcpy(dvar->name, CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "var"));
BLI_uniquename(&driver->variables,
dvar,
@@ -887,13 +902,13 @@ DriverVar *driver_add_new_variable(ChannelDriver *driver)
offsetof(DriverVar, name),
sizeof(dvar->name));
- /* set the default type to 'single prop' */
+ /* Set the default type to 'single prop'. */
driver_change_variable_type(dvar, DVAR_TYPE_SINGLE_PROP);
- /* since driver variables are cached, the expression needs re-compiling too */
+ /* Since driver variables are cached, the expression needs re-compiling too. */
BKE_driver_invalidate_expression(driver, false, true);
- /* return the target */
+ /* Return the target. */
return dvar;
}
@@ -903,20 +918,20 @@ void fcurve_free_driver(FCurve *fcu)
ChannelDriver *driver;
DriverVar *dvar, *dvarn;
- /* sanity checks */
+ /* Sanity checks. */
if (ELEM(NULL, fcu, fcu->driver)) {
return;
}
driver = fcu->driver;
- /* free driver targets */
+ /* Free driver targets. */
for (dvar = driver->variables.first; dvar; dvar = dvarn) {
dvarn = dvar->next;
driver_free_variable_ex(driver, dvar);
}
#ifdef WITH_PYTHON
- /* free compiled driver expression */
+ /* Free compiled driver expression. */
if (driver->expr_comp) {
BPY_DECREF(driver->expr_comp);
}
@@ -935,27 +950,31 @@ ChannelDriver *fcurve_copy_driver(const ChannelDriver *driver)
{
ChannelDriver *ndriver;
- /* sanity checks */
+ /* Sanity checks. */
if (driver == NULL) {
return NULL;
}
- /* copy all data */
+ /* Copy all data. */
ndriver = MEM_dupallocN(driver);
ndriver->expr_comp = NULL;
ndriver->expr_simple = NULL;
- /* copy variables */
+ /* Copy variables. */
- /* to get rid of refs to non-copied data (that's still used on original) */
+ /* To get rid of refs to non-copied data (that's still used on original). */
BLI_listbase_clear(&ndriver->variables);
driver_variables_copy(&ndriver->variables, &driver->variables);
- /* return the new driver */
+ /* Return the new driver. */
return ndriver;
}
-/* Driver Expression Evaluation --------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Expression Evaluation
+ * \{ */
/* Index constants for the expression parameter array. */
enum {
@@ -1025,7 +1044,7 @@ static bool driver_evaluate_simple_expr(ChannelDriver *driver,
return true;
default:
- /* arriving here means a bug, not user error */
+ /* Arriving here means a bug, not user error. */
CLOG_ERROR(&LOG, "simple driver expression evaluation failed: '%s'", driver->expression);
return false;
}
@@ -1134,22 +1153,25 @@ void BKE_driver_invalidate_expression(ChannelDriver *driver,
#endif
}
-/* Driver Evaluation -------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Evaluation
+ * \{ */
/* Evaluate a Driver Variable to get a value that contributes to the final */
float driver_get_variable_value(ChannelDriver *driver, DriverVar *dvar)
{
const DriverVarTypeInfo *dvti;
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, driver, dvar)) {
return 0.0f;
}
- /* call the relevant callbacks to get the variable value
+ /* Call the relevant callbacks to get the variable value
* using the variable type info, storing the obtained value
- * in dvar->curval so that drivers can be debugged
- */
+ * in `dvar->curval` so that drivers can be debugged. */
dvti = get_dvar_typeinfo(dvar->type);
if (dvti && dvti->get_value) {
@@ -1166,25 +1188,25 @@ static void evaluate_driver_sum(ChannelDriver *driver)
{
DriverVar *dvar;
- /* check how many variables there are first (i.e. just one?) */
+ /* Check how many variables there are first (i.e. just one?). */
if (BLI_listbase_is_single(&driver->variables)) {
- /* just one target, so just use that */
+ /* Just one target, so just use that. */
dvar = driver->variables.first;
driver->curval = driver_get_variable_value(driver, dvar);
return;
}
- /* more than one target, so average the values of the targets */
+ /* More than one target, so average the values of the targets. */
float value = 0.0f;
int tot = 0;
- /* loop through targets, adding (hopefully we don't get any overflow!) */
+ /* Loop through targets, adding (hopefully we don't get any overflow!). */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
value += driver_get_variable_value(driver, dvar);
tot++;
}
- /* perform operations on the total if appropriate */
+ /* Perform operations on the total if appropriate. */
if (driver->type == DRIVER_TYPE_AVERAGE) {
driver->curval = tot ? (value / (float)tot) : 0.0f;
}
@@ -1198,97 +1220,99 @@ static void evaluate_driver_min_max(ChannelDriver *driver)
DriverVar *dvar;
float value = 0.0f;
- /* loop through the variables, getting the values and comparing them to existing ones */
+ /* Loop through the variables, getting the values and comparing them to existing ones. */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- /* get value */
+ /* Get value. */
float tmp_val = driver_get_variable_value(driver, dvar);
- /* store this value if appropriate */
+ /* Store this value if appropriate. */
if (dvar->prev) {
- /* check if greater/smaller than the baseline */
+ /* Check if greater/smaller than the baseline. */
if (driver->type == DRIVER_TYPE_MAX) {
- /* max? */
+ /* Max? */
if (tmp_val > value) {
value = tmp_val;
}
}
else {
- /* min? */
+ /* Min? */
if (tmp_val < value) {
value = tmp_val;
}
}
}
else {
- /* first item - make this the baseline for comparisons */
+ /* First item - make this the baseline for comparisons. */
value = tmp_val;
}
}
- /* store value in driver */
+ /* Store value in driver. */
driver->curval = value;
}
static void evaluate_driver_python(PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
- const float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
- /* check for empty or invalid expression */
+ /* Check for empty or invalid expression. */
if ((driver_orig->expression[0] == '\0') || (driver_orig->flag & DRIVER_FLAG_INVALID)) {
driver->curval = 0.0f;
}
- else if (!driver_try_evaluate_simple_expr(driver, driver_orig, &driver->curval, evaltime)) {
+ else if (!driver_try_evaluate_simple_expr(
+ driver, driver_orig, &driver->curval, anim_eval_context->eval_time)) {
#ifdef WITH_PYTHON
- /* this evaluates the expression using Python, and returns its result:
- * - on errors it reports, then returns 0.0f
- */
+ /* This evaluates the expression using Python, and returns its result:
+ * - on errors it reports, then returns 0.0f. */
BLI_mutex_lock(&python_driver_lock);
- driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, evaltime);
+ driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, anim_eval_context);
BLI_mutex_unlock(&python_driver_lock);
-#else /* WITH_PYTHON*/
- UNUSED_VARS(anim_rna, evaltime);
-#endif /* WITH_PYTHON*/
+#else /* WITH_PYTHON */
+ UNUSED_VARS(anim_rna, anim_eval_context);
+#endif /* WITH_PYTHON */
}
}
-/* Evaluate an Channel-Driver to get a 'time' value to use instead of "evaltime"
- * - "evaltime" is the frame at which F-Curve is being evaluated
- * - has to return a float value
- * - driver_orig is where we cache Python expressions, in case of COW
+/**
+ * Evaluate an Channel-Driver to get a 'time' value to use
+ * instead of `anim_eval_context->eval_time`.
+ *
+ * - `anim_eval_context->eval_time` is the frame at which F-Curve is being evaluated.
+ * - Has to return a float value.
+ * - \a driver_orig is where we cache Python expressions, in case of COW
*/
float evaluate_driver(PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
- const float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
- /* check if driver can be evaluated */
+ /* Check if driver can be evaluated. */
if (driver_orig->flag & DRIVER_FLAG_INVALID) {
return 0.0f;
}
switch (driver->type) {
- case DRIVER_TYPE_AVERAGE: /* average values of driver targets */
- case DRIVER_TYPE_SUM: /* sum values of driver targets */
+ case DRIVER_TYPE_AVERAGE: /* Average values of driver targets. */
+ case DRIVER_TYPE_SUM: /* Sum values of driver targets. */
evaluate_driver_sum(driver);
break;
- case DRIVER_TYPE_MIN: /* smallest value */
- case DRIVER_TYPE_MAX: /* largest value */
+ case DRIVER_TYPE_MIN: /* Smallest value. */
+ case DRIVER_TYPE_MAX: /* Largest value. */
evaluate_driver_min_max(driver);
break;
- case DRIVER_TYPE_PYTHON: /* expression */
- evaluate_driver_python(anim_rna, driver, driver_orig, evaltime);
+ case DRIVER_TYPE_PYTHON: /* Expression. */
+ evaluate_driver_python(anim_rna, driver, driver_orig, anim_eval_context);
break;
default:
- /* special 'hack' - just use stored value
+ /* Special 'hack' - just use stored value
* This is currently used as the mechanism which allows animated settings to be able
- * to be changed via the UI.
- */
+ * to be changed via the UI. */
break;
}
- /* return value for driver */
+ /* Return value for driver. */
return driver->curval;
}
diff --git a/source/blender/blenkernel/intern/fcurve_test.cc b/source/blender/blenkernel/intern/fcurve_test.cc
new file mode 100644
index 00000000000..a6f65a7c9b3
--- /dev/null
+++ b/source/blender/blenkernel/intern/fcurve_test.cc
@@ -0,0 +1,213 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 by Blender Foundation.
+ */
+#include "testing/testing.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_fcurve.h"
+
+#include "ED_keyframing.h"
+
+#include "DNA_anim_types.h"
+
+namespace blender::bke::tests {
+
+// Epsilon for floating point comparisons.
+static const float EPSILON = 1e-7f;
+
+TEST(evaluate_fcurve, EmptyFCurve)
+{
+ FCurve *fcu = BKE_fcurve_create();
+ EXPECT_EQ(evaluate_fcurve(fcu, 47.0f), 0.0f);
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, OnKeys)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
+ insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
+ insert_vert_fcurve(fcu, 3.0f, 19.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.0f), 7.0f, EPSILON); // hits 'on or before first' function
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.0f), 13.0f, EPSILON); // hits 'between' function
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.0f), 19.0f, EPSILON); // hits 'on or after last' function
+
+ /* Also test within a specific time epsilon of the keys, as this was an issue in T39207.
+ * This epsilon is just slightly smaller than the epsilon given to binarysearch_bezt_index_ex()
+ * in fcurve_eval_between_keyframes(), so it should hit the "exact" code path. */
+ float time_epsilon = 0.00008f;
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.0f - time_epsilon), 13.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.0f + time_epsilon), 13.0f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, InterpolationConstant)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ fcu->bezt[0].ipo = BEZT_IPO_CONST;
+ fcu->bezt[1].ipo = BEZT_IPO_CONST;
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.25f), 7.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.50f), 7.0f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, InterpolationLinear)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ fcu->bezt[0].ipo = BEZT_IPO_LIN;
+ fcu->bezt[1].ipo = BEZT_IPO_LIN;
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.25f), 8.5f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.50f), 10.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.75f), 11.5f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, InterpolationBezier)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ EXPECT_EQ(fcu->bezt[0].ipo, BEZT_IPO_BEZ);
+ EXPECT_EQ(fcu->bezt[1].ipo, BEZT_IPO_BEZ);
+
+ // Test with default handles.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.25f), 7.8297067f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.50f), 10.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.75f), 12.170294f, EPSILON);
+
+ // Test with modified handles.
+ fcu->bezt[0].vec[0][0] = 0.71855f; // left handle X
+ fcu->bezt[0].vec[0][1] = 6.22482f; // left handle Y
+ fcu->bezt[0].vec[2][0] = 1.35148f; // right handle X
+ fcu->bezt[0].vec[2][1] = 7.96806f; // right handle Y
+
+ fcu->bezt[1].vec[0][0] = 1.66667f; // left handle X
+ fcu->bezt[1].vec[0][1] = 10.4136f; // left handle Y
+ fcu->bezt[1].vec[2][0] = 2.33333f; // right handle X
+ fcu->bezt[1].vec[2][1] = 15.5864f; // right handle Y
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.25f), 7.945497f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.50f), 9.3495407f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.75f), 11.088551f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, InterpolationBounce)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ fcu->bezt[0].ipo = BEZT_IPO_BOUNCE;
+ fcu->bezt[1].ipo = BEZT_IPO_BOUNCE;
+
+ fcu->bezt[0].easing = BEZT_IPO_EASE_IN;
+ fcu->bezt[1].easing = BEZT_IPO_EASE_AUTO;
+
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.4f), 8.3649998f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.5f), 8.4062500f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 1.8f), 11.184999f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, ExtrapolationLinearKeys)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+ fcu->bezt[0].ipo = BEZT_IPO_LIN;
+ fcu->bezt[1].ipo = BEZT_IPO_LIN;
+
+ fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
+ // Before first keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.75f), 5.5f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.50f), 4.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, -1.50f), -8.0f, EPSILON);
+ // After last keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.75f), 17.5f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.50f), 22.0f, EPSILON);
+
+ fcu->extend = FCURVE_EXTRAPOLATE_CONSTANT;
+ // Before first keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.75f), 7.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, -1.50f), 7.0f, EPSILON);
+ // After last keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.75f), 13.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.50f), 13.0f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+TEST(evaluate_fcurve, ExtrapolationBezierKeys)
+{
+ FCurve *fcu = BKE_fcurve_create();
+
+ EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
+ EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
+
+ fcu->bezt[0].vec[0][0] = 0.71855f; // left handle X
+ fcu->bezt[0].vec[0][1] = 6.22482f; // left handle Y
+ fcu->bezt[0].vec[2][0] = 1.35148f; // right handle X
+ fcu->bezt[0].vec[2][1] = 7.96806f; // right handle Y
+
+ fcu->bezt[1].vec[0][0] = 1.66667f; // left handle X
+ fcu->bezt[1].vec[0][1] = 10.4136f; // left handle Y
+ fcu->bezt[1].vec[2][0] = 2.33333f; // right handle X
+ fcu->bezt[1].vec[2][1] = 15.5864f; // right handle Y
+
+ fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
+ // Before first keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.75f), 6.3114409f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, -0.50f), 2.8686447f, EPSILON);
+ // After last keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.75f), 18.81946f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.50f), 24.63892f, EPSILON);
+
+ fcu->extend = FCURVE_EXTRAPOLATE_CONSTANT;
+ // Before first keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 0.75f), 7.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, -1.50f), 7.0f, EPSILON);
+ // After last keyframe.
+ EXPECT_NEAR(evaluate_fcurve(fcu, 2.75f), 13.0f, EPSILON);
+ EXPECT_NEAR(evaluate_fcurve(fcu, 3.50f), 13.0f, EPSILON);
+
+ BKE_fcurve_free(fcu);
+}
+
+} // namespace blender::bke::tests
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 1f748487841..2245af31f0d 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -137,109 +137,84 @@ bool BKE_fluid_reallocate_fluid(FluidDomainSettings *fds, int res[3], int free_o
void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
int o_res[3],
int n_res[3],
- int o_min[3],
- int n_min[3],
- int o_max[3],
+ const int o_min[3],
+ const int n_min[3],
+ const int o_max[3],
int o_shift[3],
int n_shift[3])
{
- int x, y, z;
struct MANTA *fluid_old = fds->fluid;
const int block_size = fds->noise_scale;
int new_shift[3] = {0};
sub_v3_v3v3_int(new_shift, n_shift, o_shift);
- /* allocate new fluid data */
+ /* Allocate new fluid data. */
BKE_fluid_reallocate_fluid(fds, n_res, 0);
int o_total_cells = o_res[0] * o_res[1] * o_res[2];
int n_total_cells = n_res[0] * n_res[1] * n_res[2];
- /* boundary cells will be skipped when copying data */
- int bwidth = fds->boundary_width;
-
- /* copy values from old fluid to new */
+ /* Copy values from old fluid to new fluid object. */
if (o_total_cells > 1 && n_total_cells > 1) {
- /* base smoke */
- float *o_dens, *o_react, *o_flame, *o_fuel, *o_heat, *o_vx, *o_vy, *o_vz, *o_r, *o_g, *o_b;
- float *n_dens, *n_react, *n_flame, *n_fuel, *n_heat, *n_vx, *n_vy, *n_vz, *n_r, *n_g, *n_b;
- float dummy, *dummy_s;
- int *dummy_p;
- /* noise smoke */
+ float *o_dens = manta_smoke_get_density(fluid_old);
+ float *o_react = manta_smoke_get_react(fluid_old);
+ float *o_flame = manta_smoke_get_flame(fluid_old);
+ float *o_fuel = manta_smoke_get_fuel(fluid_old);
+ float *o_heat = manta_smoke_get_heat(fluid_old);
+ float *o_vx = manta_get_velocity_x(fluid_old);
+ float *o_vy = manta_get_velocity_y(fluid_old);
+ float *o_vz = manta_get_velocity_z(fluid_old);
+ float *o_r = manta_smoke_get_color_r(fluid_old);
+ float *o_g = manta_smoke_get_color_g(fluid_old);
+ float *o_b = manta_smoke_get_color_b(fluid_old);
+
+ float *n_dens = manta_smoke_get_density(fds->fluid);
+ float *n_react = manta_smoke_get_react(fds->fluid);
+ float *n_flame = manta_smoke_get_flame(fds->fluid);
+ float *n_fuel = manta_smoke_get_fuel(fds->fluid);
+ float *n_heat = manta_smoke_get_heat(fds->fluid);
+ float *n_vx = manta_get_velocity_x(fds->fluid);
+ float *n_vy = manta_get_velocity_y(fds->fluid);
+ float *n_vz = manta_get_velocity_z(fds->fluid);
+ float *n_r = manta_smoke_get_color_r(fds->fluid);
+ float *n_g = manta_smoke_get_color_g(fds->fluid);
+ float *n_b = manta_smoke_get_color_b(fds->fluid);
+
+ /* Noise smoke fields. */
int wt_res_old[3];
- float *o_wt_dens, *o_wt_react, *o_wt_flame, *o_wt_fuel, *o_wt_tcu, *o_wt_tcv, *o_wt_tcw,
- *o_wt_tcu2, *o_wt_tcv2, *o_wt_tcw2, *o_wt_r, *o_wt_g, *o_wt_b;
- float *n_wt_dens, *n_wt_react, *n_wt_flame, *n_wt_fuel, *n_wt_tcu, *n_wt_tcv, *n_wt_tcw,
- *n_wt_tcu2, *n_wt_tcv2, *n_wt_tcw2, *n_wt_r, *n_wt_g, *n_wt_b;
-
- if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
- manta_smoke_turbulence_export(fluid_old,
- &o_wt_dens,
- &o_wt_react,
- &o_wt_flame,
- &o_wt_fuel,
- &o_wt_r,
- &o_wt_g,
- &o_wt_b,
- &o_wt_tcu,
- &o_wt_tcv,
- &o_wt_tcw,
- &o_wt_tcu2,
- &o_wt_tcv2,
- &o_wt_tcw2);
- manta_smoke_turbulence_get_res(fluid_old, wt_res_old);
- manta_smoke_turbulence_export(fds->fluid,
- &n_wt_dens,
- &n_wt_react,
- &n_wt_flame,
- &n_wt_fuel,
- &n_wt_r,
- &n_wt_g,
- &n_wt_b,
- &n_wt_tcu,
- &n_wt_tcv,
- &n_wt_tcw,
- &n_wt_tcu2,
- &n_wt_tcv2,
- &n_wt_tcw2);
- }
-
- manta_smoke_export(fluid_old,
- &dummy,
- &dummy,
- &o_dens,
- &o_react,
- &o_flame,
- &o_fuel,
- &o_heat,
- &o_vx,
- &o_vy,
- &o_vz,
- &o_r,
- &o_g,
- &o_b,
- &dummy_p,
- &dummy_s);
- manta_smoke_export(fds->fluid,
- &dummy,
- &dummy,
- &n_dens,
- &n_react,
- &n_flame,
- &n_fuel,
- &n_heat,
- &n_vx,
- &n_vy,
- &n_vz,
- &n_r,
- &n_g,
- &n_b,
- &dummy_p,
- &dummy_s);
-
- for (x = o_min[0]; x < o_max[0]; x++) {
- for (y = o_min[1]; y < o_max[1]; y++) {
- for (z = o_min[2]; z < o_max[2]; z++) {
+ float *o_wt_dens = manta_noise_get_density(fluid_old);
+ float *o_wt_react = manta_noise_get_react(fluid_old);
+ float *o_wt_flame = manta_noise_get_flame(fluid_old);
+ float *o_wt_fuel = manta_noise_get_fuel(fluid_old);
+ float *o_wt_r = manta_noise_get_color_r(fluid_old);
+ float *o_wt_g = manta_noise_get_color_g(fluid_old);
+ float *o_wt_b = manta_noise_get_color_b(fluid_old);
+ float *o_wt_tcu = manta_noise_get_texture_u(fluid_old);
+ float *o_wt_tcv = manta_noise_get_texture_v(fluid_old);
+ float *o_wt_tcw = manta_noise_get_texture_w(fluid_old);
+ float *o_wt_tcu2 = manta_noise_get_texture_u2(fluid_old);
+ float *o_wt_tcv2 = manta_noise_get_texture_v2(fluid_old);
+ float *o_wt_tcw2 = manta_noise_get_texture_w2(fluid_old);
+
+ float *n_wt_dens = manta_noise_get_density(fds->fluid);
+ float *n_wt_react = manta_noise_get_react(fds->fluid);
+ float *n_wt_flame = manta_noise_get_flame(fds->fluid);
+ float *n_wt_fuel = manta_noise_get_fuel(fds->fluid);
+ float *n_wt_r = manta_noise_get_color_r(fds->fluid);
+ float *n_wt_g = manta_noise_get_color_g(fds->fluid);
+ float *n_wt_b = manta_noise_get_color_b(fds->fluid);
+ float *n_wt_tcu = manta_noise_get_texture_u(fds->fluid);
+ float *n_wt_tcv = manta_noise_get_texture_v(fds->fluid);
+ float *n_wt_tcw = manta_noise_get_texture_w(fds->fluid);
+ float *n_wt_tcu2 = manta_noise_get_texture_u2(fds->fluid);
+ float *n_wt_tcv2 = manta_noise_get_texture_v2(fds->fluid);
+ float *n_wt_tcw2 = manta_noise_get_texture_w2(fds->fluid);
+
+ manta_noise_get_res(fluid_old, wt_res_old);
+
+ for (int z = o_min[2]; z < o_max[2]; z++) {
+ for (int y = o_min[1]; y < o_max[1]; y++) {
+ for (int x = o_min[0]; x < o_max[0]; x++) {
/* old grid index */
int xo = x - o_min[0];
int yo = y - o_min[1];
@@ -251,20 +226,31 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
int zn = z - n_min[2] - new_shift[2];
int index_new = manta_get_index(xn, n_res[0], yn, n_res[1], zn);
- /* skip if outside new domain */
+ /* Skip if outside new domain. */
if (xn < 0 || xn >= n_res[0] || yn < 0 || yn >= n_res[1] || zn < 0 || zn >= n_res[2]) {
continue;
}
- /* skip if trying to copy from old boundary cell */
+# if 0
+ /* Note (sebbas):
+ * Disabling this "skip section" as not copying borders results in weird cut-off effects.
+ * It is possible that this cutting off is the reason for line effects as seen in T74559.
+ * Since domain borders will be handled on the simulation side anyways,
+ * copying border values should not be an issue. */
+
+ /* boundary cells will be skipped when copying data */
+ int bwidth = fds->boundary_width;
+
+ /* Skip if trying to copy from old boundary cell. */
if (xo < bwidth || yo < bwidth || zo < bwidth || xo >= o_res[0] - bwidth ||
yo >= o_res[1] - bwidth || zo >= o_res[2] - bwidth) {
continue;
}
- /* skip if trying to copy into new boundary cell */
+ /* Skip if trying to copy into new boundary cell. */
if (xn < bwidth || yn < bwidth || zn < bwidth || xn >= n_res[0] - bwidth ||
yn >= n_res[1] - bwidth || zn >= n_res[2] - bwidth) {
continue;
}
+# endif
/* copy data */
if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
@@ -491,6 +477,17 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds,
fds->cell_size[2] /= (float)fds->base_res[2];
}
+static void update_final_gravity(FluidDomainSettings *fds, Scene *scene)
+{
+ if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
+ copy_v3_v3(fds->gravity_final, scene->physics_settings.gravity);
+ }
+ else {
+ copy_v3_v3(fds->gravity_final, fds->gravity);
+ }
+ mul_v3_fl(fds->gravity_final, fds->effector_weights->global_gravity);
+}
+
static bool BKE_fluid_modifier_init(
FluidModifierData *fmd, Depsgraph *depsgraph, Object *ob, Scene *scene, Mesh *me)
{
@@ -502,10 +499,7 @@ static bool BKE_fluid_modifier_init(
/* Set domain dimensions from mesh. */
manta_set_domain_from_mesh(fds, ob, me, true);
/* Set domain gravity, use global gravity if enabled. */
- if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
- copy_v3_v3(fds->gravity, scene->physics_settings.gravity);
- }
- mul_v3_fl(fds->gravity, fds->effector_weights->global_gravity);
+ update_final_gravity(fds, scene);
/* Reset domain values. */
zero_v3_int(fds->shift);
zero_v3(fds->shift_f);
@@ -559,7 +553,7 @@ static bool BKE_fluid_modifier_init(
// forward declaration
static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *view_layer);
static float calc_voxel_transp(
- float *result, float *input, int res[3], int *pixel, float *t_ray, float correct);
+ float *result, const float *input, int res[3], int *pixel, float *t_ray, float correct);
static void update_distances(int index,
float *fesh_distances,
BVHTreeFromMesh *tree_data,
@@ -594,8 +588,8 @@ static int get_light(ViewLayer *view_layer, float *light)
static void clamp_bounds_in_domain(FluidDomainSettings *fds,
int min[3],
int max[3],
- float *min_vel,
- float *max_vel,
+ const float *min_vel,
+ const float *max_vel,
int margin,
float dt)
{
@@ -1125,6 +1119,7 @@ static void ensure_obstaclefields(FluidDomainSettings *fds)
if (fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE) {
manta_ensure_guiding(fds->fluid, fds->fmd);
}
+ manta_update_pointers(fds->fluid, fds->fmd, false);
}
static void update_obstacleflags(FluidDomainSettings *fds,
@@ -1398,8 +1393,7 @@ static void update_obstacles(Depsgraph *depsgraph,
/* Cannot use static mode with adaptive domain.
* The adaptive domain might expand and only later in the simulations discover the static
* object. */
- bool is_static = is_static_object(effecobj) &&
- ((fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) == 0);
+ bool is_static = is_static_object(effecobj) && !use_adaptivedomain;
/* Check for initialized effector object. */
if ((fmd2->type & MOD_FLUID_TYPE_EFFEC) && fmd2->effector) {
@@ -1830,7 +1824,7 @@ static void sample_mesh(FluidFlowSettings *ffs,
float *velocity_map,
int index,
const int base_res[3],
- float flow_center[3],
+ const float flow_center[3],
BVHTreeFromMesh *tree_data,
const float ray_start[3],
const float *vert_vel,
@@ -2256,15 +2250,15 @@ static void adaptive_domain_adjust(
int x, y, z;
float *density = manta_smoke_get_density(fds->fluid);
float *fuel = manta_smoke_get_fuel(fds->fluid);
- float *bigdensity = manta_smoke_turbulence_get_density(fds->fluid);
- float *bigfuel = manta_smoke_turbulence_get_fuel(fds->fluid);
+ float *bigdensity = manta_noise_get_density(fds->fluid);
+ float *bigfuel = manta_noise_get_fuel(fds->fluid);
float *vx = manta_get_velocity_x(fds->fluid);
float *vy = manta_get_velocity_y(fds->fluid);
float *vz = manta_get_velocity_z(fds->fluid);
int wt_res[3];
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
- manta_smoke_turbulence_get_res(fds->fluid, wt_res);
+ manta_noise_get_res(fds->fluid, wt_res);
}
INIT_MINMAX(min_vel, max_vel);
@@ -2603,7 +2597,7 @@ static void ensure_flowsfields(FluidDomainSettings *fds)
manta_smoke_ensure_fire(fds->fluid, fds->fmd);
}
if (fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) {
- /* initialize all smoke with "active_color" */
+ /* Initialize all smoke with "active_color". */
manta_smoke_ensure_colors(fds->fluid, fds->fmd);
}
if (fds->type == FLUID_DOMAIN_TYPE_LIQUID &&
@@ -2612,6 +2606,7 @@ static void ensure_flowsfields(FluidDomainSettings *fds)
fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER)) {
manta_liquid_ensure_sndparts(fds->fluid, fds->fmd);
}
+ manta_update_pointers(fds->fluid, fds->fmd, false);
}
static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int numflowobj)
@@ -2624,7 +2619,7 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
FLUID_DOMAIN_ACTIVE_HEAT | FLUID_DOMAIN_ACTIVE_FIRE);
active_fields &= ~prev_flags;
- /* Monitor active fields based on flow settings */
+ /* Monitor active fields based on flow settings. */
for (flow_index = 0; flow_index < numflowobj; flow_index++) {
Object *flow_ob = flowobjs[flow_index];
FluidModifierData *fmd2 = (FluidModifierData *)BKE_modifiers_findby_type(flow_ob,
@@ -2635,6 +2630,7 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
continue;
}
+ /* Activate specific grids if at least one flow object requires this grid. */
if ((fmd2->type & MOD_FLUID_TYPE_FLOW) && fmd2->flow) {
FluidFlowSettings *ffs = fmd2->flow;
if (!ffs) {
@@ -2655,17 +2651,17 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
continue;
}
- /* activate heat field if flow produces any heat */
- if (ffs->temperature) {
+ /* Activate heat field if a flow object produces any heat. */
+ if (ffs->temperature != 0.0) {
active_fields |= FLUID_DOMAIN_ACTIVE_HEAT;
}
- /* activate fuel field if flow adds any fuel */
- if (ffs->fuel_amount &&
- (ffs->type == FLUID_FLOW_TYPE_FIRE || ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE)) {
+ /* Activate fuel field if a flow object is of fire type. */
+ if (ffs->fuel_amount != 0.0 || ffs->type == FLUID_FLOW_TYPE_FIRE ||
+ ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE) {
active_fields |= FLUID_DOMAIN_ACTIVE_FIRE;
}
- /* activate color field if flows add smoke with varying colors */
- if (ffs->density &&
+ /* Activate color field if flows add smoke with varying colors. */
+ if (ffs->density != 0.0 &&
(ffs->type == FLUID_FLOW_TYPE_SMOKE || ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE)) {
if (!(active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET)) {
copy_v3_v3(fds->active_color, ffs->color);
@@ -2678,11 +2674,11 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
}
}
}
- /* Monitor active fields based on domain settings */
+ /* Monitor active fields based on domain settings. */
if (fds->type == FLUID_DOMAIN_TYPE_GAS && active_fields & FLUID_DOMAIN_ACTIVE_FIRE) {
- /* heat is always needed for fire */
+ /* Heat is always needed for fire. */
active_fields |= FLUID_DOMAIN_ACTIVE_HEAT;
- /* also activate colors if domain smoke color differs from active color */
+ /* Also activate colors if domain smoke color differs from active color. */
if (!(active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET)) {
copy_v3_v3(fds->active_color, fds->flame_smoke_color);
active_fields |= FLUID_DOMAIN_ACTIVE_COLOR_SET;
@@ -2931,8 +2927,21 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
float *velx_initial = manta_get_in_velocity_x(fds->fluid);
float *vely_initial = manta_get_in_velocity_y(fds->fluid);
float *velz_initial = manta_get_in_velocity_z(fds->fluid);
- uint z;
+ float *forcex = manta_get_force_x(fds->fluid);
+ float *forcey = manta_get_force_y(fds->fluid);
+ float *forcez = manta_get_force_z(fds->fluid);
+
+ BLI_assert(forcex && forcey && forcez);
+
+ /* Either all or no components have to exist. */
+ BLI_assert((color_r && color_g && color_b) || (!color_r && !color_g && !color_b));
+ BLI_assert((color_r_in && color_g_in && color_b_in) ||
+ (!color_r_in && !color_g_in && !color_b_in));
+ BLI_assert((velx_initial && vely_initial && velz_initial) ||
+ (!velx_initial && !vely_initial && !velz_initial));
+
+ uint z;
/* Grid reset before writing again. */
for (z = 0; z < fds->res[0] * fds->res[1] * fds->res[2]; z++) {
/* Only reset static phi on first frame, dynamic phi gets reset every time. */
@@ -2956,7 +2965,7 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
if (heat_in) {
heat_in[z] = heat[z];
}
- if (color_r_in) {
+ if (color_r_in && color_g_in && color_b_in) {
color_r_in[z] = color_r[z];
color_g_in[z] = color_b[z];
color_b_in[z] = color_g[z];
@@ -2968,11 +2977,15 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
if (emission_in) {
emission_in[z] = 0.0f;
}
- if (velx_initial) {
+ if (velx_initial && vely_initial && velz_initial) {
velx_initial[z] = 0.0f;
vely_initial[z] = 0.0f;
velz_initial[z] = 0.0f;
}
+ /* Reset forces here as update_effectors() is skipped when no external forces are present. */
+ forcex[z] = 0.0f;
+ forcey[z] = 0.0f;
+ forcez[z] = 0.0f;
}
/* Apply emission data for every flow object. */
@@ -3156,13 +3169,13 @@ static void update_effectors_task_cb(void *__restrict userdata,
continue;
}
- /* get velocities from manta grid space and convert to blender units */
+ /* Get velocities from manta grid space and convert to blender units. */
vel[0] = data->velocity_x[index];
vel[1] = data->velocity_y[index];
vel[2] = data->velocity_z[index];
mul_v3_fl(vel, fds->dx);
- /* convert vel to global space */
+ /* Convert vel to global space. */
mag = len_v3(vel);
mul_mat3_m4_v3(fds->obmat, vel);
normalize_v3(vel);
@@ -3173,18 +3186,18 @@ static void update_effectors_task_cb(void *__restrict userdata,
voxel_center[2] = fds->p0[2] + fds->cell_size[2] * ((float)(z + fds->res_min[2]) + 0.5f);
mul_m4_v3(fds->obmat, voxel_center);
- /* do effectors */
+ /* Do effectors. */
pd_point_from_loc(data->scene, voxel_center, vel, index, &epoint);
BKE_effectors_apply(
data->effectors, NULL, fds->effector_weights, &epoint, retvel, NULL, NULL);
- /* convert retvel to local space */
+ /* Convert retvel to local space. */
mag = len_v3(retvel);
mul_mat3_m4_v3(fds->imat, retvel);
normalize_v3(retvel);
mul_v3_fl(retvel, mag);
- /* constrain forces to interval -1 to 1 */
+ /* Constrain forces to interval -1 to 1. */
data->force_x[index] = min_ff(max_ff(-1.0f, retvel[0] * 0.2f), 1.0f);
data->force_y[index] = min_ff(max_ff(-1.0f, retvel[1] * 0.2f), 1.0f);
data->force_z[index] = min_ff(max_ff(-1.0f, retvel[2] * 0.2f), 1.0f);
@@ -3328,17 +3341,13 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obj
mverts->co[1] = manta_liquid_get_vertex_y_at(fds->fluid, i);
mverts->co[2] = manta_liquid_get_vertex_z_at(fds->fluid, i);
- /* If reading raw data directly from manta, normalize now (e.g. during replay mode).
- * If reading data from files from disk, omit this normalization. */
- if (!manta_liquid_mesh_from_file(fds->fluid)) {
- // normalize to unit cube around 0
- mverts->co[0] -= ((float)fds->res[0] * fds->mesh_scale) * 0.5f;
- mverts->co[1] -= ((float)fds->res[1] * fds->mesh_scale) * 0.5f;
- mverts->co[2] -= ((float)fds->res[2] * fds->mesh_scale) * 0.5f;
- mverts->co[0] *= fds->dx / fds->mesh_scale;
- mverts->co[1] *= fds->dx / fds->mesh_scale;
- mverts->co[2] *= fds->dx / fds->mesh_scale;
- }
+ /* Adjust coordinates from Mantaflow to match viewport scaling. */
+ float tmp[3] = {(float)fds->res[0], (float)fds->res[1], (float)fds->res[2]};
+ /* Scale to unit cube around 0. */
+ mul_v3_fl(tmp, fds->mesh_scale * 0.5f);
+ sub_v3_v3(mverts->co, tmp);
+ /* Apply scaling of domain object. */
+ mul_v3_fl(mverts->co, fds->dx / fds->mesh_scale);
mul_v3_v3(mverts->co, co_scale);
add_v3_v3(mverts->co, co_offset);
@@ -3628,14 +3637,16 @@ static int manta_step(
fds->time_per_frame = time_per_frame;
fds->time_total = time_total;
}
+
/* Total time must not exceed framecount times framelength. Correct tiny errors here. */
CLAMP(fds->time_total, fds->time_total, time_total_old + fds->frame_length);
+ /* Compute shadow grid for gas simulations. Make sure to skip if bake job was canceled early. */
if (fds->type == FLUID_DOMAIN_TYPE_GAS && result) {
manta_smoke_calc_transparency(fds, DEG_get_evaluated_view_layer(depsgraph));
}
- BLI_mutex_unlock(&object_update_lock);
+ BLI_mutex_unlock(&object_update_lock);
return result;
}
@@ -3727,29 +3738,35 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
int mode = fds->cache_type;
/* Do not process modifier if current frame is out of cache range. */
+ bool escape = false;
switch (mode) {
case FLUID_DOMAIN_CACHE_ALL:
case FLUID_DOMAIN_CACHE_MODULAR:
if (fds->cache_frame_offset > 0) {
if (scene_framenr < fds->cache_frame_start ||
scene_framenr > fds->cache_frame_end + fds->cache_frame_offset) {
- return;
+ escape = true;
}
}
else {
if (scene_framenr < fds->cache_frame_start + fds->cache_frame_offset ||
scene_framenr > fds->cache_frame_end) {
- return;
+ escape = true;
}
}
break;
case FLUID_DOMAIN_CACHE_REPLAY:
default:
if (scene_framenr < fds->cache_frame_start || scene_framenr > fds->cache_frame_end) {
- return;
+ escape = true;
}
break;
}
+ /* If modifier will not be processed, update/flush pointers from (old) fluid object once more. */
+ if (escape && fds->fluid) {
+ manta_update_pointers(fds->fluid, fmd, true);
+ return;
+ }
/* Reset fluid if no fluid present. Also resets active fields. */
if (!fds->fluid) {
@@ -3808,10 +3825,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
fds->time_per_frame = 0;
/* Ensure that gravity is copied over every frame (could be keyframed). */
- if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
- copy_v3_v3(fds->gravity, scene->physics_settings.gravity);
- mul_v3_fl(fds->gravity, fds->effector_weights->global_gravity);
- }
+ update_final_gravity(fds, scene);
int next_frame = scene_framenr + 1;
int prev_frame = scene_framenr - 1;
@@ -3831,9 +3845,8 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
floater = fds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM;
bool with_resumable_cache = fds->flags & FLUID_DOMAIN_USE_RESUMABLE_CACHE;
- bool with_script, with_adaptive, with_noise, with_mesh, with_particles, with_guide;
+ bool with_script, with_noise, with_mesh, with_particles, with_guide;
with_script = fds->flags & FLUID_DOMAIN_EXPORT_MANTA_SCRIPT;
- with_adaptive = fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN;
with_noise = fds->flags & FLUID_DOMAIN_USE_NOISE;
with_mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
with_guide = fds->flags & FLUID_DOMAIN_USE_GUIDE;
@@ -3845,7 +3858,15 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
has_mesh = manta_has_mesh(fds->fluid, fmd, scene_framenr);
has_particles = manta_has_particles(fds->fluid, fmd, scene_framenr);
has_guide = manta_has_guiding(fds->fluid, fmd, scene_framenr, guide_parent);
- has_config = false;
+ has_config = manta_read_config(fds->fluid, fmd, scene_framenr);
+
+ /* When reading data from cache (has_config == true) ensure that active fields are allocated.
+ * update_flowsflags() and update_obstacleflags() will not find flow sources hidden from renders.
+ * See also: T72192. */
+ if (has_config) {
+ ensure_flowsfields(fds);
+ ensure_obstaclefields(fds);
+ }
bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA;
@@ -3950,13 +3971,21 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
break;
}
+ /* Adaptive domain needs to know about current state, so save it here. */
+ copy_v3_v3_int(o_res, fds->res);
+ copy_v3_v3_int(o_min, fds->res_min);
+ copy_v3_v3_int(o_max, fds->res_max);
+ copy_v3_v3_int(o_shift, fds->shift);
+
bool read_partial = false, read_all = false;
/* Try to read from cache and keep track of read success. */
if (read_cache) {
/* Read mesh cache. */
if (with_liquid && with_mesh) {
- has_config = manta_read_config(fds->fluid, fmd, mesh_frame);
+ if (mesh_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, mesh_frame);
+ }
/* Update mesh data from file is faster than via Python (manta_read_mesh()). */
has_mesh = manta_read_mesh(fds->fluid, fmd, mesh_frame);
@@ -3964,7 +3993,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
/* Read particles cache. */
if (with_liquid && with_particles) {
- has_config = manta_read_config(fds->fluid, fmd, particles_frame);
+ if (particles_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, particles_frame);
+ }
read_partial = !baking_data && !baking_particles && next_particles;
read_all = !read_partial && with_resumable_cache;
@@ -3979,38 +4010,29 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
/* Read noise and data cache */
if (with_smoke && with_noise) {
- has_config = manta_read_config(fds->fluid, fmd, noise_frame);
+ if (noise_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, noise_frame);
+ }
/* Only reallocate when just reading cache or when resuming during bake. */
- if ((!baking_noise || (baking_noise && resume_noise)) && has_config &&
- manta_needs_realloc(fds->fluid, fmd)) {
- BKE_fluid_reallocate_fluid(fds, fds->res, 1);
+ if (has_data && has_config && manta_needs_realloc(fds->fluid, fmd)) {
+ BKE_fluid_reallocate_copy_fluid(
+ fds, o_res, fds->res, o_min, fds->res_min, o_max, o_shift, fds->shift);
}
read_partial = !baking_data && !baking_noise && next_noise;
read_all = !read_partial && with_resumable_cache;
has_noise = manta_read_noise(fds->fluid, fmd, noise_frame, read_all);
- /* When using the adaptive domain, copy all data that was read to a new fluid object. */
- if (with_adaptive && baking_noise) {
- /* Adaptive domain needs to know about current state, so save it, then copy. */
- copy_v3_v3_int(o_res, fds->res);
- copy_v3_v3_int(o_min, fds->res_min);
- copy_v3_v3_int(o_max, fds->res_max);
- copy_v3_v3_int(o_shift, fds->shift);
- if (has_config && manta_needs_realloc(fds->fluid, fmd)) {
- BKE_fluid_reallocate_copy_fluid(
- fds, o_res, fds->res, o_min, fds->res_min, o_max, o_shift, fds->shift);
- }
- }
-
read_partial = !baking_data && !baking_noise && next_data && next_noise;
read_all = !read_partial && with_resumable_cache;
has_data = manta_read_data(fds->fluid, fmd, data_frame, read_all);
}
/* Read data cache only */
else {
- has_config = manta_read_config(fds->fluid, fmd, data_frame);
+ if (data_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, data_frame);
+ }
if (with_smoke) {
/* Read config and realloc fluid object if needed. */
@@ -4095,6 +4117,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
}
}
+ /* Ensure that fluid pointers are always up to date at the end of modifier processing. */
+ manta_update_pointers(fds->fluid, fmd, false);
+
fds->flags &= ~FLUID_DOMAIN_FILE_LOAD;
fmd->time = scene_framenr;
}
@@ -4118,43 +4143,47 @@ static void BKE_fluid_modifier_process(
struct Mesh *BKE_fluid_modifier_do(
FluidModifierData *fmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *me)
{
- /* Lock so preview render does not read smoke data while it gets modified. */
- if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
- BLI_rw_mutex_lock(fmd->domain->fluid_mutex, THREAD_LOCK_WRITE);
- }
-
- BKE_fluid_modifier_process(fmd, depsgraph, scene, ob, me);
-
- if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
- BLI_rw_mutex_unlock(fmd->domain->fluid_mutex);
- }
-
/* Optimization: Do not update viewport during bakes (except in replay mode)
* Reason: UI is locked and updated liquid / smoke geometry is not visible anyways. */
bool needs_viewport_update = false;
- if (fmd->domain) {
- FluidDomainSettings *fds = fmd->domain;
- /* Always update viewport in cache replay mode. */
- if (fds->cache_type == FLUID_DOMAIN_CACHE_REPLAY ||
- fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
- needs_viewport_update = true;
+ /* Optimization: Only process modifier if object is not being altered. */
+ if (!G.moving) {
+ /* Lock so preview render does not read smoke data while it gets modified. */
+ if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
+ BLI_rw_mutex_lock(fmd->domain->fluid_mutex, THREAD_LOCK_WRITE);
}
- /* In other cache modes, only update the viewport when no bake is going on. */
- else {
- bool with_mesh;
- with_mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
- bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
- baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA;
- baking_noise = fds->cache_flag & FLUID_DOMAIN_BAKING_NOISE;
- baking_mesh = fds->cache_flag & FLUID_DOMAIN_BAKING_MESH;
- baking_particles = fds->cache_flag & FLUID_DOMAIN_BAKING_PARTICLES;
- baking_guide = fds->cache_flag & FLUID_DOMAIN_BAKING_GUIDE;
-
- if (with_mesh && !baking_data && !baking_noise && !baking_mesh && !baking_particles &&
- !baking_guide) {
+
+ BKE_fluid_modifier_process(fmd, depsgraph, scene, ob, me);
+
+ if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) {
+ BLI_rw_mutex_unlock(fmd->domain->fluid_mutex);
+ }
+
+ if (fmd->domain) {
+ FluidDomainSettings *fds = fmd->domain;
+
+ /* Always update viewport in cache replay mode. */
+ if (fds->cache_type == FLUID_DOMAIN_CACHE_REPLAY ||
+ fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) {
needs_viewport_update = true;
}
+ /* In other cache modes, only update the viewport when no bake is going on. */
+ else {
+ bool with_mesh;
+ with_mesh = fds->flags & FLUID_DOMAIN_USE_MESH;
+ bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
+ baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA;
+ baking_noise = fds->cache_flag & FLUID_DOMAIN_BAKING_NOISE;
+ baking_mesh = fds->cache_flag & FLUID_DOMAIN_BAKING_MESH;
+ baking_particles = fds->cache_flag & FLUID_DOMAIN_BAKING_PARTICLES;
+ baking_guide = fds->cache_flag & FLUID_DOMAIN_BAKING_GUIDE;
+
+ if (with_mesh && !baking_data && !baking_noise && !baking_mesh && !baking_particles &&
+ !baking_guide) {
+ needs_viewport_update = true;
+ }
+ }
}
}
@@ -4196,7 +4225,7 @@ struct Mesh *BKE_fluid_modifier_do(
}
static float calc_voxel_transp(
- float *result, float *input, int res[3], int *pixel, float *t_ray, float correct)
+ float *result, const float *input, int res[3], int *pixel, float *t_ray, float correct)
{
const size_t index = manta_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]);
@@ -4311,7 +4340,7 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
{
float bv[6] = {0};
float light[3];
- int a, z, slabsize = fds->res[0] * fds->res[1], size = fds->res[0] * fds->res[1] * fds->res[2];
+ int slabsize = fds->res[0] * fds->res[1];
float *density = manta_smoke_get_density(fds->fluid);
float *shadow = manta_smoke_get_shadow(fds->fluid);
float correct = -7.0f * fds->dx;
@@ -4320,54 +4349,49 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
return;
}
- /* convert light pos to sim cell space */
+ /* Convert light pos to sim cell space. */
mul_m4_v3(fds->imat, light);
light[0] = (light[0] - fds->p0[0]) / fds->cell_size[0] - 0.5f - (float)fds->res_min[0];
light[1] = (light[1] - fds->p0[1]) / fds->cell_size[1] - 0.5f - (float)fds->res_min[1];
light[2] = (light[2] - fds->p0[2]) / fds->cell_size[2] - 0.5f - (float)fds->res_min[2];
- for (a = 0; a < size; a++) {
- shadow[a] = -1.0f;
- }
-
- /* calculate domain bounds in sim cell space */
+ /* Calculate domain bounds in sim cell space. */
// 0,2,4 = 0.0f
bv[1] = (float)fds->res[0]; // x
bv[3] = (float)fds->res[1]; // y
bv[5] = (float)fds->res[2]; // z
- for (z = 0; z < fds->res[2]; z++) {
+ for (int z = 0; z < fds->res[2]; z++) {
size_t index = z * slabsize;
- int x, y;
- for (y = 0; y < fds->res[1]; y++) {
- for (x = 0; x < fds->res[0]; x++, index++) {
+ for (int y = 0; y < fds->res[1]; y++) {
+ for (int x = 0; x < fds->res[0]; x++, index++) {
float voxel_center[3];
float pos[3];
int cell[3];
float t_ray = 1.0;
- if (shadow[index] >= 0.0f) {
- continue;
- }
+ /* Reset shadow value.*/
+ shadow[index] = -1.0f;
+
voxel_center[0] = (float)x;
voxel_center[1] = (float)y;
voxel_center[2] = (float)z;
- // get starting cell (light pos)
+ /* Get starting cell (light pos). */
if (BLI_bvhtree_bb_raycast(bv, light, voxel_center, pos) > FLT_EPSILON) {
- // we're outside -> use point on side of domain
+ /* We're outside -> use point on side of domain. */
cell[0] = (int)floor(pos[0]);
cell[1] = (int)floor(pos[1]);
cell[2] = (int)floor(pos[2]);
}
else {
- // we're inside -> use light itself
+ /* We're inside -> use light itself. */
cell[0] = (int)floor(light[0]);
cell[1] = (int)floor(light[1]);
cell[2] = (int)floor(light[2]);
}
- /* clamp within grid bounds */
+ /* Clamp within grid bounds */
CLAMP(cell[0], 0, fds->res[0] - 1);
CLAMP(cell[1], 0, fds->res[1] - 1);
CLAMP(cell[2], 0, fds->res[2] - 1);
@@ -4385,7 +4409,7 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
fds->res,
correct);
- // convention -> from a RGBA float array, use G value for t_ray
+ /* Convention -> from a RGBA float array, use G value for t_ray. */
shadow[index] = t_ray;
}
}
@@ -4879,6 +4903,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd)
fmd->domain->particle_radius = 1.0f;
fmd->domain->particle_band_width = 3.0f;
fmd->domain->fractions_threshold = 0.05f;
+ fmd->domain->sys_particle_maximum = 0;
/* diffusion options*/
fmd->domain->surface_tension = 0.0f;
@@ -5123,6 +5148,7 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd,
tfds->particle_radius = fds->particle_radius;
tfds->particle_band_width = fds->particle_band_width;
tfds->fractions_threshold = fds->fractions_threshold;
+ tfds->sys_particle_maximum = fds->sys_particle_maximum;
/* diffusion options*/
tfds->surface_tension = fds->surface_tension;
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index dfa5ff6975f..958acf0589b 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -797,7 +797,7 @@ static bool vfont_to_curve(Object *ob,
}
else {
char32_t *mem_tmp;
- slen = cu->len_wchar;
+ slen = cu->len_char32;
/* Create unicode string */
mem_tmp = MEM_malloc_arrayN((slen + 1), sizeof(*mem_tmp), "convertedmem");
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 6a9511d8275..eeb55c44d6e 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -681,10 +681,10 @@ void BKE_gpencil_stroke_weights_duplicate(bGPDstroke *gps_src, bGPDstroke *gps_d
}
/**
- * Make a copy of a given gpencil stroke.
- * \param gps_src: Source grease pencil strokeyes
- * \param dup_points: Duplicate points data
- * \return Pointer to new stroke
+ * Make a copy of a given grease-pencil stroke.
+ * \param gps_src: Source grease pencil strokes.
+ * \param dup_points: Duplicate points data.
+ * \return Pointer to new stroke.
*/
bGPDstroke *BKE_gpencil_stroke_duplicate(bGPDstroke *gps_src, const bool dup_points)
{
@@ -1512,12 +1512,12 @@ int BKE_gpencil_object_material_ensure(Main *bmain, Object *ob, Material *materi
}
/**
- * Creates a new gpencil material and assigns it to object.
+ * Creates a new grease-pencil material and assigns it to object.
* \param bmain: Main pointer
* \param ob: Grease pencil object
* \param name: Material name
* \param r_index: value is set to zero based index of the new material if \a r_index is not NULL.
- * \return Materil pointer
+ * \return Material pointer.
*/
Material *BKE_gpencil_object_material_new(Main *bmain, Object *ob, const char *name, int *r_index)
{
@@ -1555,7 +1555,7 @@ Material *BKE_gpencil_object_material_from_brush_get(Object *ob, Brush *brush)
* Returns the material index for a brush with respect to its pinned state.
* \param ob: Grease pencil object
* \param brush: Brush
- * \return Materil index
+ * \return Material index.
*/
int BKE_gpencil_object_material_get_index_from_brush(Object *ob, Brush *brush)
{
@@ -1571,8 +1571,7 @@ int BKE_gpencil_object_material_get_index_from_brush(Object *ob, Brush *brush)
* Guaranteed to return a material assigned to object. Returns never NULL.
* \param bmain: Main pointer
* \param ob: Grease pencil object
- * \param ts: Toolsettings
- * \return Material pointer
+ * \return Material pointer.
*/
Material *BKE_gpencil_object_material_ensure_from_active_input_toolsettings(Main *bmain,
Object *ob,
@@ -1590,7 +1589,7 @@ Material *BKE_gpencil_object_material_ensure_from_active_input_toolsettings(Main
/**
* Guaranteed to return a material assigned to object. Returns never NULL.
* \param bmain: Main pointer
- * \param ob: Grease pencil obejct
+ * \param ob: Grease pencil object.
* \param brush: Brush
* \return Material pointer
*/
@@ -1783,7 +1782,8 @@ float BKE_gpencil_multiframe_falloff_calc(
value = BKE_curvemapping_evaluateF(cur_falloff, 0, fnum + 0.5f);
}
else {
- value = 1.0f;
+ /* Center of the curve. */
+ value = BKE_curvemapping_evaluateF(cur_falloff, 0, 0.5f);
}
return value;
@@ -2330,8 +2330,8 @@ void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
/**
* Update original pointers in evaluated frame.
- * \param gpf_orig: Original greas epencil frame
- * \param gpf_eval: Evaluated grease pencil frame
+ * \param gpf_orig: Original grease-pencil frame.
+ * \param gpf_eval: Evaluated grease pencil frame.
*/
void BKE_gpencil_frame_original_pointers_update(const struct bGPDframe *gpf_orig,
const struct bGPDframe *gpf_eval)
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index 66e9e2184c1..a7adbed6c4b 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -363,7 +363,7 @@ static void gpencil_convert_spline(Main *bmain,
BKE_nurb_makeCurve(nu, coord_array, NULL, NULL, NULL, resolu, sizeof(float[3]));
/* Allocate memory for storage points. */
- gps->totpoints = nurb_points - 1;
+ gps->totpoints = nurb_points;
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
/* Add points. */
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 49940c2d466..14eb6bb4f4c 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -33,6 +33,7 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
+#include "BLI_hash.h"
#include "BLI_math_vector.h"
#include "BLI_polyfill_2d.h"
@@ -989,7 +990,7 @@ bool BKE_gpencil_stroke_smooth_uv(bGPDstroke *gps, int point_index, float influe
* \param points: Array of grease pencil points (3D)
* \param totpoints: Total of points
* \param points2d: Result array of 2D points
- * \param r_direction: Return Concave (-1), Convex (1), or Autodetect (0)
+ * \param r_direction: Return Concave (-1), Convex (1), or Auto-detect (0)
*/
void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
int totpoints,
@@ -1043,7 +1044,7 @@ void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
points2d[i][1] = dot_v3v3(loc, locy);
}
- /* Concave (-1), Convex (1), or Autodetect (0)? */
+ /* Concave (-1), Convex (1), or Auto-detect (0)? */
*r_direction = (int)locy[2];
}
@@ -1056,7 +1057,7 @@ void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
* \param totpoints: Total points
* \param points2d: Result array of 2D points
* \param scale: Scale factor
- * \param r_direction: Return Concave (-1), Convex (1), or Autodetect (0)
+ * \param r_direction: Return Concave (-1), Convex (1), or Auto-detect (0)
*/
void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points,
int ref_totpoints,
@@ -1138,7 +1139,7 @@ void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points,
points2d[i][1] = dot_v3v3(loc, locy);
}
- /* Concave (-1), Convex (1), or Autodetect (0)? */
+ /* Concave (-1), Convex (1), or Auto-detect (0)? */
*r_direction = (int)locy[2];
}
@@ -1146,7 +1147,7 @@ void BKE_gpencil_stroke_2d_flat_ref(const bGPDspoint *ref_points,
static void gpencil_calc_stroke_fill_uv(const float (*points2d)[2],
bGPDstroke *gps,
const float minv[2],
- float maxv[2],
+ const float maxv[2],
float (*r_uv)[2])
{
const float s = sin(gps->uv_rotation);
@@ -1289,9 +1290,9 @@ void BKE_gpencil_stroke_geometry_update(bGPDstroke *gps)
/**
* Calculate grease pencil stroke length.
- * @param gps Grease pencil stroke
- * @param use_3d Set to true to use 3D points
- * @return Length of the stroke
+ * \param gps: Grease pencil stroke
+ * \param use_3d: Set to true to use 3D points
+ * \return Length of the stroke
*/
float BKE_gpencil_stroke_length(const bGPDstroke *gps, bool use_3d)
{
@@ -2088,6 +2089,7 @@ static int gpencil_walk_edge(GHash *v_table,
static void gpencil_generate_edgeloops(Object *ob,
bGPDframe *gpf_stroke,
+ int stroke_mat_index,
const float angle,
const int thickness,
const float offset,
@@ -2175,7 +2177,7 @@ static void gpencil_generate_edgeloops(Object *ob,
/* Create Stroke. */
bGPDstroke *gps_stroke = BKE_gpencil_stroke_add(
- gpf_stroke, 0, array_len + 1, thickness * thickness, false);
+ gpf_stroke, MAX2(stroke_mat_index, 0), array_len + 1, thickness * thickness, false);
/* Create first segment. */
float fpt[3];
@@ -2258,6 +2260,19 @@ static Material *gpencil_add_material(Main *bmain,
return mat_gp;
}
+static int gpencil_material_find_index_by_name_prefix(Object *ob, const char *name_prefix)
+{
+ const int name_prefix_len = strlen(name_prefix);
+ for (int i = 0; i < ob->totcol; i++) {
+ Material *ma = BKE_object_material_get(ob, i + 1);
+ if ((ma != NULL) && (ma->gp_style != NULL) &&
+ (STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len))) {
+ return i;
+ }
+ }
+
+ return -1;
+}
/**
* Convert a mesh object to grease pencil stroke.
*
@@ -2273,6 +2288,7 @@ static Material *gpencil_add_material(Main *bmain,
* \param frame_offset: Destination frame number offset.
* \param use_seams: Only export seam edges.
* \param use_faces: Export faces as filled strokes.
+ * \simple_material: Create only 2 materials (stroke and fill)
*/
void BKE_gpencil_convert_mesh(Main *bmain,
Depsgraph *depsgraph,
@@ -2285,7 +2301,8 @@ void BKE_gpencil_convert_mesh(Main *bmain,
const float matrix[4][4],
const int frame_offset,
const bool use_seams,
- const bool use_faces)
+ const bool use_faces,
+ const bool simple_material)
{
if (ELEM(NULL, ob_gp, ob_mesh) || (ob_gp->type != OB_GPENCIL) || (ob_gp->data == NULL)) {
return;
@@ -2300,6 +2317,8 @@ void BKE_gpencil_convert_mesh(Main *bmain,
MLoop *mloop = me_eval->mloop;
int mpoly_len = me_eval->totpoly;
int i;
+ int stroke_mat_index = gpencil_material_find_index_by_name_prefix(ob_gp, "Stroke");
+ int fill_mat_index = gpencil_material_find_index_by_name_prefix(ob_gp, "Fill");
/* If the object has enough materials means it was created in a previous step. */
const bool create_mat = ((ob_gp->totcol > 0) && (ob_gp->totcol >= ob_mesh->totcol)) ? false :
@@ -2314,12 +2333,15 @@ void BKE_gpencil_convert_mesh(Main *bmain,
const float default_colors[2][4] = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.7f, 0.7f, 0.7f, 1.0f}};
/* Create stroke material. */
if (create_mat) {
- gpencil_add_material(bmain, ob_gp, "Stroke", default_colors[0], true, false, &r_idx);
+ if (stroke_mat_index == -1) {
+ gpencil_add_material(bmain, ob_gp, "Stroke", default_colors[0], true, false, &r_idx);
+ stroke_mat_index = ob_gp->totcol - 1;
+ }
}
/* Export faces as filled strokes. */
if (use_faces) {
if (create_mat) {
- /* Find a material slot with material assigned */
+ /* Find a material slot with material assigned. */
bool material_found = false;
for (i = 0; i < ob_mesh->totcol; i++) {
Material *ma = BKE_object_material_get(ob_mesh, i + 1);
@@ -2329,9 +2351,12 @@ void BKE_gpencil_convert_mesh(Main *bmain,
}
}
- /* If no materials, create a simple fill. */
- if (!material_found) {
- gpencil_add_material(bmain, ob_gp, "Fill", default_colors[1], false, true, &r_idx);
+ /* If no materials or use simple materials, create a simple fill. */
+ if ((!material_found) || (simple_material)) {
+ if (fill_mat_index == -1) {
+ gpencil_add_material(bmain, ob_gp, "Fill", default_colors[1], false, true, &r_idx);
+ fill_mat_index = ob_gp->totcol - 1;
+ }
}
else {
/* Create all materials for fill. */
@@ -2359,8 +2384,11 @@ void BKE_gpencil_convert_mesh(Main *bmain,
for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
MLoop *ml = &mloop[mp->loopstart];
/* Create fill stroke. */
- bGPDstroke *gps_fill = BKE_gpencil_stroke_add(
- gpf_fill, mp->mat_nr + 1, mp->totloop, 10, false);
+ int mat_idx = (simple_material) || (mp->mat_nr + 1 > ob_gp->totcol - 1) ?
+ MAX2(fill_mat_index, 0) :
+ mp->mat_nr + 1;
+
+ bGPDstroke *gps_fill = BKE_gpencil_stroke_add(gpf_fill, mat_idx, mp->totloop, 10, false);
gps_fill->flag |= GP_STROKE_CYCLIC;
/* Add points to strokes. */
@@ -2387,7 +2415,8 @@ void BKE_gpencil_convert_mesh(Main *bmain,
}
bGPDframe *gpf_stroke = BKE_gpencil_layer_frame_get(
gpl_stroke, CFRA + frame_offset, GP_GETFRAME_ADD_NEW);
- gpencil_generate_edgeloops(ob_eval, gpf_stroke, angle, thickness, offset, matrix, use_seams);
+ gpencil_generate_edgeloops(
+ ob_eval, gpf_stroke, stroke_mat_index, angle, thickness, offset, matrix, use_seams);
/* Tag for recalculation */
DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
@@ -2395,10 +2424,10 @@ void BKE_gpencil_convert_mesh(Main *bmain,
/**
* Apply grease pencil Transforms.
- * @param gpd Grease pencil data-block
- * @param mat Transformation matrix
+ * \param gpd: Grease pencil data-block
+ * \param mat: Transformation matrix
*/
-void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4])
+void BKE_gpencil_transform(bGPdata *gpd, const float mat[4][4])
{
if (gpd == NULL) {
return;
@@ -2430,4 +2459,152 @@ void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4])
}
}
}
+
+/* Used for "move only origins" in object_data_transform.c */
+int BKE_gpencil_stroke_point_count(bGPdata *gpd)
+{
+ int total_points = 0;
+
+ if (gpd == NULL) {
+ return 0;
+ }
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* FIXME: For now, we just skip parented layers.
+ * Otherwise, we have to update each frame to find
+ * the current parent position/effects.
+ */
+ if (gpl->parent) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ total_points += gps->totpoints;
+ }
+ }
+ }
+ return total_points;
+}
+
+/* Used for "move only origins" in object_data_transform.c */
+void BKE_gpencil_point_coords_get(bGPdata *gpd, GPencilPointCoordinates *elem_data)
+{
+ if (gpd == NULL) {
+ return;
+ }
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* FIXME: For now, we just skip parented layers.
+ * Otherwise, we have to update each frame to find
+ * the current parent position/effects.
+ */
+ if (gpl->parent) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDspoint *pt;
+ int i;
+
+ for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
+ copy_v3_v3(elem_data->co, &pt->x);
+ elem_data->pressure = pt->pressure;
+ elem_data++;
+ }
+ }
+ }
+ }
+}
+
+/* Used for "move only origins" in object_data_transform.c */
+void BKE_gpencil_point_coords_apply(bGPdata *gpd, const GPencilPointCoordinates *elem_data)
+{
+ if (gpd == NULL) {
+ return;
+ }
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* FIXME: For now, we just skip parented layers.
+ * Otherwise, we have to update each frame to find
+ * the current parent position/effects.
+ */
+ if (gpl->parent) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDspoint *pt;
+ int i;
+
+ for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
+ copy_v3_v3(&pt->x, elem_data->co);
+ pt->pressure = elem_data->pressure;
+ elem_data++;
+ }
+
+ /* Distortion may mean we need to re-triangulate. */
+ BKE_gpencil_stroke_geometry_update(gps);
+ }
+ }
+ }
+}
+
+/* Used for "move only origins" in object_data_transform.c */
+void BKE_gpencil_point_coords_apply_with_mat4(bGPdata *gpd,
+ const GPencilPointCoordinates *elem_data,
+ const float mat[4][4])
+{
+ if (gpd == NULL) {
+ return;
+ }
+
+ const float scalef = mat4_to_scale(mat);
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* FIXME: For now, we just skip parented layers.
+ * Otherwise, we have to update each frame to find
+ * the current parent position/effects.
+ */
+ if (gpl->parent) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ bGPDspoint *pt;
+ int i;
+
+ for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) {
+ mul_v3_m4v3(&pt->x, mat, elem_data->co);
+ pt->pressure = elem_data->pressure * scalef;
+ elem_data++;
+ }
+
+ /* Distortion may mean we need to re-triangulate. */
+ BKE_gpencil_stroke_geometry_update(gps);
+ }
+ }
+ }
+}
+
+/**
+ * Set a random color to stroke using vertex color.
+ * \param gps: Stroke
+ */
+void BKE_gpencil_stroke_set_random_color(bGPDstroke *gps)
+{
+ BLI_assert(gps->totpoints > 0);
+
+ float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ bGPDspoint *pt = &gps->points[0];
+ color[0] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints / 5, pt->x + pt->z));
+ color[1] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints + pt->x, pt->y * pt->z + pt->x));
+ color[2] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints - pt->x, pt->z * pt->x + pt->y));
+ for (int i = 0; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ copy_v4_v4(pt->vert_color, color);
+ }
+}
/** \} */
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 24cfc65a8fe..e92bf5a4502 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -197,7 +197,7 @@ static int gpencil_time_modifier(
/**
* Set current grease pencil active frame.
* \param depsgraph: Current depsgraph
- * \param gpd: Grease pencil data-block
+ * \param gpd: Grease pencil data-block.
*/
void BKE_gpencil_frame_active_set(Depsgraph *depsgraph, bGPdata *gpd)
{
@@ -223,8 +223,7 @@ void BKE_gpencil_frame_active_set(Depsgraph *depsgraph, bGPdata *gpd)
}
/**
- * Init grease pencil modifier.
- * \param void
+ * Initialize grease pencil modifier.
*/
void BKE_gpencil_modifier_init(void)
{
@@ -460,7 +459,6 @@ GpencilModifierData *BKE_gpencil_modifiers_findby_type(Object *ob, GpencilModifi
* Set grease pencil modifier error.
* \param md: Modifier data
* \param _format: Format
- * \param
*/
void BKE_gpencil_modifier_set_error(GpencilModifierData *md, const char *_format, ...)
{
@@ -560,8 +558,8 @@ static int gpencil_remap_time_get(Depsgraph *depsgraph, Scene *scene, Object *ob
return remap_cfra;
}
-/** Get the current frame retimed with time modifiers.
- * \param depsgraph: Current depsgraph
+/** Get the current frame re-timed with time modifiers.
+ * \param depsgraph: Current depsgraph.
* \param scene: Current scene
* \param ob: Grease pencil object
* \param gpl: Grease pencil layer
diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c
index 2684e964eb1..1166ad9ad2f 100644
--- a/source/blender/blenkernel/intern/idtype.c
+++ b/source/blender/blenkernel/intern/idtype.c
@@ -36,8 +36,11 @@
#include "BLT_translation.h"
#include "DNA_ID.h"
+#include "DNA_node_types.h"
+#include "DNA_scene_types.h"
#include "BKE_main.h"
+#include "BKE_node.h"
#include "BKE_idtype.h"
@@ -470,3 +473,33 @@ short BKE_idtype_idcode_iter_step(int *index)
{
return (*index < ARRAY_SIZE(id_types)) ? BKE_idtype_idcode_from_index((*index)++) : 0;
}
+
+/** Wrapper around IDTypeInfo foreach_cache that also handles embedded IDs. */
+void BKE_idtype_id_foreach_cache(struct ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data)
+{
+ const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id);
+ if (type_info->foreach_cache != NULL) {
+ type_info->foreach_cache(id, function_callback, user_data);
+ }
+
+ /* Handle 'private IDs'. */
+ bNodeTree *nodetree = ntreeFromID(id);
+ if (nodetree != NULL) {
+ type_info = BKE_idtype_get_info_from_id(&nodetree->id);
+ if (type_info->foreach_cache != NULL) {
+ type_info->foreach_cache(&nodetree->id, function_callback, user_data);
+ }
+ }
+
+ if (GS(id->name) == ID_SCE) {
+ Scene *scene = (Scene *)id;
+ if (scene->master_collection != NULL) {
+ type_info = BKE_idtype_get_info_from_id(&scene->master_collection->id);
+ if (type_info->foreach_cache != NULL) {
+ type_info->foreach_cache(&scene->master_collection->id, function_callback, user_data);
+ }
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 41ef5dc00ef..e331e5ae1dd 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -57,6 +57,7 @@
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_simulation_types.h"
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
@@ -64,7 +65,7 @@
#include "BLI_mempool.h"
#include "BLI_system.h"
#include "BLI_threads.h"
-#include "BLI_timecode.h" /* for stamp timecode format */
+#include "BLI_timecode.h" /* For stamp time-code format. */
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -89,7 +90,6 @@
#include "RE_pipeline.h"
-#include "GPU_draw.h"
#include "GPU_texture.h"
#include "BLI_sys_types.h" // for intptr_t support
@@ -195,24 +195,24 @@ static void image_foreach_cache(ID *id,
.offset_in_ID = offsetof(Image, cache),
.cache_v = image->cache,
};
- function_callback(id, &key, (void **)&image->cache, user_data);
+ function_callback(id, &key, (void **)&image->cache, 0, user_data);
for (int eye = 0; eye < 2; eye++) {
for (int a = 0; a < TEXTARGET_COUNT; a++) {
key.offset_in_ID = offsetof(Image, gputexture[a][eye]);
key.cache_v = image->gputexture[a][eye];
- function_callback(id, &key, (void **)&image->gputexture[a][eye], user_data);
+ function_callback(id, &key, (void **)&image->gputexture[a][eye], 0, user_data);
}
}
key.offset_in_ID = offsetof(Image, rr);
key.cache_v = image->rr;
- function_callback(id, &key, (void **)&image->rr, user_data);
+ function_callback(id, &key, (void **)&image->rr, 0, user_data);
LISTBASE_FOREACH (RenderSlot *, slot, &image->renderslots) {
key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(slot->name);
key.cache_v = slot->render;
- function_callback(id, &key, (void **)&slot->render, user_data);
+ function_callback(id, &key, (void **)&slot->render, 0, user_data);
}
}
@@ -392,7 +392,7 @@ void BKE_image_free_buffers_ex(Image *ima, bool do_lock)
ima->rr = NULL;
}
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
tile->ok = IMA_OK;
@@ -3240,6 +3240,12 @@ static void image_walk_id_all_users(
if (scene->nodetree && scene->use_nodes && !skip_nested_nodes) {
image_walk_ntree_all_users(scene->nodetree, &scene->id, customdata, callback);
}
+ break;
+ }
+ case ID_SIM: {
+ Simulation *simulation = (Simulation *)id;
+ image_walk_ntree_all_users(simulation->nodetree, &simulation->id, customdata, callback);
+ break;
}
default:
break;
@@ -3344,8 +3350,7 @@ static void image_free_tile(Image *ima, ImageTile *tile)
for (int i = 0; i < TEXTARGET_COUNT; i++) {
/* Only two textures depends on all tiles, so if this is a secondary tile we can keep the other
* two. */
- if (tile != ima->tiles.first &&
- !(ELEM(i, TEXTARGET_TEXTURE_2D_ARRAY, TEXTARGET_TEXTURE_TILE_MAPPING))) {
+ if (tile != ima->tiles.first && !(ELEM(i, TEXTARGET_2D_ARRAY, TEXTARGET_TILE_MAPPING))) {
continue;
}
@@ -3622,13 +3627,13 @@ ImageTile *BKE_image_add_tile(struct Image *ima, int tile_number, const char *la
for (int eye = 0; eye < 2; eye++) {
/* Reallocate GPU tile array. */
- if (ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye]);
- ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] = NULL;
+ if (ima->gputexture[TEXTARGET_2D_ARRAY][eye] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye]);
+ ima->gputexture[TEXTARGET_2D_ARRAY][eye] = NULL;
}
- if (ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye]);
- ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] = NULL;
+ if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye]);
+ ima->gputexture[TEXTARGET_TILE_MAPPING][eye] = NULL;
}
}
@@ -3937,7 +3942,7 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
#endif /* WITH_OPENEXR */
/* common stuff to do with images after loading */
-static void image_initialize_after_load(Image *ima, ImageUser *iuser, ImBuf *UNUSED(ibuf))
+static void image_init_after_load(Image *ima, ImageUser *iuser, ImBuf *UNUSED(ibuf))
{
/* Preview is NULL when it has never been used as an icon before.
* Never handle previews/icons outside of main thread. */
@@ -4040,11 +4045,11 @@ static ImBuf *load_sequence_single(
}
}
else {
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
*r_assign = true;
}
#else
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
*r_assign = true;
#endif
}
@@ -4149,7 +4154,7 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int e
BKE_imbuf_stamp_info(ima->rr, ibuf);
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
image_assign_ibuf(ima, ibuf, iuser ? iuser->multi_index : 0, entry);
}
// else printf("pass not found\n");
@@ -4213,7 +4218,7 @@ static ImBuf *load_movie_single(Image *ima, ImageUser *iuser, int frame, const i
ibuf = IMB_makeSingleUser(IMB_anim_absolute(ia->anim, fra, IMB_TC_RECORD_RUN, IMB_PROXY_NONE));
if (ibuf) {
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
}
else {
tile->ok = 0;
@@ -4358,12 +4363,12 @@ static ImBuf *load_image_single(Image *ima,
else
#endif
{
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
*r_assign = true;
/* make packed file for autopack */
if ((has_packed == false) && (G.fileflags & G_FILE_AUTOPACK)) {
- ImagePackedFile *imapf = MEM_mallocN(sizeof(ImagePackedFile), "Image Packefile");
+ ImagePackedFile *imapf = MEM_mallocN(sizeof(ImagePackedFile), "Image Pack-file");
BLI_addtail(&ima->packedfiles, imapf);
STRNCPY(imapf->filepath, filepath);
@@ -4472,7 +4477,7 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
if (rpass) {
ibuf = IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0);
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
ibuf->rect_float = rpass->rect;
ibuf->flags |= IB_rectfloat;
@@ -5213,24 +5218,32 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, bool *r_is_in_ran
void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
{
if (iuser) {
- bool is_in_range;
- const int framenr = BKE_image_user_frame_get(iuser, cfra, &is_in_range);
+ if (ima && BKE_image_is_animated(ima)) {
+ /* Compute current frame for animated image. */
+ bool is_in_range;
+ const int framenr = BKE_image_user_frame_get(iuser, cfra, &is_in_range);
- if (is_in_range) {
- iuser->flag |= IMA_USER_FRAME_IN_RANGE;
+ if (is_in_range) {
+ iuser->flag |= IMA_USER_FRAME_IN_RANGE;
+ }
+ else {
+ iuser->flag &= ~IMA_USER_FRAME_IN_RANGE;
+ }
+
+ iuser->framenr = framenr;
}
else {
- iuser->flag &= ~IMA_USER_FRAME_IN_RANGE;
+ /* Set fixed frame number for still image. */
+ iuser->framenr = 0;
+ iuser->flag |= IMA_USER_FRAME_IN_RANGE;
}
- iuser->framenr = framenr;
-
- if (ima && BKE_image_is_animated(ima) && ima->gpuframenr != framenr) {
+ if (ima && ima->gpuframenr != iuser->framenr) {
/* Note: a single texture and refresh doesn't really work when
* multiple image users may use different frames, this is to
* be improved with perhaps a GPU texture cache. */
ima->gpuflag |= IMA_GPU_REFRESH;
- ima->gpuframenr = framenr;
+ ima->gpuframenr = iuser->framenr;
}
if (iuser->ok == 0) {
diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c
new file mode 100644
index 00000000000..22fb6dfd02a
--- /dev/null
+++ b/source/blender/blenkernel/intern/image_gpu.c
@@ -0,0 +1,774 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_boxpack_2d.h"
+#include "BLI_linklist.h"
+#include "BLI_listbase.h"
+#include "BLI_threads.h"
+
+#include "DNA_image_types.h"
+#include "DNA_userdef_types.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+
+#include "GPU_extensions.h"
+#include "GPU_state.h"
+#include "GPU_texture.h"
+
+#include "PIL_time.h"
+
+/* Prototypes. */
+static void gpu_free_unused_buffers(void);
+static void image_free_gpu(Image *ima, const bool immediate);
+
+/* -------------------------------------------------------------------- */
+/** \name UDIM gpu texture
+ * \{ */
+
+static bool is_over_resolution_limit(int w, int h)
+{
+ return (w > GPU_texture_size_with_limit(w) || h > GPU_texture_size_with_limit(h));
+}
+
+static int smaller_power_of_2_limit(int num)
+{
+ return power_of_2_min_i(GPU_texture_size_with_limit(num));
+}
+
+static GPUTexture *gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye)
+{
+ GPUTexture *tilearray = ima->gputexture[TEXTARGET_2D_ARRAY][multiview_eye];
+
+ if (tilearray == NULL) {
+ return 0;
+ }
+
+ float array_w = GPU_texture_width(tilearray);
+ float array_h = GPU_texture_height(tilearray);
+
+ ImageTile *last_tile = (ImageTile *)ima->tiles.last;
+ /* Tiles are sorted by number. */
+ int max_tile = last_tile->tile_number - 1001;
+
+ /* create image */
+ int width = max_tile + 1;
+ float *data = (float *)MEM_callocN(width * 8 * sizeof(float), __func__);
+ for (int i = 0; i < width; i++) {
+ data[4 * i] = -1.0f;
+ }
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ int i = tile->tile_number - 1001;
+ data[4 * i] = tile->runtime.tilearray_layer;
+
+ float *tile_info = &data[4 * width + 4 * i];
+ tile_info[0] = tile->runtime.tilearray_offset[0] / array_w;
+ tile_info[1] = tile->runtime.tilearray_offset[1] / array_h;
+ tile_info[2] = tile->runtime.tilearray_size[0] / array_w;
+ tile_info[3] = tile->runtime.tilearray_size[1] / array_h;
+ }
+
+ GPUTexture *tex = GPU_texture_create_1d_array(width, 2, GPU_RGBA32F, data, NULL);
+ GPU_texture_mipmap_mode(tex, false, false);
+
+ MEM_freeN(data);
+
+ return tex;
+}
+
+typedef struct PackTile {
+ FixedSizeBoxPack boxpack;
+ ImageTile *tile;
+ float pack_score;
+} PackTile;
+
+static int compare_packtile(const void *a, const void *b)
+{
+ const PackTile *tile_a = (const PackTile *)a;
+ const PackTile *tile_b = (const PackTile *)b;
+
+ return tile_a->pack_score < tile_b->pack_score;
+}
+
+static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
+{
+ int arraywidth = 0, arrayheight = 0;
+ ListBase boxes = {NULL};
+
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
+ iuser.tile = tile->tile_number;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+
+ if (ibuf) {
+ PackTile *packtile = (PackTile *)MEM_callocN(sizeof(PackTile), __func__);
+ packtile->tile = tile;
+ packtile->boxpack.w = ibuf->x;
+ packtile->boxpack.h = ibuf->y;
+
+ if (is_over_resolution_limit(packtile->boxpack.w, packtile->boxpack.h)) {
+ packtile->boxpack.w = smaller_power_of_2_limit(packtile->boxpack.w);
+ packtile->boxpack.h = smaller_power_of_2_limit(packtile->boxpack.h);
+ }
+ arraywidth = max_ii(arraywidth, packtile->boxpack.w);
+ arrayheight = max_ii(arrayheight, packtile->boxpack.h);
+
+ /* We sort the tiles by decreasing size, with an additional penalty term
+ * for high aspect ratios. This improves packing efficiency. */
+ float w = packtile->boxpack.w, h = packtile->boxpack.h;
+ packtile->pack_score = max_ff(w, h) / min_ff(w, h) * w * h;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ BLI_addtail(&boxes, packtile);
+ }
+ }
+
+ BLI_assert(arraywidth > 0 && arrayheight > 0);
+
+ BLI_listbase_sort(&boxes, compare_packtile);
+ int arraylayers = 0;
+ /* Keep adding layers until all tiles are packed. */
+ while (boxes.first != NULL) {
+ ListBase packed = {NULL};
+ BLI_box_pack_2d_fixedarea(&boxes, arraywidth, arrayheight, &packed);
+ BLI_assert(packed.first != NULL);
+
+ LISTBASE_FOREACH (PackTile *, packtile, &packed) {
+ ImageTile *tile = packtile->tile;
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int *tilesize = tile->runtime.tilearray_size;
+
+ tileoffset[0] = packtile->boxpack.x;
+ tileoffset[1] = packtile->boxpack.y;
+ tilesize[0] = packtile->boxpack.w;
+ tilesize[1] = packtile->boxpack.h;
+ tile->runtime.tilearray_layer = arraylayers;
+ }
+
+ BLI_freelistN(&packed);
+ arraylayers++;
+ }
+
+ const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH);
+ /* Create Texture without content. */
+ GPUTexture *tex = IMB_touch_gpu_texture(
+ main_ibuf, arraywidth, arrayheight, arraylayers, use_high_bitdepth);
+
+ GPU_texture_bind(tex, 0);
+
+ /* Upload each tile one by one. */
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ int tilelayer = tile->runtime.tilearray_layer;
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int *tilesize = tile->runtime.tilearray_size;
+
+ if (tilesize[0] == 0 || tilesize[1] == 0) {
+ continue;
+ }
+
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
+ iuser.tile = tile->tile_number;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+
+ if (ibuf) {
+ const bool store_premultiplied = ibuf->rect_float ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) :
+ (ima->alpha_mode == IMA_ALPHA_PREMUL);
+ IMB_update_gpu_texture_sub(tex,
+ ibuf,
+ UNPACK2(tileoffset),
+ tilelayer,
+ UNPACK2(tilesize),
+ use_high_bitdepth,
+ store_premultiplied);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+
+ if (GPU_mipmap_enabled()) {
+ GPU_texture_generate_mipmap(tex);
+ GPU_texture_mipmap_mode(tex, true, true);
+ if (ima) {
+ ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
+ }
+ }
+ else {
+ GPU_texture_mipmap_mode(tex, false, true);
+ }
+
+ GPU_texture_unbind(tex);
+
+ return tex;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Regular gpu texture
+ * \{ */
+
+static GPUTexture **get_image_gpu_texture_ptr(Image *ima,
+ eGPUTextureTarget textarget,
+ const int multiview_eye)
+{
+ const bool in_range = (textarget >= 0) && (textarget < TEXTARGET_COUNT);
+ BLI_assert(in_range);
+
+ if (in_range) {
+ return &(ima->gputexture[textarget][multiview_eye]);
+ }
+ return NULL;
+}
+
+static GPUTexture *image_gpu_texture_error_create(eGPUTextureTarget textarget)
+{
+ switch (textarget) {
+ case TEXTARGET_2D_ARRAY:
+ return GPU_texture_create_error(2, true);
+ case TEXTARGET_TILE_MAPPING:
+ return GPU_texture_create_error(1, true);
+ case TEXTARGET_2D:
+ default:
+ return GPU_texture_create_error(2, false);
+ }
+}
+
+static GPUTexture *image_get_gpu_texture(Image *ima,
+ ImageUser *iuser,
+ ImBuf *ibuf,
+ eGPUTextureTarget textarget)
+{
+ if (ima == NULL) {
+ return NULL;
+ }
+
+ /* Free any unused GPU textures, since we know we are in a thread with OpenGL
+ * context and might as well ensure we have as much space free as possible. */
+ gpu_free_unused_buffers();
+
+ /* currently, gpu refresh tagging is used by ima sequences */
+ if (ima->gpuflag & IMA_GPU_REFRESH) {
+ image_free_gpu(ima, true);
+ ima->gpuflag &= ~IMA_GPU_REFRESH;
+ }
+
+ /* Tag as in active use for garbage collector. */
+ BKE_image_tag_time(ima);
+
+ /* Test if we already have a texture. */
+ GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, iuser ? iuser->multiview_eye : 0);
+ if (*tex) {
+ return *tex;
+ }
+
+ /* Check if we have a valid image. If not, we return a dummy
+ * texture with zero bind-code so we don't keep trying. */
+ ImageTile *tile = BKE_image_get_tile(ima, 0);
+ if (tile == NULL || tile->ok == 0) {
+ *tex = image_gpu_texture_error_create(textarget);
+ return *tex;
+ }
+
+ /* check if we have a valid image buffer */
+ ImBuf *ibuf_intern = ibuf;
+ if (ibuf_intern == NULL) {
+ ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ if (ibuf_intern == NULL) {
+ *tex = image_gpu_texture_error_create(textarget);
+ return *tex;
+ }
+ }
+
+ if (textarget == TEXTARGET_2D_ARRAY) {
+ *tex = gpu_texture_create_tile_array(ima, ibuf_intern);
+ }
+ else if (textarget == TEXTARGET_TILE_MAPPING) {
+ *tex = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0);
+ }
+ else {
+ const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH);
+ const bool store_premultiplied = ibuf_intern->rect_float ?
+ (ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false) :
+ (ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true);
+
+ *tex = IMB_create_gpu_texture(ibuf_intern, use_high_bitdepth, store_premultiplied);
+
+ if (GPU_mipmap_enabled()) {
+ GPU_texture_bind(*tex, 0);
+ GPU_texture_generate_mipmap(*tex);
+ GPU_texture_unbind(*tex);
+ if (ima) {
+ ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
+ }
+ GPU_texture_mipmap_mode(*tex, true, true);
+ }
+ else {
+ GPU_texture_mipmap_mode(*tex, false, true);
+ }
+ }
+
+ /* if `ibuf` was given, we don't own the `ibuf_intern` */
+ if (ibuf == NULL) {
+ BKE_image_release_ibuf(ima, ibuf_intern, NULL);
+ }
+
+ GPU_texture_orig_size_set(*tex, ibuf_intern->x, ibuf_intern->y);
+
+ return *tex;
+}
+
+GPUTexture *BKE_image_get_gpu_texture(Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_2D);
+}
+
+GPUTexture *BKE_image_get_gpu_tiles(Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_2D_ARRAY);
+}
+
+GPUTexture *BKE_image_get_gpu_tilemap(Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_TILE_MAPPING);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delayed GPU texture free
+ *
+ * Image datablocks can be deleted by any thread, but there may not be any active OpenGL context.
+ * In that case we push them into a queue and free the buffers later.
+ * \{ */
+
+static LinkNode *gpu_texture_free_queue = NULL;
+static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER;
+
+static void gpu_free_unused_buffers(void)
+{
+ if (gpu_texture_free_queue == NULL) {
+ return;
+ }
+
+ BLI_mutex_lock(&gpu_texture_queue_mutex);
+
+ while (gpu_texture_free_queue != NULL) {
+ GPUTexture *tex = BLI_linklist_pop(&gpu_texture_free_queue);
+ GPU_texture_free(tex);
+ }
+
+ BLI_mutex_unlock(&gpu_texture_queue_mutex);
+}
+
+void BKE_image_free_unused_gpu_textures()
+{
+ if (BLI_thread_is_main()) {
+ gpu_free_unused_buffers();
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Deletion
+ * \{ */
+
+static void image_free_gpu(Image *ima, const bool immediate)
+{
+ for (int eye = 0; eye < 2; eye++) {
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ if (ima->gputexture[i][eye] != NULL) {
+ if (immediate) {
+ GPU_texture_free(ima->gputexture[i][eye]);
+ }
+ else {
+ BLI_mutex_lock(&gpu_texture_queue_mutex);
+ BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]);
+ BLI_mutex_unlock(&gpu_texture_queue_mutex);
+ }
+
+ ima->gputexture[i][eye] = NULL;
+ }
+ }
+ }
+
+ ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+}
+
+void BKE_image_free_gputextures(Image *ima)
+{
+ image_free_gpu(ima, BLI_thread_is_main());
+}
+
+void BKE_image_free_all_gputextures(Main *bmain)
+{
+ if (bmain) {
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ BKE_image_free_gputextures(ima);
+ }
+ }
+}
+
+/* same as above but only free animated images */
+void BKE_image_free_anim_gputextures(Main *bmain)
+{
+ if (bmain) {
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if (BKE_image_is_animated(ima)) {
+ BKE_image_free_gputextures(ima);
+ }
+ }
+ }
+}
+
+void BKE_image_free_old_gputextures(Main *bmain)
+{
+ static int lasttime = 0;
+ int ctime = (int)PIL_check_seconds_timer();
+
+ /*
+ * Run garbage collector once for every collecting period of time
+ * if textimeout is 0, that's the option to NOT run the collector
+ */
+ if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime) {
+ return;
+ }
+
+ /* of course not! */
+ if (G.is_rendering) {
+ return;
+ }
+
+ lasttime = ctime;
+
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
+ /* If it's in GL memory, deallocate and set time tag to current time
+ * This gives textures a "second chance" to be used before dying. */
+ if (BKE_image_has_opengl_texture(ima)) {
+ BKE_image_free_gputextures(ima);
+ ima->lastused = ctime;
+ }
+ /* Otherwise, just kill the buffers */
+ else {
+ BKE_image_free_buffers(ima);
+ }
+ }
+ }
+}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Paint Update
+ * \{ */
+
+static ImBuf *update_do_scale(uchar *rect,
+ float *rect_float,
+ int *x,
+ int *y,
+ int *w,
+ int *h,
+ int limit_w,
+ int limit_h,
+ int full_w,
+ int full_h)
+{
+ /* Partial update with scaling. */
+ float xratio = limit_w / (float)full_w;
+ float yratio = limit_h / (float)full_h;
+
+ int part_w = *w, part_h = *h;
+
+ /* Find sub coordinates in scaled image. Take ceiling because we will be
+ * losing 1 pixel due to rounding errors in x,y. */
+ *x *= xratio;
+ *y *= yratio;
+ *w = (int)ceil(xratio * (*w));
+ *h = (int)ceil(yratio * (*h));
+
+ /* ...but take back if we are over the limit! */
+ if (*x + *w > limit_w) {
+ (*w)--;
+ }
+ if (*y + *h > limit_h) {
+ (*h)--;
+ }
+
+ /* Scale pixels. */
+ ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, part_w, part_h, 4);
+ IMB_scaleImBuf(ibuf, *w, *h);
+
+ return ibuf;
+}
+
+static void gpu_texture_update_scaled(GPUTexture *tex,
+ uchar *rect,
+ float *rect_float,
+ int full_w,
+ int full_h,
+ int x,
+ int y,
+ int layer,
+ const int *tile_offset,
+ const int *tile_size,
+ int w,
+ int h)
+{
+ ImBuf *ibuf;
+ if (layer > -1) {
+ ibuf = update_do_scale(
+ rect, rect_float, &x, &y, &w, &h, tile_size[0], tile_size[1], full_w, full_h);
+
+ /* Shift to account for tile packing. */
+ x += tile_offset[0];
+ y += tile_offset[1];
+ }
+ else {
+ /* Partial update with scaling. */
+ int limit_w = smaller_power_of_2_limit(full_w);
+ int limit_h = smaller_power_of_2_limit(full_h);
+
+ ibuf = update_do_scale(rect, rect_float, &x, &y, &w, &h, limit_w, limit_h, full_w, full_h);
+ }
+
+ void *data = (ibuf->rect_float) ? (void *)(ibuf->rect_float) : (void *)(ibuf->rect);
+ eGPUDataFormat data_format = (ibuf->rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+
+ GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1);
+
+ IMB_freeImBuf(ibuf);
+}
+
+static void gpu_texture_update_unscaled(GPUTexture *tex,
+ uchar *rect,
+ float *rect_float,
+ int x,
+ int y,
+ int layer,
+ const int tile_offset[2],
+ int w,
+ int h,
+ int tex_stride,
+ int tex_offset)
+{
+ if (layer > -1) {
+ /* Shift to account for tile packing. */
+ x += tile_offset[0];
+ y += tile_offset[1];
+ }
+
+ void *data = (rect_float) ? (void *)(rect_float + tex_offset) : (void *)(rect + tex_offset);
+ eGPUDataFormat data_format = (rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+
+ /* Partial update without scaling. Stride and offset are used to copy only a
+ * subset of a possible larger buffer than what we are updating. */
+ GPU_unpack_row_length_set(tex_stride);
+
+ GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1);
+ /* Restore default. */
+ GPU_unpack_row_length_set(0);
+}
+
+static void gpu_texture_update_from_ibuf(
+ GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h)
+{
+ bool scaled;
+ if (tile != NULL) {
+ int *tilesize = tile->runtime.tilearray_size;
+ scaled = (ibuf->x != tilesize[0]) || (ibuf->y != tilesize[1]);
+ }
+ else {
+ scaled = is_over_resolution_limit(ibuf->x, ibuf->y);
+ }
+
+ if (scaled) {
+ /* Extra padding to account for bleed from neighboring pixels. */
+ const int padding = 4;
+ const int xmax = min_ii(x + w + padding, ibuf->x);
+ const int ymax = min_ii(y + h + padding, ibuf->y);
+ x = max_ii(x - padding, 0);
+ y = max_ii(y - padding, 0);
+ w = xmax - x;
+ h = ymax - y;
+ }
+
+ /* Get texture data pointers. */
+ float *rect_float = ibuf->rect_float;
+ uchar *rect = (uchar *)ibuf->rect;
+ int tex_stride = ibuf->x;
+ int tex_offset = ibuf->channels * (y * ibuf->x + x);
+
+ if (rect_float == NULL) {
+ /* Byte pixels. */
+ if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
+ const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(
+ ibuf->rect_colorspace);
+
+ rect = (uchar *)MEM_mallocN(sizeof(uchar) * 4 * w * h, __func__);
+ if (rect == NULL) {
+ return;
+ }
+
+ tex_stride = w;
+ tex_offset = 0;
+
+ /* Convert to scene linear with sRGB compression, and premultiplied for
+ * correct texture interpolation. */
+ const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL);
+ IMB_colormanagement_imbuf_to_byte_texture(
+ rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied);
+ }
+ }
+ else {
+ /* Float pixels. */
+ const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT);
+
+ if (ibuf->channels != 4 || scaled || !store_premultiplied) {
+ rect_float = (float *)MEM_mallocN(sizeof(float) * 4 * w * h, __func__);
+ if (rect_float == NULL) {
+ return;
+ }
+
+ tex_stride = w;
+ tex_offset = 0;
+
+ IMB_colormanagement_imbuf_to_float_texture(
+ rect_float, x, y, w, h, ibuf, store_premultiplied);
+ }
+ }
+
+ GPU_texture_bind(tex, 0);
+
+ if (scaled) {
+ /* Slower update where we first have to scale the input pixels. */
+ if (tile != NULL) {
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int *tilesize = tile->runtime.tilearray_size;
+ int tilelayer = tile->runtime.tilearray_layer;
+ gpu_texture_update_scaled(
+ tex, rect, rect_float, ibuf->x, ibuf->y, x, y, tilelayer, tileoffset, tilesize, w, h);
+ }
+ else {
+ gpu_texture_update_scaled(
+ tex, rect, rect_float, ibuf->x, ibuf->y, x, y, -1, NULL, NULL, w, h);
+ }
+ }
+ else {
+ /* Fast update at same resolution. */
+ if (tile != NULL) {
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int tilelayer = tile->runtime.tilearray_layer;
+ gpu_texture_update_unscaled(
+ tex, rect, rect_float, x, y, tilelayer, tileoffset, w, h, tex_stride, tex_offset);
+ }
+ else {
+ gpu_texture_update_unscaled(
+ tex, rect, rect_float, x, y, -1, NULL, w, h, tex_stride, tex_offset);
+ }
+ }
+
+ /* Free buffers if needed. */
+ if (rect && rect != (uchar *)ibuf->rect) {
+ MEM_freeN(rect);
+ }
+ if (rect_float && rect_float != ibuf->rect_float) {
+ MEM_freeN(rect_float);
+ }
+
+ if (GPU_mipmap_enabled()) {
+ GPU_texture_generate_mipmap(tex);
+ }
+ else {
+ ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+ }
+
+ GPU_texture_unbind(tex);
+}
+
+/* Partial update of texture for texture painting. This is often much
+ * quicker than fully updating the texture for high resolution images. */
+void BKE_image_update_gputexture(Image *ima, ImageUser *iuser, int x, int y, int w, int h)
+{
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ ImageTile *tile = BKE_image_get_tile_from_iuser(ima, iuser);
+
+ if ((ibuf == NULL) || (w == 0) || (h == 0)) {
+ /* Full reload of texture. */
+ BKE_image_free_gputextures(ima);
+ }
+
+ GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0];
+ /* Check if we need to update the main gputexture. */
+ if (tex != NULL && tile == ima->tiles.first) {
+ gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h);
+ }
+
+ /* Check if we need to update the array gputexture. */
+ tex = ima->gputexture[TEXTARGET_2D_ARRAY][0];
+ if (tex != NULL) {
+ gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+}
+
+/* these two functions are called on entering and exiting texture paint mode,
+ * temporary disabling/enabling mipmapping on all images for quick texture
+ * updates with glTexSubImage2D. images that didn't change don't have to be
+ * re-uploaded to OpenGL */
+void BKE_image_paint_set_mipmap(Main *bmain, bool mipmap)
+{
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if (BKE_image_has_opengl_texture(ima)) {
+ if (ima->gpuflag & IMA_GPU_MIPMAP_COMPLETE) {
+ for (int eye = 0; eye < 2; eye++) {
+ for (int a = 0; a < TEXTARGET_COUNT; a++) {
+ if (ELEM(a, TEXTARGET_2D, TEXTARGET_2D_ARRAY)) {
+ GPUTexture *tex = ima->gputexture[a][eye];
+ if (tex != NULL) {
+ GPU_texture_mipmap_mode(tex, mipmap, true);
+ }
+ }
+ }
+ }
+ }
+ else {
+ BKE_image_free_gputextures(ima);
+ }
+ }
+ else {
+ ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+ }
+ }
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index af8ab22e14b..a71b9cc2a1d 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -529,7 +529,13 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
return 0;
}
-static void flerp(int tot, float *in, float *f0, float *f1, float *f2, float *f3, float *t)
+static void flerp(int tot,
+ float *in,
+ const float *f0,
+ const float *f1,
+ const float *f2,
+ const float *f3,
+ const float *t)
{
int a;
@@ -538,7 +544,7 @@ static void flerp(int tot, float *in, float *f0, float *f1, float *f2, float *f3
}
}
-static void rel_flerp(int tot, float *in, float *ref, float *out, float fac)
+static void rel_flerp(int tot, float *in, const float *ref, const float *out, float fac)
{
int a;
@@ -1541,6 +1547,134 @@ float *BKE_key_evaluate_object(Object *ob, int *r_totelem)
return BKE_key_evaluate_object_ex(ob, r_totelem, NULL, 0);
}
+/**
+ * \param shape_index: The index to use or all (when -1).
+ */
+int BKE_keyblock_element_count_from_shape(const Key *key, const int shape_index)
+{
+ int result = 0;
+ int index = 0;
+ for (const KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+ if ((shape_index == -1) || (index == shape_index)) {
+ result += kb->totelem;
+ }
+ }
+ return result;
+}
+
+int BKE_keyblock_element_count(const Key *key)
+{
+ return BKE_keyblock_element_count_from_shape(key, -1);
+}
+
+/**
+ * \param shape_index: The index to use or all (when -1).
+ */
+size_t BKE_keyblock_element_calc_size_from_shape(const Key *key, const int shape_index)
+{
+ return (size_t)BKE_keyblock_element_count_from_shape(key, shape_index) * key->elemsize;
+}
+
+size_t BKE_keyblock_element_calc_size(const Key *key)
+{
+ return BKE_keyblock_element_calc_size_from_shape(key, -1);
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Key-Block Data Access
+ *
+ * Utilities for getting/setting key data as a single array,
+ * use #BKE_keyblock_element_calc_size to allocate the size of the data needed.
+ * \{ */
+
+/**
+ * \param shape_index: The index to use or all (when -1).
+ */
+void BKE_keyblock_data_get_from_shape(const Key *key, float (*arr)[3], const int shape_index)
+{
+ uint8_t *elements = (uint8_t *)arr;
+ int index = 0;
+ for (const KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+ if ((shape_index == -1) || (index == shape_index)) {
+ const int block_elem_len = kb->totelem * key->elemsize;
+ memcpy(elements, kb->data, block_elem_len);
+ elements += block_elem_len;
+ }
+ }
+}
+
+void BKE_keyblock_data_get(const Key *key, float (*arr)[3])
+{
+ BKE_keyblock_data_get_from_shape(key, arr, -1);
+}
+
+/**
+ * Set the data to all key-blocks (or shape_index if != -1).
+ */
+void BKE_keyblock_data_set_with_mat4(Key *key,
+ const int shape_index,
+ const float (*coords)[3],
+ const float mat[4][4])
+{
+ if (key->elemsize != sizeof(float[3])) {
+ BLI_assert(!"Invalid elemsize");
+ return;
+ }
+
+ const float(*elements)[3] = coords;
+
+ int index = 0;
+ for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+ if ((shape_index == -1) || (index == shape_index)) {
+ const int block_elem_len = kb->totelem;
+ float(*block_data)[3] = (float(*)[3])kb->data;
+ for (int data_offset = 0; data_offset < block_elem_len; ++data_offset) {
+ const float *src_data = (const float *)(elements + data_offset);
+ float *dst_data = (float *)(block_data + data_offset);
+ mul_v3_m4v3(dst_data, mat, src_data);
+ }
+ elements += block_elem_len;
+ }
+ }
+}
+
+/**
+ * Set the data for all key-blocks (or shape_index if != -1),
+ * transforming by \a mat.
+ */
+void BKE_keyblock_curve_data_set_with_mat4(
+ Key *key, const ListBase *nurb, const int shape_index, const void *data, const float mat[4][4])
+{
+ const uint8_t *elements = data;
+
+ int index = 0;
+ for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+ if ((shape_index == -1) || (index == shape_index)) {
+ const int block_elem_size = kb->totelem * key->elemsize;
+ BKE_keyblock_curve_data_transform(nurb, mat, elements, kb->data);
+ elements += block_elem_size;
+ }
+ }
+}
+
+/**
+ * Set the data for all key-blocks (or shape_index if != -1).
+ */
+void BKE_keyblock_data_set(Key *key, const int shape_index, const void *data)
+{
+ const uint8_t *elements = data;
+ int index = 0;
+ for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) {
+ if ((shape_index == -1) || (index == shape_index)) {
+ const int block_elem_size = kb->totelem * key->elemsize;
+ memcpy(kb->data, elements, block_elem_size);
+ elements += block_elem_size;
+ }
+ }
+}
+
+/** \} */
+
bool BKE_key_idtype_support(const short id_type)
{
switch (id_type) {
@@ -1897,6 +2031,37 @@ void BKE_keyblock_update_from_curve(Curve *UNUSED(cu), KeyBlock *kb, ListBase *n
}
}
+void BKE_keyblock_curve_data_transform(const ListBase *nurb,
+ const float mat[4][4],
+ const void *src_data,
+ void *dst_data)
+{
+ const float *src = src_data;
+ float *dst = dst_data;
+ for (Nurb *nu = nurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ for (int a = nu->pntsu; a; a--) {
+ for (int i = 0; i < 3; i++) {
+ mul_v3_m4v3(&dst[i * 3], mat, &src[i * 3]);
+ }
+ dst[9] = src[9];
+ dst[10] = src[10];
+ src += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ dst += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ }
+ }
+ else {
+ for (int a = nu->pntsu * nu->pntsv; a; a--) {
+ mul_v3_m4v3(dst, mat, src);
+ dst[3] = src[3];
+ dst[4] = src[4];
+ src += KEYELEM_FLOAT_LEN_BPOINT;
+ dst += KEYELEM_FLOAT_LEN_BPOINT;
+ }
+ }
+ }
+}
+
void BKE_keyblock_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
{
int tot;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 8820434cbcf..4d523ffa2e0 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -672,7 +672,7 @@ void BKE_lattice_center_bounds(Lattice *lt, float cent[3])
mid_v3_v3v3(cent, min, max);
}
-void BKE_lattice_transform(Lattice *lt, float mat[4][4], bool do_keys)
+void BKE_lattice_transform(Lattice *lt, const float mat[4][4], bool do_keys)
{
BPoint *bp = lt->def;
int i = lt->pntsu * lt->pntsv * lt->pntsw;
@@ -694,7 +694,7 @@ void BKE_lattice_transform(Lattice *lt, float mat[4][4], bool do_keys)
}
}
-void BKE_lattice_translate(Lattice *lt, float offset[3], bool do_keys)
+void BKE_lattice_translate(Lattice *lt, const float offset[3], bool do_keys)
{
int i, numVerts;
diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c
index 2b3349d4d9a..674ee9ed2c5 100644
--- a/source/blender/blenkernel/intern/lattice_deform.c
+++ b/source/blender/blenkernel/intern/lattice_deform.c
@@ -418,8 +418,8 @@ static void lattice_deform_coords_impl(const Object *ob_lattice,
void BKE_lattice_deform_coords(const Object *ob_lattice,
const Object *ob_target,
float (*vert_coords)[3],
- int vert_coords_len,
- short flag,
+ const int vert_coords_len,
+ const short flag,
const char *defgrp_name,
float fac)
{
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index f03bf60817f..83071fd5dd3 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -221,7 +221,7 @@ ViewLayer *BKE_view_layer_add(Scene *scene,
view_layer_new = view_layer_add(name);
BLI_addtail(&scene->view_layers, view_layer_new);
- /* Initialise layercollections */
+ /* Initialize layer-collections. */
BKE_layer_collection_sync(scene, view_layer_new);
layer_collection_exclude_all(view_layer_new->layer_collections.first);
@@ -695,8 +695,8 @@ int BKE_layer_collection_findindex(ViewLayer *view_layer, const LayerCollection
* stores state like selection. */
static void layer_collection_sync(ViewLayer *view_layer,
- const ListBase *lb_scene,
- ListBase *lb_layer,
+ const ListBase *lb_collections,
+ ListBase *lb_layer_collections,
ListBase *new_object_bases,
short parent_exclude,
short parent_restrict,
@@ -708,11 +708,10 @@ static void layer_collection_sync(ViewLayer *view_layer,
* linking we can only sync after the fact. */
/* Remove layer collections that no longer have a corresponding scene collection. */
- for (LayerCollection *lc = lb_layer->first; lc;) {
- /* Note ID remap can set lc->collection to NULL when deleting collections. */
- LayerCollection *lc_next = lc->next;
+ LISTBASE_FOREACH_MUTABLE (LayerCollection *, lc, lb_layer_collections) {
+ /* Note that ID remap can set lc->collection to NULL when deleting collections. */
Collection *collection = (lc->collection) ?
- BLI_findptr(lb_scene,
+ BLI_findptr(lb_collections,
lc->collection,
offsetof(CollectionChild, collection)) :
NULL;
@@ -724,21 +723,20 @@ static void layer_collection_sync(ViewLayer *view_layer,
/* Free recursively. */
layer_collection_free(view_layer, lc);
- BLI_freelinkN(lb_layer, lc);
+ BLI_freelinkN(lb_layer_collections, lc);
}
-
- lc = lc_next;
}
/* Add layer collections for any new scene collections, and ensure order is the same. */
ListBase new_lb_layer = {NULL, NULL};
- LISTBASE_FOREACH (const CollectionChild *, child, lb_scene) {
+ LISTBASE_FOREACH (const CollectionChild *, child, lb_collections) {
Collection *collection = child->collection;
- LayerCollection *lc = BLI_findptr(lb_layer, collection, offsetof(LayerCollection, collection));
+ LayerCollection *lc = BLI_findptr(
+ lb_layer_collections, collection, offsetof(LayerCollection, collection));
if (lc) {
- BLI_remlink(lb_layer, lc);
+ BLI_remlink(lb_layer_collections, lc);
BLI_addtail(&new_lb_layer, lc);
}
else {
@@ -845,8 +843,8 @@ static void layer_collection_sync(ViewLayer *view_layer,
}
/* Replace layer collection list with new one. */
- *lb_layer = new_lb_layer;
- BLI_assert(BLI_listbase_count(lb_scene) == BLI_listbase_count(lb_layer));
+ *lb_layer_collections = new_lb_layer;
+ BLI_assert(BLI_listbase_count(lb_collections) == BLI_listbase_count(lb_layer_collections));
}
/**
@@ -876,9 +874,9 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
}
/* Generate new layer connections and object bases when collections changed. */
- CollectionChild child = {NULL, NULL, scene->master_collection};
- const ListBase collections = {&child, &child};
- ListBase new_object_bases = {NULL, NULL};
+ CollectionChild child = {.next = NULL, .prev = NULL, .collection = scene->master_collection};
+ const ListBase collections = {.first = &child, .last = &child};
+ ListBase new_object_bases = {.first = NULL, .last = NULL};
const short parent_exclude = 0, parent_restrict = 0, parent_layer_restrict = 0;
layer_collection_sync(view_layer,
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 7c09ae51344..a64e550579d 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -611,41 +611,39 @@ bool BKE_id_copy(Main *bmain, const ID *id, ID **newid)
* Invokes the appropriate copy method for the block and returns the result in
* newid, unless test. Returns true if the block can be copied.
*/
-ID *BKE_id_copy_for_duplicate(Main *bmain,
- ID *id,
- const bool is_owner_id_liboverride,
- const eDupli_ID_Flags duplicate_flags)
+ID *BKE_id_copy_for_duplicate(Main *bmain, ID *id, const eDupli_ID_Flags duplicate_flags)
{
if (id == NULL) {
- return NULL;
+ return id;
}
if (id->newid == NULL) {
- if (!is_owner_id_liboverride || !ID_IS_LINKED(id)) {
- ID *id_new;
- BKE_id_copy(bmain, id, &id_new);
- /* Copying add one user by default, need to get rid of that one. */
- id_us_min(id_new);
- ID_NEW_SET(id, id_new);
-
- /* Shape keys are always copied with their owner ID, by default. */
- ID *key_new = (ID *)BKE_key_from_id(id_new);
- ID *key = (ID *)BKE_key_from_id(id);
- if (key != NULL) {
- ID_NEW_SET(key, key_new);
- }
+ const bool do_linked_id = (duplicate_flags & USER_DUP_LINKED_ID) != 0;
+ if (!(do_linked_id || !ID_IS_LINKED(id))) {
+ return id;
+ }
- /* Note: embedded data (root nodetrees and master collections) should never be referenced by
- * anything else, so we do not need to set their newid pointer and flag. */
+ ID *id_new;
+ BKE_id_copy(bmain, id, &id_new);
+ /* Copying add one user by default, need to get rid of that one. */
+ id_us_min(id_new);
+ ID_NEW_SET(id, id_new);
- if (duplicate_flags & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, id_new, true);
- if (key_new != NULL) {
- BKE_animdata_copy_id_action(bmain, key_new, true);
- }
- /* Note that actions of embedded data (root nodetrees and master collections) are handled
- * by `BKE_animdata_copy_id_action` as well. */
- }
+ /* Shape keys are always copied with their owner ID, by default. */
+ ID *key_new = (ID *)BKE_key_from_id(id_new);
+ ID *key = (ID *)BKE_key_from_id(id);
+ if (key != NULL) {
+ ID_NEW_SET(key, key_new);
}
+
+ /* Note: embedded data (root nodetrees and master collections) should never be referenced by
+ * anything else, so we do not need to set their newid pointer and flag. */
+
+ BKE_animdata_duplicate_id_action(bmain, id_new, duplicate_flags);
+ if (key_new != NULL) {
+ BKE_animdata_duplicate_id_action(bmain, id_new, duplicate_flags);
+ }
+ /* Note that actions of embedded data (root nodetrees and master collections) are handled
+ * by `BKE_animdata_duplicate_id_action` as well. */
}
return id->newid;
}
@@ -2163,7 +2161,7 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separa
/**
* Generate full name of the data-block (without ID code, but with library if any),
- * with a 3-character prefix prepended indicating whether it comes from a library,
+ * with a 2 to 3 character prefix prepended indicating whether it comes from a library,
* is overriding, has a fake or no user, etc.
*
* \note Result is unique to a given ID type in a given Main database.
@@ -2172,11 +2170,13 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separa
* will be filled with generated string.
* \param separator_char: Character to use for separating name and library name. Can be 0 to use
* default (' ').
+ * \param r_prefix_len: The length of the prefix added.
*/
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
const ID *id,
const bool add_lib_hint,
- char separator_char)
+ char separator_char,
+ int *r_prefix_len)
{
int i = 0;
@@ -2187,6 +2187,10 @@ void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
name[i++] = ' ';
BKE_id_full_name_get(name + i, id, separator_char);
+
+ if (r_prefix_len) {
+ *r_prefix_len = i;
+ }
}
/**
diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c
index b4f2caac861..561db7d62c2 100644
--- a/source/blender/blenkernel/intern/lib_id_delete.c
+++ b/source/blender/blenkernel/intern/lib_id_delete.c
@@ -144,15 +144,14 @@ void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_i
}
#endif
+ Key *key = ((flag & LIB_ID_FREE_NO_MAIN) == 0) ? BKE_key_from_id(id) : NULL;
+
if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
BKE_libblock_relink_ex(bmain, id, NULL, NULL, 0);
}
- if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
- Key *key = BKE_key_from_id(id);
- if (key != NULL) {
- BKE_id_free_ex(bmain, &key->id, flag, use_flag_from_idtag);
- }
+ if ((flag & LIB_ID_FREE_NO_MAIN) == 0 && key != NULL) {
+ BKE_id_free_ex(bmain, &key->id, flag, use_flag_from_idtag);
}
BKE_libblock_free_datablock(id, flag);
diff --git a/source/blender/blenkernel/intern/lib_intern.h b/source/blender/blenkernel/intern/lib_intern.h
index 9cc5db64d17..7305785573b 100644
--- a/source/blender/blenkernel/intern/lib_intern.h
+++ b/source/blender/blenkernel/intern/lib_intern.h
@@ -21,11 +21,8 @@
* \ingroup bke
*/
-#ifndef __LIB_INTERN_H__
-#define __LIB_INTERN_H__
+#pragma once
extern BKE_library_free_notifier_reference_cb free_notifier_reference_cb;
extern BKE_library_remap_editor_id_reference_cb remap_editor_id_reference_cb;
-
-#endif /* __LIB_INTERN_H__ */
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 457d096f983..8b0517a77fb 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -27,19 +27,25 @@
#include "MEM_guardedalloc.h"
#include "DNA_ID.h"
+#include "DNA_collection_types.h"
#include "DNA_key_types.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "BKE_armature.h"
+#include "BKE_collection.h"
#include "BKE_idtype.h"
#include "BKE_key.h"
+#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_override.h"
+#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
+#include "BKE_scene.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
@@ -66,20 +72,6 @@ static void lib_override_library_property_clear(IDOverrideLibraryProperty *op);
static void lib_override_library_property_operation_clear(
IDOverrideLibraryPropertyOperation *opop);
-/* Temp, for until library override is ready and tested enough to go 'public',
- * we hide it by default in UI and such. */
-static bool _lib_override_library_enabled = true;
-
-void BKE_lib_override_library_enable(const bool do_enable)
-{
- _lib_override_library_enabled = do_enable;
-}
-
-bool BKE_lib_override_library_is_enabled()
-{
- return _lib_override_library_enabled;
-}
-
/** Initialize empty overriding of \a reference_id by \a local_id. */
IDOverrideLibrary *BKE_lib_override_library_init(ID *local_id, ID *reference_id)
{
@@ -163,8 +155,8 @@ void BKE_lib_override_library_clear(IDOverrideLibrary *override, const bool do_i
{
BLI_assert(override != NULL);
- if (override->runtime != NULL) {
- BLI_ghash_clear(override->runtime, NULL, NULL);
+ if (!ELEM(NULL, override->runtime, override->runtime->rna_path_to_override_properties)) {
+ BLI_ghash_clear(override->runtime->rna_path_to_override_properties, NULL, NULL);
}
LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &override->properties) {
@@ -184,8 +176,10 @@ void BKE_lib_override_library_free(struct IDOverrideLibrary **override, const bo
BLI_assert(*override != NULL);
if ((*override)->runtime != NULL) {
- BLI_ghash_free((*override)->runtime, NULL, NULL);
- (*override)->runtime = NULL;
+ if ((*override)->runtime->rna_path_to_override_properties != NULL) {
+ BLI_ghash_free((*override)->runtime->rna_path_to_override_properties, NULL, NULL);
+ }
+ MEM_SAFE_FREE((*override)->runtime);
}
BKE_lib_override_library_clear(*override, do_id_user);
@@ -368,19 +362,284 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
return success;
}
-/* We only build override GHash on request. */
-BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_mapping_ensure(
+static bool lib_override_hierarchy_recursive_tag(Main *bmain, ID *id, const uint tag)
+{
+ void **entry_vp = BLI_ghash_lookup_p(bmain->relations->id_user_to_used, id);
+ if (entry_vp == NULL) {
+ /* Already processed. */
+ return (id->tag & tag) != 0;
+ }
+
+ /* This way we won't process again that ID should we encounter it again through another
+ * relationship hierarchy.
+ * Note that this does not free any memory from relations, so we can still use the entries.
+ */
+ BKE_main_relations_ID_remove(bmain, id);
+
+ for (MainIDRelationsEntry *entry = *entry_vp; entry != NULL; entry = entry->next) {
+ if ((entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
+ /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as
+ * actual dependencies. */
+ continue;
+ }
+ /* We only consider IDs from the same library. */
+ if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) {
+ if (lib_override_hierarchy_recursive_tag(bmain, *entry->id_pointer, tag)) {
+ id->tag |= tag;
+ }
+ }
+ }
+
+ return (id->tag & tag) != 0;
+}
+
+/**
+ * Tag all IDs in given \a bmain that are being used by given \a id_root ID or its dependencies,
+ * recursively.
+ *
+ * This will include all local IDs, and all IDs from the same library as the \a id_root.
+ *
+ * \param id_root The root of the hierarchy of dependencies to be tagged.
+ * \param do_create_main_relashionships Whether main relations needs to be created or already exist
+ * (in any case, they will be freed by this function).
+ */
+void BKE_lib_override_library_dependencies_tag(struct Main *bmain,
+ struct ID *id_root,
+ const uint tag,
+ const bool do_create_main_relashionships)
+{
+ if (do_create_main_relashionships) {
+ BKE_main_relations_create(bmain, 0);
+ }
+
+ /* Then we tag all intermediary data-blocks in-between two overridden ones (e.g. if a shapekey
+ * has a driver using an armature object's bone, we need to override the shapekey/obdata, the
+ * objects using them, etc.) */
+ lib_override_hierarchy_recursive_tag(bmain, id_root, tag);
+
+ BKE_main_relations_free(bmain);
+}
+
+static int lib_override_library_make_tag_ids_cb(LibraryIDLinkCallbackData *cb_data)
+{
+ if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK)) {
+ return IDWALK_RET_STOP_RECURSION;
+ }
+
+ ID *id_root = cb_data->user_data;
+ Library *library_root = id_root->lib;
+ ID *id = *cb_data->id_pointer;
+ ID *id_owner = cb_data->id_owner;
+
+ BLI_assert(id_owner == cb_data->id_self);
+
+ if (ELEM(id, NULL, id_owner)) {
+ return IDWALK_RET_NOP;
+ }
+
+ BLI_assert(id->lib != NULL);
+ BLI_assert(id_owner->lib == library_root);
+
+ if (id->tag & LIB_TAG_DOIT) {
+ /* Already processed, but maybe not with the same chain of dependency, so we need to check that
+ * one nonetheless. */
+ return IDWALK_RET_STOP_RECURSION;
+ }
+
+ if (id->lib != library_root) {
+ /* We do not override data-blocks from other libraries, nor do we process them. */
+ return IDWALK_RET_STOP_RECURSION;
+ }
+
+ /* We tag all collections and objects for override. And we also tag all other data-blocks which
+ * would user one of those. */
+ if (ELEM(GS(id->name), ID_OB, ID_GR)) {
+ id->tag |= LIB_TAG_DOIT;
+ }
+
+ return IDWALK_RET_NOP;
+}
+
+/**
+ * Advanced 'smart' function to create fully functional overrides.
+ *
+ * \note Currently it only does special things if given \a id_root is an object of collection, more
+ * specific behaviors may be added in the future for other ID types.
+ *
+ * \note It will overrides all IDs tagged with \a LIB_TAG_DOIT, and it does not clear that tag at
+ * its beginning, so caller code can add extra data-blocks to be overridden as well.
+ *
+ * \note In the future that same function may be extended to support 'refresh' of overrides
+ * (rebuilding overrides from linked data, trying to preserve local overrides already defined).
+ *
+ * \param id_root The root ID to create an override from.
+ * \param id_reference some reference ID used to do some post-processing after overrides have been
+ * created, may be NULL. Typically, the Empty object instantiating the linked
+ * collection we override, currently.
+ * \return true if override was successfully created.
+ */
+bool BKE_lib_override_library_create(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, ID *id_root, ID *id_reference)
+{
+ /* Tag all collections and objects, as well as other IDs using them. */
+ id_root->tag |= LIB_TAG_DOIT;
+
+ BKE_main_relations_create(bmain, 0);
+
+ if (ELEM(GS(id_root->name), ID_OB, ID_GR)) {
+ BKE_library_foreach_ID_link(bmain,
+ id_root,
+ lib_override_library_make_tag_ids_cb,
+ id_root,
+ IDWALK_READONLY | IDWALK_RECURSE);
+
+ /* Then, we remove (untag) bone shape objects, you shall never want to override those
+ * (hopefully)... */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ if (ob->type == OB_ARMATURE && ob->pose != NULL && (ob->id.tag & LIB_TAG_DOIT)) {
+ for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
+ if (pchan->custom != NULL) {
+ pchan->custom->id.tag &= ~LIB_TAG_DOIT;
+ }
+ }
+ }
+ }
+ }
+
+ /* Note that this call will also free the main relations data we created above. */
+ BKE_lib_override_library_dependencies_tag(bmain, id_root, LIB_TAG_DOIT, false);
+
+ const bool success = BKE_lib_override_library_create_from_tag(bmain);
+
+ if (success) {
+ BKE_main_collection_sync(bmain);
+
+ switch (GS(id_root->name)) {
+ case ID_GR: {
+ Object *ob_reference = id_reference != NULL && GS(id_reference->name) == ID_OB ?
+ (Object *)id_reference :
+ NULL;
+ Collection *collection_new = ((Collection *)id_root->newid);
+ if (ob_reference != NULL) {
+ BKE_collection_add_from_object(bmain, scene, ob_reference, collection_new);
+ }
+ else {
+ BKE_collection_add_from_collection(
+ bmain, scene, ((Collection *)id_root), collection_new);
+ }
+
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection_new, ob_new) {
+ if (ob_new != NULL && ob_new->id.override_library != NULL) {
+ if (ob_reference != NULL) {
+ Base *base;
+ if ((base = BKE_view_layer_base_find(view_layer, ob_new)) == NULL) {
+ BKE_collection_object_add_from(bmain, scene, ob_reference, ob_new);
+ base = BKE_view_layer_base_find(view_layer, ob_new);
+ DEG_id_tag_update_ex(
+ bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
+ }
+
+ if (ob_new == (Object *)ob_reference->id.newid) {
+ /* TODO: is setting active needed? */
+ BKE_view_layer_base_select_and_set_active(view_layer, base);
+ }
+ }
+ else if (BKE_view_layer_base_find(view_layer, ob_new) == NULL) {
+ BKE_collection_object_add(bmain, collection_new, ob_new);
+ DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
+ }
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ break;
+ }
+ case ID_OB: {
+ BKE_collection_object_add_from(
+ bmain, scene, (Object *)id_root, ((Object *)id_root->newid));
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* We need to ensure all new overrides of objects are properly instantiated. */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ Object *ob_new = (Object *)ob->id.newid;
+ if (ob_new != NULL) {
+ BLI_assert(ob_new->id.override_library != NULL &&
+ ob_new->id.override_library->reference == &ob->id);
+
+ Collection *default_instantiating_collection = NULL;
+ if (BKE_view_layer_base_find(view_layer, ob_new) == NULL) {
+ if (default_instantiating_collection == NULL) {
+ switch (GS(id_root->name)) {
+ case ID_GR: {
+ default_instantiating_collection = BKE_collection_add(
+ bmain, (Collection *)id_root, "OVERRIDE_HIDDEN");
+ break;
+ }
+ case ID_OB: {
+ /* Add the new container collection to one of the collections instantiating the
+ * root object, or scene's master collection if none found. */
+ Object *ob_root = (Object *)id_root;
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
+ if (BKE_collection_has_object(collection, ob_root) &&
+ BKE_view_layer_has_collection(view_layer, collection) &&
+ !ID_IS_LINKED(collection) && !ID_IS_OVERRIDE_LIBRARY(collection)) {
+ default_instantiating_collection = BKE_collection_add(
+ bmain, collection, "OVERRIDE_HIDDEN");
+ }
+ }
+ if (default_instantiating_collection == NULL) {
+ default_instantiating_collection = BKE_collection_add(
+ bmain, scene->master_collection, "OVERRIDE_HIDDEN");
+ }
+ break;
+ }
+ default:
+ BLI_assert(0);
+ }
+ /* Hide the collection from viewport and render. */
+ default_instantiating_collection->flag |= COLLECTION_RESTRICT_VIEWPORT |
+ COLLECTION_RESTRICT_RENDER;
+ }
+
+ BKE_collection_object_add(bmain, default_instantiating_collection, ob_new);
+ DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
+ }
+ }
+ }
+ }
+
+ /* Cleanup. */
+ BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+
+ return success;
+}
+
+BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_runtime_ensure(
IDOverrideLibrary *override)
{
if (override->runtime == NULL) {
- override->runtime = BLI_ghash_new(
+ override->runtime = MEM_callocN(sizeof(*override->runtime), __func__);
+ }
+ return override->runtime;
+}
+
+/* We only build override GHash on request. */
+BLI_INLINE GHash *override_library_rna_path_mapping_ensure(IDOverrideLibrary *override)
+{
+ IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_runtime_ensure(override);
+ if (override_runtime->rna_path_to_override_properties == NULL) {
+ override_runtime->rna_path_to_override_properties = BLI_ghash_new(
BLI_ghashutil_strhash_p_murmur, BLI_ghashutil_strcmp, __func__);
for (IDOverrideLibraryProperty *op = override->properties.first; op != NULL; op = op->next) {
- BLI_ghash_insert(override->runtime, op->rna_path, op);
+ BLI_ghash_insert(override_runtime->rna_path_to_override_properties, op->rna_path, op);
}
}
- return override->runtime;
+ return override_runtime->rna_path_to_override_properties;
}
/**
@@ -389,7 +648,7 @@ BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_mapping_ensure(
IDOverrideLibraryProperty *BKE_lib_override_library_property_find(IDOverrideLibrary *override,
const char *rna_path)
{
- IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure(override);
+ GHash *override_runtime = override_library_rna_path_mapping_ensure(override);
return BLI_ghash_lookup(override_runtime, rna_path);
}
@@ -407,8 +666,7 @@ IDOverrideLibraryProperty *BKE_lib_override_library_property_get(IDOverrideLibra
op->rna_path = BLI_strdup(rna_path);
BLI_addtail(&override->properties, op);
- IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure(
- override);
+ GHash *override_runtime = override_library_rna_path_mapping_ensure(override);
BLI_ghash_insert(override_runtime, op->rna_path, op);
if (r_created) {
@@ -454,8 +712,11 @@ void lib_override_library_property_clear(IDOverrideLibraryProperty *op)
void BKE_lib_override_library_property_delete(IDOverrideLibrary *override,
IDOverrideLibraryProperty *override_property)
{
- if (override->runtime != NULL) {
- BLI_ghash_remove(override->runtime, override_property->rna_path, NULL, NULL);
+ if (!ELEM(NULL, override->runtime, override->runtime->rna_path_to_override_properties)) {
+ BLI_ghash_remove(override->runtime->rna_path_to_override_properties,
+ override_property->rna_path,
+ NULL,
+ NULL);
}
lib_override_library_property_clear(override_property);
BLI_freelinkN(&override->properties, override_property);
@@ -884,11 +1145,11 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
TaskPool *task_pool = BLI_task_pool_create(bmain, TASK_PRIORITY_HIGH);
FOREACH_MAIN_ID_BEGIN (bmain, id) {
- if ((ID_IS_OVERRIDE_LIBRARY_REAL(id) && force_auto) ||
- (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH)) {
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
+ (force_auto || (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH))) {
BLI_task_pool_push(task_pool, lib_override_library_operations_create_cb, id, false, NULL);
- id->tag &= ~LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH;
}
+ id->tag &= ~LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH;
}
FOREACH_MAIN_ID_END;
@@ -905,6 +1166,137 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
#endif
}
+static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root)
+{
+ bool was_op_deleted = false;
+
+ LISTBASE_FOREACH_MUTABLE (
+ IDOverrideLibraryProperty *, op, &id_root->override_library->properties) {
+ bool do_op_delete = true;
+ const bool is_collection = op->rna_prop_type == PROP_COLLECTION;
+ if (is_collection || op->rna_prop_type == PROP_POINTER) {
+ PointerRNA ptr_root, ptr_root_lib, ptr, ptr_lib;
+ PropertyRNA *prop, *prop_lib;
+
+ RNA_pointer_create(id_root, &RNA_ID, id_root, &ptr_root);
+ RNA_pointer_create(id_root->override_library->reference,
+ &RNA_ID,
+ id_root->override_library->reference,
+ &ptr_root_lib);
+
+ bool prop_exists = RNA_path_resolve_property(&ptr_root, op->rna_path, &ptr, &prop);
+ BLI_assert(prop_exists);
+ prop_exists = RNA_path_resolve_property(&ptr_root_lib, op->rna_path, &ptr_lib, &prop_lib);
+
+ if (prop_exists) {
+ BLI_assert(ELEM(RNA_property_type(prop), PROP_POINTER, PROP_COLLECTION));
+ BLI_assert(RNA_property_type(prop) == RNA_property_type(prop_lib));
+ if (is_collection) {
+ ptr.type = RNA_property_pointer_type(&ptr, prop);
+ ptr_lib.type = RNA_property_pointer_type(&ptr_lib, prop_lib);
+ }
+ else {
+ ptr = RNA_property_pointer_get(&ptr, prop);
+ ptr_lib = RNA_property_pointer_get(&ptr_lib, prop_lib);
+ }
+ if (ptr.owner_id != NULL && ptr_lib.owner_id != NULL) {
+ BLI_assert(ptr.type == ptr_lib.type);
+ do_op_delete = !(RNA_struct_is_ID(ptr.type) && ptr.owner_id->override_library != NULL &&
+ ptr.owner_id->override_library->reference == ptr_lib.owner_id);
+ }
+ }
+ }
+
+ if (do_op_delete) {
+ BKE_lib_override_library_property_delete(id_root->override_library, op);
+ was_op_deleted = true;
+ }
+ }
+
+ if (was_op_deleted) {
+ DEG_id_tag_update_ex(bmain, id_root, ID_RECALC_COPY_ON_WRITE);
+ IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_runtime_ensure(
+ id_root->override_library);
+ override_runtime->tag |= IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
+ }
+
+ return was_op_deleted;
+}
+
+/** Reset all overrides in given \a id_root, while preserving ID relations. */
+void BKE_lib_override_library_id_reset(Main *bmain, ID *id_root)
+{
+ if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
+ return;
+ }
+
+ if (lib_override_library_id_reset_do(bmain, id_root)) {
+ if (id_root->override_library->runtime != NULL &&
+ (id_root->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD) !=
+ 0) {
+ BKE_lib_override_library_update(bmain, id_root);
+ id_root->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
+ }
+ }
+}
+
+static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *id_root)
+{
+ if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
+ return;
+ }
+
+ void **entry_pp = BLI_ghash_lookup(bmain->relations->id_user_to_used, id_root);
+ if (entry_pp == NULL) {
+ /* Already processed. */
+ return;
+ }
+
+ lib_override_library_id_reset_do(bmain, id_root);
+
+ /* This way we won't process again that ID should we encounter it again through another
+ * relationship hierarchy.
+ * Note that this does not free any memory from relations, so we can still use the entries.
+ */
+ BKE_main_relations_ID_remove(bmain, id_root);
+
+ for (MainIDRelationsEntry *entry = *entry_pp; entry != NULL; entry = entry->next) {
+ if ((entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
+ /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as
+ * actual dependencies. */
+ continue;
+ }
+ /* We only consider IDs from the same library. */
+ if (entry->id_pointer != NULL) {
+ ID *id_entry = *entry->id_pointer;
+ if (id_entry->override_library != NULL) {
+ lib_override_library_id_hierarchy_recursive_reset(bmain, id_entry);
+ }
+ }
+ }
+}
+
+/** Reset all overrides in given \a id_root and its dependencies, while preserving ID relations. */
+void BKE_lib_override_library_id_hierarchy_reset(Main *bmain, ID *id_root)
+{
+ BKE_main_relations_create(bmain, 0);
+
+ lib_override_library_id_hierarchy_recursive_reset(bmain, id_root);
+
+ BKE_main_relations_free(bmain);
+
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || id->override_library->runtime == NULL ||
+ (id->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD) == 0) {
+ continue;
+ }
+ BKE_lib_override_library_update(bmain, id);
+ id->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
+ }
+ FOREACH_MAIN_ID_END;
+}
+
/** Set or clear given tag in all operations as unused in that override property data. */
void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property,
const short tag,
@@ -1040,8 +1432,6 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
Key *local_key = BKE_key_from_id(local);
Key *tmp_key = BKE_key_from_id(tmp_id);
if (local_key != NULL && tmp_key != NULL) {
- /* This is some kind of hard-coded 'always enforced override'... */
- tmp_key->from = local_key->from;
tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
}
@@ -1060,6 +1450,18 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
* So when we'll free tmp_id, we'll actually free old, outdated data from local. */
BKE_lib_id_swap(bmain, local, tmp_id);
+ if (local_key != NULL && tmp_key != NULL) {
+ /* This is some kind of hard-coded 'always enforced override'... */
+ BKE_lib_id_swap(bmain, &local_key->id, &tmp_key->id);
+ tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
+ /* The swap of local and tmp_id inverted those pointers, we need to redefine proper
+ * relationships. */
+ *BKE_key_from_id_p(local) = local_key;
+ *BKE_key_from_id_p(tmp_id) = tmp_key;
+ local_key->from = local;
+ tmp_key->from = tmp_id;
+ }
+
/* Again, horribly inn-efficient in our case, we need something off-Main
* (aka more generic nolib copy/free stuff)! */
/* XXX And crashing in complex cases (e.g. because depsgraph uses same data...). */
@@ -1078,6 +1480,7 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
/* Full rebuild of Depsgraph! */
/* Note: this is really brute force, in theory updates from RNA should have handle this already,
* but for now let's play it safe. */
+ DEG_id_tag_update_ex(bmain, local, ID_RECALC_ALL);
DEG_relations_tag_update(bmain);
}
@@ -1112,7 +1515,7 @@ void BKE_lib_override_library_main_update(Main *bmain)
*/
/** Initialize an override storage. */
-OverrideLibraryStorage *BKE_lib_override_library_operations_store_initialize(void)
+OverrideLibraryStorage *BKE_lib_override_library_operations_store_init(void)
{
return BKE_main_new();
}
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index 00a42b12e07..0f81d45c10f 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -412,6 +412,8 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
return ELEM(id_type_used, ID_MA);
case ID_VO:
return ELEM(id_type_used, ID_MA);
+ case ID_SIM:
+ return ELEM(id_type_used, ID_OB, ID_IM);
case ID_IM:
case ID_VF:
case ID_TXT:
@@ -422,7 +424,6 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
case ID_PAL:
case ID_PC:
case ID_CF:
- case ID_SIM:
/* Those types never use/reference other IDs... */
return false;
case ID_IP:
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index aa1005c663f..f42df6765c4 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -58,7 +58,7 @@ static void light_init_data(ID *id)
MEMCPY_STRUCT_AFTER(la, DNA_struct_default_get(Light), id);
la->curfalloff = BKE_curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
- BKE_curvemapping_initialize(la->curfalloff);
+ BKE_curvemapping_init(la->curfalloff);
}
/**
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 49c909850de..7e859799a4e 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -624,7 +624,7 @@ void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float
co, bezt->vec[1], bezt->vec[2], bezt_next->vec[0], bezt_next->vec[1], u);
}
-BLI_INLINE void orthogonal_direction_get(float vec[2], float result[2])
+BLI_INLINE void orthogonal_direction_get(const float vec[2], float result[2])
{
result[0] = -vec[1];
result[1] = vec[0];
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 412ccd3ab39..01d44d070b3 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -769,8 +769,8 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
BLI_assert(tot_diff_feather_points == tot_diff_point);
- /* note: only added for convenience, we don't infact use these to scanfill,
- * only to create feather faces after scanfill */
+ /* Note: only added for convenience, we don't in fact use these to scan-fill,
+ * only to create feather faces after scan-fill. */
for (j = 0; j < tot_diff_feather_points; j++) {
copy_v2_v2(co_feather, diff_feather_points[j]);
sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
@@ -1256,7 +1256,7 @@ static float maskrasterize_layer_z_depth_quad(
return w[2] + w[3]; /* we can make this assumption for small speedup */
}
-static float maskrasterize_layer_isect(unsigned int *face,
+static float maskrasterize_layer_isect(const unsigned int *face,
float (*cos)[3],
const float dist_orig,
const float xy[2])
@@ -1489,6 +1489,8 @@ static void maskrasterize_buffer_cb(void *__restrict userdata,
void BKE_maskrasterize_buffer(MaskRasterHandle *mr_handle,
const unsigned int width,
const unsigned int height,
+ /* Cannot be const, because it is assigned to non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
float *buffer)
{
const float x_inv = 1.0f / (float)width;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index d4de04a9e98..e878a894b27 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -955,18 +955,26 @@ void BKE_object_material_remap_calc(Object *ob_dst, Object *ob_src, short *remap
void BKE_object_material_array_assign(Main *bmain,
struct Object *ob,
struct Material ***matar,
- short totcol)
+ int totcol,
+ const bool to_object_only)
{
int actcol_orig = ob->actcol;
- short i;
while ((ob->totcol > totcol) && BKE_object_material_slot_remove(bmain, ob)) {
/* pass */
}
/* now we have the right number of slots */
- for (i = 0; i < totcol; i++) {
- BKE_object_material_assign(bmain, ob, (*matar)[i], i + 1, BKE_MAT_ASSIGN_USERPREF);
+ for (int i = 0; i < totcol; i++) {
+ if (to_object_only && ob->matbits[i] == 0) {
+ /* If we only assign to object, and that slot uses obdata material, do nothing. */
+ continue;
+ }
+ BKE_object_material_assign(bmain,
+ ob,
+ (*matar)[i],
+ i + 1,
+ to_object_only ? BKE_MAT_ASSIGN_OBJECT : BKE_MAT_ASSIGN_USERPREF);
}
if (actcol_orig > ob->totcol) {
@@ -1272,8 +1280,6 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
if (ma->paint_clone_slot >= count) {
ma->paint_clone_slot = count - 1;
}
-
- return;
}
void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
@@ -1712,6 +1718,29 @@ static void material_default_volume_init(Material *ma)
nodeSetActive(ntree, output);
}
+static void material_default_holdout_init(Material *ma)
+{
+ bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname);
+ ma->nodetree = ntree;
+ ma->use_nodes = true;
+
+ bNode *holdout = nodeAddStaticNode(NULL, ntree, SH_NODE_HOLDOUT);
+ bNode *output = nodeAddStaticNode(NULL, ntree, SH_NODE_OUTPUT_MATERIAL);
+
+ nodeAddLink(ntree,
+ holdout,
+ nodeFindSocket(holdout, SOCK_OUT, "Holdout"),
+ output,
+ nodeFindSocket(output, SOCK_IN, "Surface"));
+
+ holdout->locx = 10.0f;
+ holdout->locy = 300.0f;
+ output->locx = 300.0f;
+ output->locy = 300.0f;
+
+ nodeSetActive(ntree, output);
+}
+
Material *BKE_material_default_empty(void)
{
return &default_material_empty;
@@ -1757,6 +1786,7 @@ void BKE_materials_init(void)
material_default_surface_init(&default_material_surface);
material_default_volume_init(&default_material_volume);
+ material_default_holdout_init(&default_material_holdout);
material_default_gpencil_init(&default_material_gpencil);
}
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index ad178e76ef6..72b99bea0f4 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -315,7 +315,7 @@ static float densfunc(const MetaElem *ball, float x, float y, float z)
float dist2;
float dvec[3] = {x, y, z};
- mul_m4_v3((float(*)[4])ball->imat, dvec);
+ mul_m4_v3((const float(*)[4])ball->imat, dvec);
switch (ball->type) {
case MB_BALL:
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 48baedadd73..048af022adb 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1305,7 +1305,7 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
return (me->totvert != 0);
}
-void BKE_mesh_transform(Mesh *me, float mat[4][4], bool do_keys)
+void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
{
int i;
MVert *mvert = me->mvert;
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 9e5565d744a..a0f3bc9e74d 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -286,12 +286,14 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob,
}
}
else if (dl->type == DL_SURF) {
- int tot;
- totvert += dl->parts * dl->nr;
- tot = (dl->parts - 1 + ((dl->flag & DL_CYCL_V) == 2)) *
- (dl->nr - 1 + (dl->flag & DL_CYCL_U));
- totpoly += tot;
- totloop += tot * 4;
+ if (dl->parts != 0) {
+ int tot;
+ totvert += dl->parts * dl->nr;
+ tot = (((dl->flag & DL_CYCL_U) ? 1 : 0) + (dl->nr - 1)) *
+ (((dl->flag & DL_CYCL_V) ? 1 : 0) + (dl->parts - 1));
+ totpoly += tot;
+ totloop += tot * 4;
+ }
}
else if (dl->type == DL_INDEX3) {
int tot;
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index b298a6a2787..49957b584ad 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -2888,7 +2888,7 @@ void BKE_mesh_loops_to_mface_corners(
void BKE_mesh_loops_to_tessdata(CustomData *fdata,
CustomData *ldata,
MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces)
{
@@ -2981,7 +2981,7 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata,
void BKE_mesh_tangent_loops_to_tessdata(CustomData *fdata,
CustomData *ldata,
MFace *mface,
- int *polyindices,
+ const int *polyindices,
unsigned int (*loopindices)[4],
const int num_faces,
const char *layer_name)
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 4ed9b31dbb5..686f58a0ceb 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -953,7 +953,7 @@ void BKE_mesh_loop_islands_free(MeshIslandStore *island_store)
void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
const int item_num,
- int *items_indices,
+ const int *items_indices,
const int num_island_items,
int *island_item_indices,
const int num_innercut_items,
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index 404d6a581ae..a4991675d2d 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -1071,7 +1071,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
BLI_bitmap *done_edges,
MeshElemMap *edge_to_poly_map,
const bool is_edge_innercut,
- int *poly_island_index_map,
+ const int *poly_island_index_map,
float (*poly_centers)[3],
unsigned char *poly_status)
{
diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c
index 932423bc445..b9eb3876dde 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.c
+++ b/source/blender/blenkernel/intern/mesh_runtime.c
@@ -43,8 +43,6 @@
/** \name Mesh Runtime Struct Utils
* \{ */
-static ThreadRWMutex loops_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
-
/**
* Default values defined at read time.
*/
@@ -159,23 +157,21 @@ const MLoopTri *BKE_mesh_runtime_looptri_ensure(Mesh *mesh)
{
MLoopTri *looptri;
- BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_READ);
+ ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex;
+ BLI_mutex_lock(mesh_eval_mutex);
+
looptri = mesh->runtime.looptris.array;
- BLI_rw_mutex_unlock(&loops_cache_lock);
if (looptri != NULL) {
BLI_assert(BKE_mesh_runtime_looptri_len(mesh) == mesh->runtime.looptris.len);
}
else {
- BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_WRITE);
- /* We need to ensure array is still NULL inside mutex-protected code,
- * some other thread might have already recomputed those looptris. */
- if (mesh->runtime.looptris.array == NULL) {
- BKE_mesh_runtime_looptri_recalc(mesh);
- }
+ BKE_mesh_runtime_looptri_recalc(mesh);
looptri = mesh->runtime.looptris.array;
- BLI_rw_mutex_unlock(&loops_cache_lock);
}
+
+ BLI_mutex_unlock(mesh_eval_mutex);
+
return looptri;
}
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index f64ed609d18..4d8c0568eb6 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -547,6 +547,16 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
for (i = 0, mp = mpolys; i < totpoly; i++, mp++, sp++) {
sp->index = i;
+ /* Material index, isolated from other tests here. While large indices are clamped,
+ * negative indices aren't supported by drawing, exporters etc.
+ * To check the indices are in range, use #BKE_mesh_validate_material_indices */
+ if (mp->mat_nr < 0) {
+ PRINT_ERR("\tPoly %u has invalid material (%d)", sp->index, mp->mat_nr);
+ if (do_fixes) {
+ mp->mat_nr = 0;
+ }
+ }
+
if (mp->loopstart < 0 || mp->totloop < 3) {
/* Invalid loop data. */
PRINT_ERR("\tPoly %u is invalid (loopstart: %d, totloop: %d)",
@@ -1133,14 +1143,15 @@ bool BKE_mesh_is_valid(Mesh *me)
*/
bool BKE_mesh_validate_material_indices(Mesh *me)
{
+ /* Cast to unsigned to catch negative indices too. */
+ const uint16_t mat_nr_max = max_ii(0, me->totcol - 1);
MPoly *mp;
- const int max_idx = max_ii(0, me->totcol - 1);
const int totpoly = me->totpoly;
int i;
bool is_valid = true;
for (mp = me->mpoly, i = 0; i < totpoly; i++, mp++) {
- if (mp->mat_nr > max_idx) {
+ if ((uint16_t)mp->mat_nr > mat_nr_max) {
mp->mat_nr = 0;
is_valid = false;
}
diff --git a/source/blender/blenkernel/intern/mesh_wrapper.c b/source/blender/blenkernel/intern/mesh_wrapper.c
index 6a8bc698b11..acd272ac305 100644
--- a/source/blender/blenkernel/intern/mesh_wrapper.c
+++ b/source/blender/blenkernel/intern/mesh_wrapper.c
@@ -40,6 +40,7 @@
#include "BLI_ghash.h"
#include "BLI_math.h"
+#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BKE_editmesh.h"
@@ -96,9 +97,14 @@ Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em,
void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
{
+ ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime.eval_mutex;
+ BLI_mutex_lock(mesh_eval_mutex);
+
if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
+ BLI_mutex_unlock(mesh_eval_mutex);
return;
}
+
const eMeshWrapperType geom_type_orig = me->runtime.wrapper_type;
me->runtime.wrapper_type = ME_WRAPPER_TYPE_MDATA;
@@ -130,6 +136,8 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
if (me->runtime.wrapper_type_finalize) {
BKE_mesh_wrapper_deferred_finalize(me, &me->runtime.cd_mask_extra);
}
+
+ BLI_mutex_unlock(mesh_eval_mutex);
}
bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3])
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index f0efc9b8c50..a5bd2ecf68a 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -129,6 +129,23 @@ static void movie_clip_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void movie_clip_foreach_cache(ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data)
+{
+ MovieClip *movie_clip = (MovieClip *)id;
+ IDCacheKey key = {
+ .id_session_uuid = id->session_uuid,
+ .offset_in_ID = offsetof(MovieClip, cache),
+ .cache_v = movie_clip->cache,
+ };
+ function_callback(id, &key, (void **)&movie_clip->cache, 0, user_data);
+
+ key.offset_in_ID = offsetof(MovieClip, tracking.camera.intrinsics);
+ key.cache_v = movie_clip->tracking.camera.intrinsics;
+ function_callback(id, &key, (void **)&movie_clip->tracking.camera.intrinsics, 0, user_data);
+}
+
IDTypeInfo IDType_ID_MC = {
.id_code = ID_MC,
.id_filter = FILTER_ID_MC,
@@ -144,6 +161,7 @@ IDTypeInfo IDType_ID_MC = {
.free_data = movie_clip_free_data,
.make_local = NULL,
.foreach_id = movie_clip_foreach_id,
+ .foreach_cache = movie_clip_foreach_cache,
};
/*********************** movieclip buffer loaders *************************/
@@ -1848,3 +1866,88 @@ void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, MovieClip
DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip);
movieclip_selection_sync(clip, (MovieClip *)clip->id.orig_id);
}
+
+/* -------------------------------------------------------------------- */
+/** \name GPU textures
+ * \{ */
+
+static GPUTexture **movieclip_get_gputexture_ptr(MovieClip *clip,
+ MovieClipUser *cuser,
+ eGPUTextureTarget textarget)
+{
+ /* Check if we have an existing entry for that clip user. */
+ MovieClip_RuntimeGPUTexture *tex;
+ for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) {
+ if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) {
+ break;
+ }
+ }
+
+ /* If not, allocate a new one. */
+ if (tex == NULL) {
+ tex = (MovieClip_RuntimeGPUTexture *)MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture),
+ __func__);
+
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ tex->gputexture[i] = NULL;
+ }
+
+ memcpy(&tex->user, cuser, sizeof(MovieClipUser));
+ BLI_addtail(&clip->runtime.gputextures, tex);
+ }
+
+ return &tex->gputexture[textarget];
+}
+
+GPUTexture *BKE_movieclip_get_gpu_texture(MovieClip *clip, MovieClipUser *cuser)
+{
+ if (clip == NULL) {
+ return NULL;
+ }
+
+ GPUTexture **tex = movieclip_get_gputexture_ptr(clip, cuser, TEXTARGET_2D);
+ if (*tex) {
+ return *tex;
+ }
+
+ /* check if we have a valid image buffer */
+ ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser);
+ if (ibuf == NULL) {
+ *tex = GPU_texture_create_error(2, false);
+ return *tex;
+ }
+
+ /* This only means RGBA16F instead of RGBA32F. */
+ const bool high_bitdepth = false;
+ const bool store_premultiplied = ibuf->rect_float ? false : true;
+ *tex = IMB_create_gpu_texture(ibuf, high_bitdepth, store_premultiplied);
+
+ /* Do not generate mips for movieclips... too slow. */
+ GPU_texture_mipmap_mode(*tex, false, true);
+
+ IMB_freeImBuf(ibuf);
+
+ return *tex;
+}
+
+void BKE_movieclip_free_gputexture(struct MovieClip *clip)
+{
+ /* number of gpu textures to keep around as cache
+ * We don't want to keep too many GPU textures for
+ * movie clips around, as they can be large.*/
+ const int MOVIECLIP_NUM_GPUTEXTURES = 1;
+
+ while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) {
+ MovieClip_RuntimeGPUTexture *tex = (MovieClip_RuntimeGPUTexture *)BLI_pophead(
+ &clip->runtime.gputextures);
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ /* free glsl image binding */
+ if (tex->gputexture[i]) {
+ GPU_texture_free(tex->gputexture[i]);
+ tex->gputexture[i] = NULL;
+ }
+ }
+ MEM_freeN(tex);
+ }
+}
+/** \} */
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 7e78be6d66e..6c10f6de855 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -175,7 +175,7 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden,
return subd;
}
-static BLI_bitmap *multires_mdisps_downsample_hidden(BLI_bitmap *old_hidden,
+static BLI_bitmap *multires_mdisps_downsample_hidden(const BLI_bitmap *old_hidden,
int old_level,
int new_level)
{
@@ -241,7 +241,7 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level)
md->hidden = subd;
}
-static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
+static MDisps *multires_mdisps_init_hidden(Mesh *me, int level)
{
MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
int gridsize = BKE_ccg_gridsize(level);
@@ -868,7 +868,7 @@ static void multires_subdivide_legacy(
mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
if (!mdisps) {
- mdisps = multires_mdisps_initialize_hidden(me, totlvl);
+ mdisps = multires_mdisps_init_hidden(me, totlvl);
}
if (mdisps->disps && !updateblock && lvl != 0) {
diff --git a/source/blender/blenkernel/intern/multires_inline.h b/source/blender/blenkernel/intern/multires_inline.h
index 3d00101ec29..49329698b3a 100644
--- a/source/blender/blenkernel/intern/multires_inline.h
+++ b/source/blender/blenkernel/intern/multires_inline.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __MULTIRES_INLINE_H__
-#define __MULTIRES_INLINE_H__
+#pragma once
#include "BKE_multires.h"
#include "BLI_math_vector.h"
@@ -57,5 +56,3 @@ BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3]
normalize_v3(tangent_matrix[1]);
normalize_v3(tangent_matrix[2]);
}
-
-#endif /* __MULTIRES_INLINE_H__ */
diff --git a/source/blender/blenkernel/intern/multires_reshape.h b/source/blender/blenkernel/intern/multires_reshape.h
index 12816a455ee..d6c1d79dfd7 100644
--- a/source/blender/blenkernel/intern/multires_reshape.h
+++ b/source/blender/blenkernel/intern/multires_reshape.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_INTERN_MULTIRES_RESHAPE_H__
-#define __BKE_INTERN_MULTIRES_RESHAPE_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -331,4 +330,3 @@ void multires_reshape_apply_base_refine_from_base(MultiresReshapeContext *reshap
*
* NOTE: Will re-evaluate all leading modifiers, so it's not cheap. */
void multires_reshape_apply_base_refine_from_deform(MultiresReshapeContext *reshape_context);
-#endif /* __BKE_INTERN_MULTIRES_RESHAPE_H__ */
diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.c
index 3564ae80d24..e12e692ea23 100644
--- a/source/blender/blenkernel/intern/multires_reshape_smooth.c
+++ b/source/blender/blenkernel/intern/multires_reshape_smooth.c
@@ -271,7 +271,7 @@ static void base_surface_grids_allocate(MultiresReshapeSmoothContext *reshape_sm
for (int grid_index = 0; grid_index < num_grids; ++grid_index) {
surface_grid[grid_index].points = MEM_calloc_arrayN(
- sizeof(SurfacePoint), grid_area, "delta grid dispalcement");
+ sizeof(SurfacePoint), grid_area, "delta grid displacement");
}
reshape_smooth_context->base_surface_grids = surface_grid;
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c
index 6bd7b6b6a98..fa1a53f946e 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.c
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.c
@@ -80,7 +80,7 @@
/**
* Used to check if a vertex is in a disconnected element ID.
*/
-static bool is_vertex_in_id(BMVert *v, int *elem_id, int elem)
+static bool is_vertex_in_id(BMVert *v, const int *elem_id, int elem)
{
const int v_index = BM_elem_index_get(v);
return elem_id[v_index] == elem;
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.h b/source/blender/blenkernel/intern/multires_unsubdivide.h
index e00a1ae6d8b..39c6da0b6c8 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.h
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __BKE_INTERN_MULTIRES_UNSUBDIVIDE_H__
-#define __BKE_INTERN_MULTIRES_UNSUBDIVIDE_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -90,5 +89,3 @@ void multires_unsubdivide_context_free(MultiresUnsubdivideContext *context);
/* Rebuilds all subdivision to the level 0 base mesh. */
bool multires_unsubdivide_to_basemesh(MultiresUnsubdivideContext *context);
-
-#endif /* __BKE_INTERN_MULTIRES_UNSUBDIVIDE_H__ */
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index b73f957535c..91693abd1cf 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -61,6 +61,7 @@
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_simulation.h"
#include "BLI_ghash.h"
#include "BLI_threads.h"
@@ -315,6 +316,33 @@ static void node_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void node_foreach_cache(ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data)
+{
+ bNodeTree *nodetree = (bNodeTree *)id;
+ IDCacheKey key = {
+ .id_session_uuid = id->session_uuid,
+ .offset_in_ID = offsetof(bNodeTree, previews),
+ .cache_v = nodetree->previews,
+ };
+
+ /* TODO, see also `direct_link_nodetree()` in readfile.c. */
+#if 0
+ function_callback(id, &key, (void **)&nodetree->previews, 0, user_data);
+#endif
+
+ if (nodetree->type == NTREE_COMPOSIT) {
+ for (bNode *node = nodetree->nodes.first; node; node = node->next) {
+ if (node->type == CMP_NODE_MOVIEDISTORTION) {
+ key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(node->name);
+ key.cache_v = node->storage;
+ function_callback(id, &key, (void **)&node->storage, 0, user_data);
+ }
+ }
+ }
+}
+
IDTypeInfo IDType_ID_NT = {
.id_code = ID_NT,
.id_filter = FILTER_ID_NT,
@@ -330,6 +358,7 @@ IDTypeInfo IDType_ID_NT = {
.free_data = ntree_free_data,
.make_local = NULL,
.foreach_id = node_foreach_id,
+ .foreach_cache = node_foreach_cache,
};
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
@@ -817,12 +846,12 @@ static void socket_id_user_increment(bNodeSocket *sock)
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
bNodeSocketValueObject *default_value = sock->default_value;
- id_us_plus(&default_value->value->id);
+ id_us_plus((ID *)default_value->value);
break;
}
case SOCK_IMAGE: {
bNodeSocketValueImage *default_value = sock->default_value;
- id_us_plus(&default_value->value->id);
+ id_us_plus((ID *)default_value->value);
break;
}
case SOCK_FLOAT:
@@ -2465,6 +2494,7 @@ ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree)
&bmain->textures,
&bmain->scenes,
&bmain->linestyles,
+ &bmain->simulations,
NULL};
for (int i = 0; lists[i] != NULL; i++) {
@@ -3609,6 +3639,16 @@ void ntreeUpdateAllUsers(Main *main, ID *ngroup)
FOREACH_NODETREE_END;
}
+static void ntreeUpdateSimulationDependencies(Main *main, bNodeTree *simulation_ntree)
+{
+ FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
+ if (GS(owner_id->name) == ID_SIM && ntree == simulation_ntree) {
+ BKE_simulation_update_dependencies((Simulation *)owner_id, main);
+ }
+ }
+ FOREACH_NODETREE_END;
+}
+
void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
{
bNode *node;
@@ -3651,7 +3691,6 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
ntreeInterfaceTypeUpdate(ntree);
}
- /* XXX hack, should be done by depsgraph!! */
if (bmain) {
ntreeUpdateAllUsers(bmain, &ntree->id);
}
@@ -3667,6 +3706,11 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
ntree_validate_links(ntree);
}
+ if (bmain != NULL && ntree->typeinfo == ntreeType_Simulation &&
+ (ntree->id.flag & LIB_EMBEDDED_DATA)) {
+ ntreeUpdateSimulationDependencies(bmain, ntree);
+ }
+
/* clear update flags */
for (node = ntree->nodes.first; node; node = node->next) {
node->update = 0;
@@ -4308,6 +4352,8 @@ static void registerSimulationNodes(void)
register_node_type_sim_emit_particles();
register_node_type_sim_time();
register_node_type_sim_particle_attribute();
+ register_node_type_sim_age_reached_event();
+ register_node_type_sim_kill_particle();
}
static void registerFunctionNodes(void)
@@ -4317,6 +4363,8 @@ static void registerFunctionNodes(void)
register_node_type_fn_switch();
register_node_type_fn_group_instance_id();
register_node_type_fn_combine_strings();
+ register_node_type_fn_object_transforms();
+ register_node_type_fn_random_float();
}
void init_nodesystem(void)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 6331f87f09f..fe559d2a44e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1760,7 +1760,7 @@ Object *BKE_object_copy(Main *bmain, const Object *ob)
*/
Object *BKE_object_duplicate(Main *bmain,
Object *ob,
- const eDupli_ID_Flags dupflag,
+ eDupli_ID_Flags dupflag,
const eLibIDDuplicateFlags duplicate_options)
{
const bool is_subprocess = (duplicate_options & LIB_ID_DUPLICATE_IS_SUBPROCESS) != 0;
@@ -1768,10 +1768,14 @@ Object *BKE_object_duplicate(Main *bmain,
if (!is_subprocess) {
BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
BKE_main_id_clear_newpoins(bmain);
+ /* In case root duplicated ID is linked, assume we want to get a local copy of it and duplicate
+ * all expected linked data. */
+ if (ID_IS_LINKED(ob)) {
+ dupflag |= USER_DUP_LINKED_ID;
+ }
}
Material ***matarar;
- const bool is_object_liboverride = ID_IS_OVERRIDE_LIBRARY(ob);
Object *obn;
BKE_id_copy(bmain, &ob->id, (ID **)&obn);
@@ -1785,112 +1789,109 @@ Object *BKE_object_duplicate(Main *bmain,
return obn;
}
- /* duplicates using userflags */
- if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, &obn->id, true);
- }
+ BKE_animdata_duplicate_id_action(bmain, &obn->id, dupflag);
if (dupflag & USER_DUP_MAT) {
for (int i = 0; i < obn->totcol; i++) {
- BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], is_object_liboverride, dupflag);
+ BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], dupflag);
}
}
if (dupflag & USER_DUP_PSYS) {
ParticleSystem *psys;
for (psys = obn->particlesystem.first; psys; psys = psys->next) {
- BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, is_object_liboverride, dupflag);
+ BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, dupflag);
}
}
- ID *id = obn->data;
+ ID *id_old = obn->data;
ID *id_new = NULL;
- const bool need_to_duplicate_obdata = (id != NULL) && (id->newid == NULL);
+ const bool need_to_duplicate_obdata = (id_old != NULL) && (id_old->newid == NULL);
switch (obn->type) {
case OB_MESH:
if (dupflag & USER_DUP_MESH) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_CURVE:
if (dupflag & USER_DUP_CURVE) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_SURF:
if (dupflag & USER_DUP_SURF) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_FONT:
if (dupflag & USER_DUP_FONT) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_MBALL:
if (dupflag & USER_DUP_MBALL) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_LAMP:
if (dupflag & USER_DUP_LAMP) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_ARMATURE:
if (dupflag & USER_DUP_ARM) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_LATTICE:
if (dupflag != 0) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_CAMERA:
if (dupflag != 0) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_LIGHTPROBE:
if (dupflag & USER_DUP_LIGHTPROBE) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_SPEAKER:
if (dupflag != 0) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_GPENCIL:
if (dupflag & USER_DUP_GPENCIL) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_HAIR:
if (dupflag & USER_DUP_HAIR) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_POINTCLOUD:
if (dupflag & USER_DUP_POINTCLOUD) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
case OB_VOLUME:
if (dupflag & USER_DUP_VOLUME) {
- id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
+ id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
}
break;
}
/* If obdata has been copied, we may also have to duplicate the materials assigned to it. */
- if (need_to_duplicate_obdata && id_new != NULL) {
+ if (need_to_duplicate_obdata && !ELEM(id_new, NULL, id_old)) {
if (dupflag & USER_DUP_MAT) {
matarar = BKE_object_material_array_p(obn);
if (matarar) {
for (int i = 0; i < obn->totcol; i++) {
- BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], is_object_liboverride, dupflag);
+ BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], dupflag);
}
}
}
@@ -2087,7 +2088,7 @@ void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob)
/* type conversions */
if (target->type == OB_ARMATURE) {
copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */
- BKE_pose_rest(ob->pose); /* clear all transforms in channels */
+ BKE_pose_rest(ob->pose, false); /* clear all transforms in channels */
BKE_pose_rebuild(bmain, ob, ob->data, true); /* set all internal links */
armature_set_id_extern(ob);
@@ -2343,7 +2344,7 @@ void BKE_object_tfm_copy(Object *object_dst, const Object *object_src)
#undef TFMCPY4D
}
-void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
+void BKE_object_to_mat3(Object *ob, float r_mat[3][3]) /* no parent */
{
float smat[3][3];
float rmat[3][3];
@@ -2354,38 +2355,38 @@ void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
/* rot */
BKE_object_rot_to_mat3(ob, rmat, true);
- mul_m3_m3m3(mat, rmat, smat);
+ mul_m3_m3m3(r_mat, rmat, smat);
}
-void BKE_object_to_mat4(Object *ob, float mat[4][4])
+void BKE_object_to_mat4(Object *ob, float r_mat[4][4])
{
float tmat[3][3];
BKE_object_to_mat3(ob, tmat);
- copy_m4_m3(mat, tmat);
+ copy_m4_m3(r_mat, tmat);
- add_v3_v3v3(mat[3], ob->loc, ob->dloc);
+ add_v3_v3v3(r_mat[3], ob->loc, ob->dloc);
}
-void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4])
+void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4])
{
if (ob->parent) {
float par_imat[4][4];
BKE_object_get_parent_matrix(ob, ob->parent, par_imat);
invert_m4(par_imat);
- mul_m4_m4m4(mat, par_imat, ob->obmat);
+ mul_m4_m4m4(r_mat, par_imat, ob->obmat);
}
else {
- copy_m4_m4(mat, ob->obmat);
+ copy_m4_m4(r_mat, ob->obmat);
}
}
/**
* \return success if \a mat is set.
*/
-static bool ob_parcurve(Object *ob, Object *par, float mat[4][4])
+static bool ob_parcurve(Object *ob, Object *par, float r_mat[4][4])
{
Curve *cu = par->data;
float vec[4], dir[3], quat[4], radius, ctime;
@@ -2408,7 +2409,7 @@ static bool ob_parcurve(Object *ob, Object *par, float mat[4][4])
/* ctime is now a proper var setting of Curve which gets set by Animato like any other var
* that's animated, but this will only work if it actually is animated.
*
- * We divide the curvetime calculated in the previous step by the length of the path,
+ * We divide the curve-time calculated in the previous step by the length of the path,
* to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range.
*/
if (cu->pathlen) {
@@ -2419,34 +2420,34 @@ static bool ob_parcurve(Object *ob, Object *par, float mat[4][4])
}
CLAMP(ctime, 0.0f, 1.0f);
- unit_m4(mat);
+ unit_m4(r_mat);
/* vec: 4 items! */
if (where_on_path(par, ctime, vec, dir, (cu->flag & CU_FOLLOW) ? quat : NULL, &radius, NULL)) {
if (cu->flag & CU_FOLLOW) {
quat_apply_track(quat, ob->trackflag, ob->upflag);
normalize_qt(quat);
- quat_to_mat4(mat, quat);
+ quat_to_mat4(r_mat, quat);
}
if (cu->flag & CU_PATH_RADIUS) {
float tmat[4][4], rmat[4][4];
scale_m4_fl(tmat, radius);
- mul_m4_m4m4(rmat, tmat, mat);
- copy_m4_m4(mat, rmat);
+ mul_m4_m4m4(rmat, tmat, r_mat);
+ copy_m4_m4(r_mat, rmat);
}
- copy_v3_v3(mat[3], vec);
+ copy_v3_v3(r_mat[3], vec);
}
return true;
}
-static void ob_parbone(Object *ob, Object *par, float mat[4][4])
+static void ob_parbone(Object *ob, Object *par, float r_mat[4][4])
{
bPoseChannel *pchan;
float vec[3];
if (par->type != OB_ARMATURE) {
- unit_m4(mat);
+ unit_m4(r_mat);
return;
}
@@ -2455,7 +2456,7 @@ static void ob_parbone(Object *ob, Object *par, float mat[4][4])
if (!pchan || !pchan->bone) {
CLOG_ERROR(
&LOG, "Object %s with Bone parent: bone %s doesn't exist", ob->id.name + 2, ob->parsubstr);
- unit_m4(mat);
+ unit_m4(r_mat);
return;
}
@@ -2463,15 +2464,15 @@ static void ob_parbone(Object *ob, Object *par, float mat[4][4])
if (pchan->bone->flag & BONE_RELATIVE_PARENTING) {
/* the new option uses the root - expected behavior, but differs from old... */
/* XXX check on version patching? */
- copy_m4_m4(mat, pchan->chan_mat);
+ copy_m4_m4(r_mat, pchan->chan_mat);
}
else {
- copy_m4_m4(mat, pchan->pose_mat);
+ copy_m4_m4(r_mat, pchan->pose_mat);
/* but for backwards compatibility, the child has to move to the tail */
- copy_v3_v3(vec, mat[1]);
+ copy_v3_v3(vec, r_mat[1]);
mul_v3_fl(vec, pchan->bone->length);
- add_v3_v3(mat[3], vec);
+ add_v3_v3(r_mat[3], vec);
}
}
@@ -2593,7 +2594,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
}
-static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
+static void ob_parvert3(Object *ob, Object *par, float r_mat[4][4])
{
/* in local ob space */
@@ -2606,16 +2607,16 @@ static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
tri_to_quat(q, v1, v2, v3);
quat_to_mat3(cmat, q);
- copy_m4_m3(mat, cmat);
+ copy_m4_m3(r_mat, cmat);
- mid_v3_v3v3v3(mat[3], v1, v2, v3);
+ mid_v3_v3v3v3(r_mat[3], v1, v2, v3);
}
else {
- unit_m4(mat);
+ unit_m4(r_mat);
}
}
-void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4])
+void BKE_object_get_parent_matrix(Object *ob, Object *par, float r_parentmat[4][4])
{
float tmat[4][4];
float vec[3];
@@ -2631,31 +2632,31 @@ void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4]
}
if (ok) {
- mul_m4_m4m4(parentmat, par->obmat, tmat);
+ mul_m4_m4m4(r_parentmat, par->obmat, tmat);
}
else {
- copy_m4_m4(parentmat, par->obmat);
+ copy_m4_m4(r_parentmat, par->obmat);
}
break;
case PARBONE:
ob_parbone(ob, par, tmat);
- mul_m4_m4m4(parentmat, par->obmat, tmat);
+ mul_m4_m4m4(r_parentmat, par->obmat, tmat);
break;
case PARVERT1:
- unit_m4(parentmat);
+ unit_m4(r_parentmat);
give_parvert(par, ob->par1, vec);
- mul_v3_m4v3(parentmat[3], par->obmat, vec);
+ mul_v3_m4v3(r_parentmat[3], par->obmat, vec);
break;
case PARVERT3:
ob_parvert3(ob, par, tmat);
- mul_m4_m4m4(parentmat, par->obmat, tmat);
+ mul_m4_m4m4(r_parentmat, par->obmat, tmat);
break;
case PARSKEL:
- copy_m4_m4(parentmat, par->obmat);
+ copy_m4_m4(r_parentmat, par->obmat);
break;
}
}
@@ -2671,7 +2672,7 @@ void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4]
* (without its own matrix applied)
*/
static void solve_parenting(
- Object *ob, Object *par, float obmat[4][4], float r_originmat[3][3], const bool set_origin)
+ Object *ob, Object *par, const bool set_origin, float r_obmat[4][4], float r_originmat[3][3])
{
float totmat[4][4];
float tmat[4][4];
@@ -2683,7 +2684,7 @@ static void solve_parenting(
/* total */
mul_m4_m4m4(tmat, totmat, ob->parentinv);
- mul_m4_m4m4(obmat, tmat, locmat);
+ mul_m4_m4m4(r_obmat, tmat, locmat);
if (r_originmat) {
/* usable originmat */
@@ -2713,7 +2714,7 @@ static void object_where_is_calc_ex(Depsgraph *depsgraph,
Object *par = ob->parent;
/* calculate parent matrix */
- solve_parenting(ob, par, ob->obmat, r_originmat, true);
+ solve_parenting(ob, par, true, ob->obmat, r_originmat);
}
else {
BKE_object_to_mat4(ob, ob->obmat);
@@ -2745,7 +2746,10 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
{
/* Execute drivers and animation. */
const bool flush_to_original = DEG_is_active(depsgraph);
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_ALL, flush_to_original);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
+ BKE_animsys_evaluate_animdata(
+ &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ALL, flush_to_original);
object_where_is_calc_ex(depsgraph, scene, ob, ctime, NULL, NULL);
}
@@ -2753,14 +2757,14 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
* constraints -- assume dependencies are already solved by depsgraph.
* no changes to object and it's parent would be done.
* used for bundles orientation in 3d space relative to parented blender camera */
-void BKE_object_where_is_calc_mat4(Object *ob, float obmat[4][4])
+void BKE_object_where_is_calc_mat4(Object *ob, float r_obmat[4][4])
{
if (ob->parent) {
Object *par = ob->parent;
- solve_parenting(ob, par, obmat, NULL, false);
+ solve_parenting(ob, par, false, r_obmat, NULL);
}
else {
- BKE_object_to_mat4(ob, obmat);
+ BKE_object_to_mat4(ob, r_obmat);
}
}
@@ -2821,8 +2825,11 @@ void BKE_object_workob_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *o
* \param use_compat: true to ensure that rotations are set using the
* min difference between the old and new orientation.
*/
-void BKE_object_apply_mat4_ex(
- Object *ob, float mat[4][4], Object *parent, float parentinv[4][4], const bool use_compat)
+void BKE_object_apply_mat4_ex(Object *ob,
+ const float mat[4][4],
+ Object *parent,
+ const float parentinv[4][4],
+ const bool use_compat)
{
/* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
@@ -2863,7 +2870,7 @@ void BKE_object_apply_mat4_ex(
/* XXX: should be removed after COW operators port to use BKE_object_apply_mat4_ex directly */
void BKE_object_apply_mat4(Object *ob,
- float mat[4][4],
+ const float mat[4][4],
const bool use_compat,
const bool use_parent)
{
@@ -2913,7 +2920,10 @@ void BKE_boundbox_calc_size_aabb(const BoundBox *bb, float r_size[3])
r_size[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]);
}
-void BKE_boundbox_minmax(const BoundBox *bb, float obmat[4][4], float r_min[3], float r_max[3])
+void BKE_boundbox_minmax(const BoundBox *bb,
+ const float obmat[4][4],
+ float r_min[3],
+ float r_max[3])
{
int i;
for (i = 0; i < 8; i++) {
@@ -3005,7 +3015,7 @@ void BKE_object_boundbox_calc_from_mesh(struct Object *ob, struct Mesh *me_eval)
* \warning Setting dimensions is prone to feedback loops in evaluation.
* \{ */
-void BKE_object_dimensions_get(Object *ob, float vec[3])
+void BKE_object_dimensions_get(Object *ob, float r_vec[3])
{
BoundBox *bb = NULL;
@@ -3015,12 +3025,12 @@ void BKE_object_dimensions_get(Object *ob, float vec[3])
mat4_to_size(scale, ob->obmat);
- vec[0] = fabsf(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
- vec[1] = fabsf(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
- vec[2] = fabsf(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
+ r_vec[0] = fabsf(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
+ r_vec[1] = fabsf(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
+ r_vec[2] = fabsf(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
}
else {
- zero_v3(vec);
+ zero_v3(r_vec);
}
}
@@ -3058,9 +3068,9 @@ void BKE_object_dimensions_set_ex(Object *ob,
}
}
- if (len[i] > 0.0f) {
-
- ob->scale[i] = copysignf(value[i] / len[i], ob->scale[i]);
+ const float scale = copysignf(value[i] / len[i], ob->scale[i]);
+ if (isfinite(scale)) {
+ ob->scale[i] = scale;
}
}
}
@@ -3289,7 +3299,7 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
}
void BKE_object_foreach_display_point(Object *ob,
- float obmat[4][4],
+ const float obmat[4][4],
void (*func_cb)(const float[3], void *),
void *user_data)
{
@@ -3960,15 +3970,20 @@ int BKE_object_is_modified(Scene *scene, Object *ob)
return flag;
}
-/* Check of objects moves in time. */
-/* NOTE: This function is currently optimized for usage in combination
- * with mti->canDeform, so modifiers can quickly check if their target
- * objects moves (causing deformation motion blur) or not.
+/**
+ * Check of objects moves in time.
+ *
+ * \note This function is currently optimized for usage in combination
+ * with modifier deformation checks (#eModifierTypeType_OnlyDeform),
+ * so modifiers can quickly check if their target objects moves
+ * (causing deformation motion blur) or not.
*
* This makes it possible to give some degree of false-positives here,
* but it's currently an acceptable tradeoff between complexity and check
* speed. In combination with checks of modifier stack and real life usage
- * percentage of false-positives shouldn't be that height.
+ * percentage of false-positives shouldn't be that high.
+ *
+ * \note This function does not consider physics systems.
*/
bool BKE_object_moves_in_time(const Object *object, bool recurse_parent)
{
@@ -4642,9 +4657,13 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
/* was originally ID_RECALC_ALL - TODO - which flags are really needed??? */
/* TODO(sergey): What about animation? */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ frame);
+
ob->id.recalc |= ID_RECALC_ALL;
if (update_mesh) {
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
/* ignore cache clear during subframe updates
* to not mess up cache validity */
object_cacheIgnoreClear(ob, 1);
@@ -4658,12 +4677,14 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
/* for curve following objects, parented curve has to be updated too */
if (ob->type == OB_CURVE) {
Curve *cu = ob->data;
- BKE_animsys_evaluate_animdata(&cu->id, cu->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &cu->id, cu->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
}
/* and armatures... */
if (ob->type == OB_ARMATURE) {
bArmature *arm = ob->data;
- BKE_animsys_evaluate_animdata(&arm->id, arm->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &arm->id, arm->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
BKE_pose_where_is(depsgraph, scene, ob);
}
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index 6ca1442497a..51ec89cf77d 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -68,7 +68,7 @@ static Lattice *object_defgroup_lattice_get(ID *id)
*
* \param map: an array mapping old indices to new indices.
*/
-void BKE_object_defgroup_remap_update_users(Object *ob, int *map)
+void BKE_object_defgroup_remap_update_users(Object *ob, const int *map)
{
ModifierData *md;
ParticleSystem *psys;
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 4c6354f12a1..e0aea3a2910 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -37,6 +37,7 @@
#include "DNA_collection_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
@@ -186,7 +187,7 @@ static DupliObject *make_dupli(const DupliContext *ctx, Object *ob, float mat[4]
dob->random_id = BLI_hash_string(dob->ob->id.name + 2);
if (dob->persistent_id[0] != INT_MAX) {
- for (i = 0; i < MAX_DUPLI_RECUR * 2; i++) {
+ for (i = 0; i < MAX_DUPLI_RECUR; i++) {
dob->random_id = BLI_hash_int_2d(dob->random_id, (unsigned int)dob->persistent_id[i]);
}
}
@@ -367,17 +368,13 @@ static void vertex_dupli(const VertexDupliData *vdd,
DupliObject *dob;
float obmat[4][4], space_mat[4][4];
- /* obmat is transform to vertex */
- get_duplivert_transform(co, no, vdd->use_rotation, inst_ob->trackflag, inst_ob->upflag, obmat);
+ /* space_mat is transform to vertex */
+ get_duplivert_transform(
+ co, no, vdd->use_rotation, inst_ob->trackflag, inst_ob->upflag, space_mat);
/* make offset relative to inst_ob using relative child transform */
- mul_mat3_m4_v3((float(*)[4])vdd->child_imat, obmat[3]);
+ mul_mat3_m4_v3((float(*)[4])vdd->child_imat, space_mat[3]);
/* apply obmat _after_ the local vertex transform */
- mul_m4_m4m4(obmat, inst_ob->obmat, obmat);
-
- /* space matrix is constructed by removing obmat transform,
- * this yields the worldspace transform for recursive duplis
- */
- mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
+ mul_m4_m4m4(obmat, inst_ob->obmat, space_mat);
dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index);
@@ -523,7 +520,7 @@ static void make_duplis_font(const DupliContext *ctx)
/* Safety check even if it might fail badly when called for original object. */
const bool is_eval_curve = DEG_is_evaluated_id(&cu->id);
- /* advance matching BLI_strncpy_wchar_from_utf8 */
+ /* Advance matching BLI_str_utf8_as_utf32. */
for (a = 0; a < text_len; a++, ct++) {
/* XXX That G.main is *really* ugly, but not sure what to do here...
@@ -573,6 +570,63 @@ static const DupliGenerator gen_dupli_verts_font = {
make_duplis_font /* make_duplis */
};
+/* OB_DUPLIVERTS - PointCloud */
+static void make_child_duplis_pointcloud(const DupliContext *ctx,
+ void *UNUSED(userdata),
+ Object *child)
+{
+ const Object *parent = ctx->object;
+ const PointCloud *pointcloud = parent->data;
+ const float(*co)[3] = pointcloud->co;
+ const float *radius = pointcloud->radius;
+ const float(*rotation)[4] = NULL; /* TODO: add optional rotation attribute. */
+ const float(*orco)[3] = NULL; /* TODO: add optional texture coordinate attribute. */
+
+ /* Relative transform from parent to child space. */
+ float child_imat[4][4];
+ mul_m4_m4m4(child_imat, child->imat, parent->obmat);
+
+ for (int i = 0; i < pointcloud->totpoint; i++) {
+ /* Transform matrix from point position, radius and rotation. */
+ float quat[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ float size[3] = {1.0f, 1.0f, 1.0f};
+ if (radius) {
+ copy_v3_fl(size, radius[i]);
+ }
+ if (rotation) {
+ copy_v4_v4(quat, rotation[i]);
+ }
+
+ float space_mat[4][4];
+ loc_quat_size_to_mat4(space_mat, co[i], quat, size);
+
+ /* Make offset relative to child object using relative child transform,
+ * and apply object matrix after local vertex transform. */
+ mul_mat3_m4_v3(child_imat, space_mat[3]);
+
+ /* Create dupli object. */
+ float obmat[4][4];
+ mul_m4_m4m4(obmat, child->obmat, space_mat);
+ DupliObject *dob = make_dupli(ctx, child, obmat, i);
+ if (orco) {
+ copy_v3_v3(dob->orco, orco[i]);
+ }
+
+ /* Recursion. */
+ make_recursive_duplis(ctx, child, space_mat, i);
+ }
+}
+
+static void make_duplis_pointcloud(const DupliContext *ctx)
+{
+ make_child_duplis(ctx, NULL, make_child_duplis_pointcloud);
+}
+
+static const DupliGenerator gen_dupli_verts_pointcloud = {
+ OB_DUPLIVERTS, /* type */
+ make_duplis_pointcloud /* make_duplis */
+};
+
/* OB_DUPLIFACES */
typedef struct FaceDupliData {
Mesh *me_eval;
@@ -1105,6 +1159,9 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
else if (ctx->object->type == OB_FONT) {
return &gen_dupli_verts_font;
}
+ else if (ctx->object->type == OB_POINTCLOUD) {
+ return &gen_dupli_verts_pointcloud;
+ }
}
else if (transflag & OB_DUPLIFACES) {
if (ctx->object->type == OB_MESH) {
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 8957628c76a..198ff5a0540 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -147,19 +147,19 @@ static void init_complex(fftw_complex cmpl, float real, float image)
cmpl[1] = image;
}
-static void add_comlex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl2)
+static void add_comlex_c(fftw_complex res, const fftw_complex cmpl1, const fftw_complex cmpl2)
{
res[0] = cmpl1[0] + cmpl2[0];
res[1] = cmpl1[1] + cmpl2[1];
}
-static void mul_complex_f(fftw_complex res, fftw_complex cmpl, float f)
+static void mul_complex_f(fftw_complex res, const fftw_complex cmpl, float f)
{
res[0] = cmpl[0] * (double)f;
res[1] = cmpl[1] * (double)f;
}
-static void mul_complex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl2)
+static void mul_complex_c(fftw_complex res, const fftw_complex cmpl1, const fftw_complex cmpl2)
{
fftwf_complex temp;
temp[0] = cmpl1[0] * cmpl2[0] - cmpl1[1] * cmpl2[1];
@@ -178,7 +178,7 @@ static float image_c(fftw_complex cmpl)
return cmpl[1];
}
-static void conj_complex(fftw_complex res, fftw_complex cmpl1)
+static void conj_complex(fftw_complex res, const fftw_complex cmpl1)
{
res[0] = cmpl1[0];
res[1] = -cmpl1[1];
@@ -753,18 +753,26 @@ struct Ocean *BKE_ocean_add(void)
return oc;
}
-bool BKE_ocean_ensure(struct OceanModifierData *omd)
+bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution)
{
if (omd->ocean) {
- return false;
+ /* Check that the ocean has the same resolution than we want now. */
+ if (omd->ocean->_M == resolution * resolution) {
+ return false;
+ }
+ else {
+ BKE_ocean_free(omd->ocean);
+ }
}
omd->ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(omd->ocean, omd);
+ BKE_ocean_init_from_modifier(omd->ocean, omd, resolution);
return true;
}
-void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd)
+void BKE_ocean_init_from_modifier(struct Ocean *ocean,
+ struct OceanModifierData const *omd,
+ const int resolution)
{
short do_heightfield, do_chop, do_normals, do_jacobian;
@@ -774,9 +782,10 @@ void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData
do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
BKE_ocean_free_data(ocean);
+
BKE_ocean_init(ocean,
- omd->resolution * omd->resolution,
- omd->resolution * omd->resolution,
+ resolution * resolution,
+ resolution * resolution,
omd->spatial_size,
omd->spatial_size,
omd->wind_velocity,
@@ -831,7 +840,7 @@ void BKE_ocean_init(struct Ocean *o,
o->_A = A;
o->_w = w;
o->_damp_reflections = 1.0f - damp;
- o->_wind_alignment = alignment;
+ o->_wind_alignment = alignment * 10.0f;
o->_depth = depth;
o->_Lx = Lx;
o->_Lz = Lz;
@@ -845,7 +854,7 @@ void BKE_ocean_init(struct Ocean *o,
/* Common JONSWAP parameters. */
o->_fetch_jonswap = fetch_jonswap;
- o->_sharpen_peak_jonswap = sharpen_peak_jonswap;
+ o->_sharpen_peak_jonswap = sharpen_peak_jonswap * 10.0f;
o->_do_disp_y = do_height_field;
o->_do_normals = do_normals;
@@ -1607,7 +1616,8 @@ void BKE_ocean_bake(struct Ocean *UNUSED(o),
}
void BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean),
- struct OceanModifierData const *UNUSED(omd))
+ struct OceanModifierData const *UNUSED(omd),
+ int UNUSED(resolution))
{
}
diff --git a/source/blender/blenkernel/intern/ocean_intern.h b/source/blender/blenkernel/intern/ocean_intern.h
index 7da88419219..39ce0db09d6 100644
--- a/source/blender/blenkernel/intern/ocean_intern.h
+++ b/source/blender/blenkernel/intern/ocean_intern.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_OCEAN_INTERN_H__
-#define __BKE_OCEAN_INTERN_H__
+#pragma once
/** \file
* \ingroup bli
@@ -133,5 +132,3 @@ typedef struct Ocean {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index b3ab856468c..e7ff53f27b6 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1314,6 +1314,13 @@ static void sculptsession_free_pbvh(Object *object)
MEM_SAFE_FREE(ss->preview_vert_index_list);
ss->preview_vert_index_count = 0;
+
+ MEM_SAFE_FREE(ss->preview_vert_index_list);
+
+ MEM_SAFE_FREE(ss->vertex_info.connected_component);
+ MEM_SAFE_FREE(ss->vertex_info.boundary);
+
+ MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index);
}
void BKE_sculptsession_bm_to_me_for_render(Object *object)
@@ -1366,11 +1373,6 @@ void BKE_sculptsession_free(Object *ob)
MEM_SAFE_FREE(ss->deform_cos);
MEM_SAFE_FREE(ss->deform_imats);
- MEM_SAFE_FREE(ss->preview_vert_index_list);
-
- MEM_SAFE_FREE(ss->vertex_info.connected_component);
- MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index);
-
if (ss->pose_ik_chain_preview) {
for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
MEM_SAFE_FREE(ss->pose_ik_chain_preview->segments[i].weights);
@@ -1482,7 +1484,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
Mesh *me_eval,
bool need_pmap,
bool need_mask,
- bool need_colors)
+ bool UNUSED(need_colors))
{
Scene *scene = DEG_get_input_scene(depsgraph);
Sculpt *sd = scene->toolsettings->sculpt;
@@ -1491,6 +1493,8 @@ static void sculpt_update_object(Depsgraph *depsgraph,
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
+ ss->depsgraph = depsgraph;
+
ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob);
ss->show_mask = (sd->flags & SCULPT_HIDE_MASK) == 0;
ss->show_face_sets = (sd->flags & SCULPT_HIDE_FACE_SETS) == 0;
@@ -1512,16 +1516,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
}
}
- /* Add a color layer if a color tool is used. */
- Mesh *orig_me = BKE_object_get_original_mesh(ob);
- if (need_colors) {
- if (!CustomData_has_layer(&orig_me->vdata, CD_PROP_COLOR)) {
- CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
- BKE_mesh_update_customdata_pointers(orig_me, true);
- DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY);
- }
- }
-
/* tessfaces aren't used and will become invalid */
BKE_mesh_tessface_clear(me);
@@ -1682,10 +1676,25 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
BLI_assert(me_eval != NULL);
-
sculpt_update_object(depsgraph, ob_orig, me_eval, false, false, false);
}
+void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
+{
+ Mesh *orig_me = BKE_object_get_original_mesh(object);
+ if (!U.experimental.use_sculpt_vertex_colors) {
+ return;
+ }
+
+ if (CustomData_has_layer(&orig_me->vdata, CD_PROP_COLOR)) {
+ return;
+ }
+
+ CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
+ BKE_mesh_update_customdata_pointers(orig_me, true);
+ DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY);
+}
+
void BKE_sculpt_update_object_for_edit(
Depsgraph *depsgraph, Object *ob_orig, bool need_pmap, bool need_mask, bool need_colors)
{
@@ -1817,6 +1826,64 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
return deformed;
}
+static void sculpt_sync_face_sets_visibility_to_base_mesh(Mesh *mesh)
+{
+ int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ if (!face_sets) {
+ return;
+ }
+
+ for (int i = 0; i < mesh->totvert; i++) {
+ mesh->mvert[i].flag |= ME_HIDE;
+ }
+
+ for (int i = 0; i < mesh->totpoly; i++) {
+ if (face_sets[i] >= 0) {
+ for (int l = 0; l < mesh->mpoly[i].totloop; l++) {
+ MLoop *loop = &mesh->mloop[mesh->mpoly[i].loopstart + l];
+ mesh->mvert[loop->v].flag &= ~ME_HIDE;
+ }
+ }
+ }
+}
+
+static void sculpt_sync_face_sets_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
+{
+ int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ if (!face_sets) {
+ return;
+ }
+
+ if (!subdiv_ccg) {
+ return;
+ }
+
+ CCGKey key;
+ BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
+ for (int i = 0; i < mesh->totloop; i++) {
+ const int face_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, i);
+ const bool is_hidden = (face_sets[face_index] < 0);
+
+ /* Avoid creating and modifying the grid_hidden bitmap if the base mesh face is visible and
+ * there is not bitmap for the grid. This is because missing grid_hidden implies grid is fully
+ * visible. */
+ if (is_hidden) {
+ BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg, i);
+ }
+
+ BLI_bitmap *gh = subdiv_ccg->grid_hidden[i];
+ if (gh) {
+ BLI_bitmap_set_all(gh, is_hidden, key.grid_area);
+ }
+ }
+}
+
+void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *subdiv_ccg)
+{
+ sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
+ sculpt_sync_face_sets_visibility_to_grids(mesh, subdiv_ccg);
+}
+
static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
{
PBVH *pbvh = BKE_pbvh_new();
@@ -1842,6 +1909,8 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
+ BKE_sculpt_sync_face_set_visibility(me, NULL);
+
BKE_pbvh_build_mesh(pbvh,
me,
me->mpoly,
@@ -1874,6 +1943,10 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
PBVH *pbvh = BKE_pbvh_new();
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
+
+ Mesh *base_mesh = BKE_mesh_from_object(ob);
+ BKE_sculpt_sync_face_set_visibility(base_mesh, subdiv_ccg);
+
BKE_pbvh_build_grids(pbvh,
subdiv_ccg->grids,
subdiv_ccg->num_grids,
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 942f3e0ca2b..1df5cda0ce5 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -283,8 +283,8 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur)
}
return tot;
}
-/* we allocate path cache memory in chunks instead of a big contiguous
- * chunk, windows' memory allocater fails to find big blocks of memory often */
+/* We allocate path cache memory in chunks instead of a big contiguous
+ * chunk, windows' memory allocator fails to find big blocks of memory often. */
#define PATH_CACHE_BUF_SIZE 1024
@@ -1297,7 +1297,7 @@ static void do_particle_interpolation(ParticleSystem *psys,
dfra = keys[2].time - keys[1].time;
keytime = (real_t - keys[1].time) / dfra;
- /* convert velocity to timestep size */
+ /* Convert velocity to time-step size. */
if (pind->keyed || pind->cache || point_vel) {
invdt = dfra * 0.04f * (psys ? psys->part->timetweak : 1.f);
mul_v3_fl(keys[1].vel, invdt);
@@ -1305,8 +1305,8 @@ static void do_particle_interpolation(ParticleSystem *psys,
interp_qt_qtqt(result->rot, keys[1].rot, keys[2].rot, keytime);
}
- /* Now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between
- * [0, 1]->[k2, k3] (k1 & k4 used for cardinal & bspline interpolation). */
+ /* Now we should have in chronological order k1<=k2<=t<=k3<=k4 with key-time between
+ * [0, 1]->[k2, k3] (k1 & k4 used for cardinal & b-spline interpolation). */
psys_interpolate_particle((pind->keyed || pind->cache || point_vel) ?
-1 /* signal for cubic interpolation */
:
@@ -3611,7 +3611,8 @@ void psys_mat_hair_to_global(
/************************************************/
/* ParticleSettings handling */
/************************************************/
-ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob, const char *name)
+static ModifierData *object_add_or_copy_particle_system(
+ Main *bmain, Scene *scene, Object *ob, const char *name, const ParticleSystem *psys_orig)
{
ParticleSystem *psys;
ModifierData *md;
@@ -3622,7 +3623,7 @@ ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob,
}
if (name == NULL) {
- name = DATA_("ParticleSettings");
+ name = (psys_orig != NULL) ? psys_orig->name : DATA_("ParticleSettings");
}
psys = ob->particlesystem.first;
@@ -3635,8 +3636,13 @@ ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob,
BLI_addtail(&ob->particlesystem, psys);
psys_unique_name(ob, psys, name);
- psys->part = BKE_particlesettings_add(bmain, psys->name);
-
+ if (psys_orig != NULL) {
+ psys->part = psys_orig->part;
+ id_us_plus(&psys->part->id);
+ }
+ else {
+ psys->part = BKE_particlesettings_add(bmain, psys->name);
+ }
md = BKE_modifier_new(eModifierType_ParticleSystem);
BLI_strncpy(md->name, psys->name, sizeof(md->name));
BKE_modifier_unique_name(&ob->modifiers, md);
@@ -3656,6 +3662,20 @@ ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob,
return md;
}
+
+ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob, const char *name)
+{
+ return object_add_or_copy_particle_system(bmain, scene, ob, name, NULL);
+}
+
+ModifierData *object_copy_particle_system(Main *bmain,
+ Scene *scene,
+ Object *ob,
+ const ParticleSystem *psys_orig)
+{
+ return object_add_or_copy_particle_system(bmain, scene, ob, NULL, psys_orig);
+}
+
void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob)
{
ParticleSystem *psys = psys_get_current(ob);
@@ -3851,7 +3871,7 @@ void BKE_particlesettings_clump_curve_init(ParticleSettings *part)
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
part->clumpcurve = cumap;
}
@@ -3865,7 +3885,7 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
part->roughcurve = cumap;
}
@@ -3879,7 +3899,7 @@ void BKE_particlesettings_twist_curve_init(ParticleSettings *part)
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
part->twistcurve = cumap;
}
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index 7b9b2484dbe..e0dccd4d14a 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -433,7 +433,7 @@ static void psys_uv_to_w(float u, float v, int quad, float *w)
}
/* Find the index in "sum" array before "value" is crossed. */
-static int distribute_binary_search(float *sum, int n, float value)
+static int distribute_binary_search(const float *sum, int n, float value)
{
int mid, low = 0, high = n - 1;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 4dc4aea04a7..6bfbb4b9d00 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -570,7 +570,7 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
}
}
-static void initialize_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
+static void init_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
@@ -595,7 +595,7 @@ static void initialize_particle_texture(ParticleSimulationData *sim, ParticleDat
}
/* set particle parameters that don't change during particle's life */
-void initialize_particle(ParticleSimulationData *sim, ParticleData *pa)
+void init_particle(ParticleSimulationData *sim, ParticleData *pa)
{
ParticleSettings *part = sim->psys->part;
float birth_time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart;
@@ -629,7 +629,7 @@ static void initialize_all_particles(ParticleSimulationData *sim)
LOOP_PARTICLES
{
if (!(emit_from_volume_grid && (pa->flag & PARS_UNEXIST) != 0)) {
- initialize_particle(sim, pa);
+ init_particle(sim, pa);
}
}
}
@@ -1092,7 +1092,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
* We could only do it now because we'll need to know coordinate
* before sampling the texture.
*/
- initialize_particle_texture(sim, pa, p);
+ init_particle_texture(sim, pa, p);
if (part->phystype == PART_PHYS_BOIDS && pa->boid) {
BoidParticle *bpa = pa->boid;
@@ -1939,7 +1939,7 @@ static void sphclassical_density_accum_cb(void *userdata,
return;
}
- /* Smoothing factor. Utilise the Wendland kernel. gnuplot:
+ /* Smoothing factor. Utilize the Wendland kernel. gnuplot:
* q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x)
* plot [0:2] q1(x) */
q = qfac / pow3f(pfr->h) * pow4f(2.0f - rij_h) * (1.0f + 2.0f * rij_h);
@@ -2054,7 +2054,7 @@ static void sphclassical_force_cb(void *sphdata_v,
npressure = stiffness * (pow7f(npa->sphdensity / rest_density) - 1.0f);
- /* First derivative of smoothing factor. Utilise the Wendland kernel.
+ /* First derivative of smoothing factor. Utilize the Wendland kernel.
* gnuplot:
* q2(x) = 2.0 * (2.0 - x)**4 - 4.0 * (2.0 - x)**3 * (1.0 + 2.0 * x)
* plot [0:2] q2(x)
@@ -2947,7 +2947,7 @@ static int collision_response(ParticleSimulationData *sim,
/* get exact velocity right before collision */
madd_v3_v3v3fl(v0, col->ve1, col->acc, dt1);
- /* Convert collider velocity from 1/framestep to 1/s TODO:
+ /* Convert collider velocity from `1/frame_step` to `1/s` TODO:
* here we assume 1 frame step for collision modifier. */
mul_v3_fl(pce->vel, col->inv_timestep);
@@ -4584,7 +4584,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
psys->dt_frac = get_base_time_step(part);
}
else if ((int)cfra == startframe) {
- /* Variable time step; initialise to subframes */
+ /* Variable time step; initialize to sub-frames. */
psys->dt_frac = get_base_time_step(part);
}
else if (psys->dt_frac < MIN_TIMESTEP) {
@@ -4854,8 +4854,10 @@ void particle_system_update(struct Depsgraph *depsgraph,
for (i = 0; i <= part->hair_step; i++) {
hcfra = 100.0f * (float)i / (float)psys->part->hair_step;
if ((part->flag & PART_HAIR_REGROW) == 0) {
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, hcfra);
BKE_animsys_evaluate_animdata(
- &part_local->id, part_local->adt, hcfra, ADT_RECALC_ANIM, false);
+ &part_local->id, part_local->adt, &anim_eval_context, ADT_RECALC_ANIM, false);
}
system_step(&sim, hcfra, use_render_params);
psys->cfra = hcfra;
@@ -4966,6 +4968,7 @@ void particle_system_update(struct Depsgraph *depsgraph,
psys_orig->flag = (psys->flag & ~PSYS_SHARED_CACHES);
psys_orig->cfra = psys->cfra;
psys_orig->recalc = psys->recalc;
+ psys_orig->part->totpart = part->totpart;
}
}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 8d7dabf9859..92a47f24240 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -358,7 +358,7 @@ static void update_vb(PBVH *pbvh, PBVHNode *node, BBC *prim_bbc, int offset, int
/* Returns the number of visible quads in the nodes' grids. */
int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
- int *grid_indices,
+ const int *grid_indices,
int totgrid,
int gridsize)
{
@@ -644,7 +644,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
pbvh->totgrid = totgrid;
pbvh->gridkey = *key;
pbvh->grid_hidden = grid_hidden;
- pbvh->leaf_limit = max_ii(LEAF_LIMIT / ((gridsize - 1) * (gridsize - 1)), 1);
+ pbvh->leaf_limit = max_ii(LEAF_LIMIT / (gridsize * gridsize), 1);
BB cb;
BB_reset(&cb);
@@ -1542,7 +1542,7 @@ static void pbvh_update_visibility_task_cb(void *__restrict userdata,
PBVHUpdateData *data = userdata;
PBVH *pbvh = data->pbvh;
PBVHNode *node = data->nodes[n];
- if (node->flag & PBVH_UpdateMask) {
+ if (node->flag & PBVH_UpdateVisibility) {
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES:
pbvh_faces_node_visibility_update(pbvh, node);
@@ -1554,7 +1554,7 @@ static void pbvh_update_visibility_task_cb(void *__restrict userdata,
pbvh_bmesh_node_visibility_update(node);
break;
}
- node->flag &= ~PBVH_UpdateMask;
+ node->flag &= ~PBVH_UpdateVisibility;
}
}
@@ -1772,6 +1772,11 @@ void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
}
}
+bool BKE_pbvh_node_fully_hidden_get(PBVHNode *node)
+{
+ return (node->flag & PBVH_Leaf) && (node->flag & PBVH_FullyHidden);
+}
+
void BKE_pbvh_node_fully_masked_set(PBVHNode *node, int fully_masked)
{
BLI_assert(node->flag & PBVH_Leaf);
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index 6f8bae822ea..63bc8753fc7 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __PBVH_INTERN_H__
-#define __PBVH_INTERN_H__
+#pragma once
/** \file
* \ingroup bli
@@ -235,5 +234,3 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
bool use_original);
void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
-
-#endif
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 61308810191..c2c5b42dbb0 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -206,7 +206,7 @@ static int ptcache_softbody_write(int index, void *soft_v, void **data, int UNUS
return 1;
}
static void ptcache_softbody_read(
- int index, void *soft_v, void **data, float UNUSED(cfra), float *old_data)
+ int index, void *soft_v, void **data, float UNUSED(cfra), const float *old_data)
{
SoftBody *soft = soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -220,8 +220,13 @@ static void ptcache_softbody_read(
PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, bp->vec);
}
}
-static void ptcache_softbody_interpolate(
- int index, void *soft_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_softbody_interpolate(int index,
+ void *soft_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
SoftBody *soft = soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -316,7 +321,7 @@ static int ptcache_particle_write(int index, void *psys_v, void **data, int cfra
return 1 + (pa->state.time >= pa->time && pa->prev_state.time <= pa->time);
}
static void ptcache_particle_read(
- int index, void *psys_v, void **data, float cfra, float *old_data)
+ int index, void *psys_v, void **data, float cfra, const float *old_data)
{
ParticleSystem *psys = psys_v;
ParticleData *pa;
@@ -383,8 +388,13 @@ static void ptcache_particle_read(
unit_qt(pa->state.rot);
}
}
-static void ptcache_particle_interpolate(
- int index, void *psys_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_particle_interpolate(int index,
+ void *psys_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
ParticleSystem *psys = psys_v;
ParticleData *pa;
@@ -528,7 +538,7 @@ static int ptcache_cloth_write(int index, void *cloth_v, void **data, int UNUSED
return 1;
}
static void ptcache_cloth_read(
- int index, void *cloth_v, void **data, float UNUSED(cfra), float *old_data)
+ int index, void *cloth_v, void **data, float UNUSED(cfra), const float *old_data)
{
ClothModifierData *clmd = cloth_v;
Cloth *cloth = clmd->clothObject;
@@ -545,8 +555,13 @@ static void ptcache_cloth_read(
PTCACHE_DATA_TO(data, BPHYS_DATA_XCONST, 0, vert->xconst);
}
}
-static void ptcache_cloth_interpolate(
- int index, void *cloth_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_cloth_interpolate(int index,
+ void *cloth_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
ClothModifierData *clmd = cloth_v;
Cloth *cloth = clmd->clothObject;
@@ -1496,7 +1511,7 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUSE
if (ob && ob->rigidbody_object) {
RigidBodyOb *rbo = ob->rigidbody_object;
- if (rbo->type == RBO_TYPE_ACTIVE) {
+ if (rbo->type == RBO_TYPE_ACTIVE && rbo->shared->physics_object != NULL) {
#ifdef WITH_BULLET
RB_body_get_position(rbo->shared->physics_object, rbo->pos);
RB_body_get_orientation(rbo->shared->physics_object, rbo->orn);
@@ -1509,7 +1524,7 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUSE
return 1;
}
static void ptcache_rigidbody_read(
- int index, void *rb_v, void **data, float UNUSED(cfra), float *old_data)
+ int index, void *rb_v, void **data, float UNUSED(cfra), const float *old_data)
{
RigidBodyWorld *rbw = rb_v;
Object *ob = NULL;
@@ -1534,8 +1549,13 @@ static void ptcache_rigidbody_read(
}
}
}
-static void ptcache_rigidbody_interpolate(
- int index, void *rb_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
+static void ptcache_rigidbody_interpolate(int index,
+ void *rb_v,
+ void **data,
+ float cfra,
+ float cfra1,
+ float cfra2,
+ const float *old_data)
{
RigidBodyWorld *rbw = rb_v;
Object *ob = NULL;
@@ -1865,87 +1885,6 @@ void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *r
pid->file_type = PTCACHE_FILE_PTCACHE;
}
-static int ptcache_sim_particle_totpoint(void *state_v, int UNUSED(cfra))
-{
- ParticleSimulationState *state = (ParticleSimulationState *)state_v;
- return state->tot_particles;
-}
-
-static void ptcache_sim_particle_error(void *UNUSED(state_v), const char *UNUSED(message))
-{
-}
-
-static int ptcache_sim_particle_write(int index, void *state_v, void **data, int UNUSED(cfra))
-{
- ParticleSimulationState *state = (ParticleSimulationState *)state_v;
-
- const float *positions = (const float *)CustomData_get_layer_named(
- &state->attributes, CD_LOCATION, "Position");
-
- PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, positions + (index * 3));
-
- return 1;
-}
-static void ptcache_sim_particle_read(
- int index, void *state_v, void **data, float UNUSED(cfra), float *UNUSED(old_data))
-{
- ParticleSimulationState *state = (ParticleSimulationState *)state_v;
-
- BLI_assert(index < state->tot_particles);
- float *positions = (float *)CustomData_get_layer_named(
- &state->attributes, CD_LOCATION, "Position");
-
- PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, positions + (index * 3));
-}
-
-void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, ParticleSimulationState *state)
-{
- memset(pid, 0, sizeof(PTCacheID));
-
- ParticleSimulationState *state_orig;
- if (state->head.orig_state != NULL) {
- state_orig = (ParticleSimulationState *)state->head.orig_state;
- }
- else {
- state_orig = state;
- }
-
- pid->calldata = state;
- pid->type = PTCACHE_TYPE_SIM_PARTICLES;
- pid->cache = state_orig->point_cache;
- pid->cache_ptr = &state_orig->point_cache;
- pid->ptcaches = &state_orig->ptcaches;
- pid->totpoint = ptcache_sim_particle_totpoint;
- pid->totwrite = ptcache_sim_particle_totpoint;
- pid->error = ptcache_sim_particle_error;
-
- pid->write_point = ptcache_sim_particle_write;
- pid->read_point = ptcache_sim_particle_read;
- pid->interpolate_point = NULL;
-
- pid->write_stream = NULL;
- pid->read_stream = NULL;
-
- pid->write_openvdb_stream = NULL;
- pid->read_openvdb_stream = NULL;
-
- pid->write_extra_data = NULL;
- pid->read_extra_data = NULL;
- pid->interpolate_extra_data = NULL;
-
- pid->write_header = NULL;
- pid->read_header = NULL;
-
- pid->data_types = 1 << BPHYS_DATA_LOCATION;
- pid->info_types = 0;
-
- pid->stack_index = 0;
-
- pid->default_step = 1;
- pid->max_step = 1;
- pid->file_type = PTCACHE_FILE_PTCACHE;
-}
-
/**
* \param ob: Optional, may be NULL.
* \param scene: Optional may be NULL.
@@ -2045,21 +1984,7 @@ static bool foreach_object_modifier_ptcache(Object *object,
}
}
else if (md->type == eModifierType_Simulation) {
- SimulationModifierData *smd = (SimulationModifierData *)md;
- if (smd->simulation) {
- LISTBASE_FOREACH (SimulationState *, state, &smd->simulation->states) {
- switch ((eSimulationStateType)state->type) {
- case SIM_STATE_TYPE_PARTICLES: {
- ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
- BKE_ptcache_id_from_sim_particles(&pid, particle_state);
- if (!callback(&pid, callback_user_data)) {
- return false;
- }
- break;
- }
- }
- }
- }
+ /* TODO(jacques) */
}
}
return true;
@@ -2289,7 +2214,9 @@ static int ptcache_filename(PTCacheID *pid, char *filename, int cfra, short do_p
return len; /* make sure the above string is always 16 chars */
}
-/* youll need to close yourself after! */
+/**
+ * Caller must close after!
+ */
static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
{
PTCacheFile *pf;
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 4752782eaeb..7c335a8e98c 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -466,10 +466,10 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
return shape;
}
-/* Create new physics sim collision shape for object and store it,
- * or remove the existing one first and replace...
+/* Helper function to create physics collision shape for object.
+ * Returns a new collision shape.
*/
-static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
+static rbCollisionShape *rigidbody_validate_sim_shape_helper(RigidBodyWorld *rbw, Object *ob)
{
RigidBodyOb *rbo = ob->rigidbody_object;
rbCollisionShape *new_shape = NULL;
@@ -484,12 +484,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
/* sanity check */
if (rbo == NULL) {
- return;
- }
-
- /* don't create a new shape if we already have one and don't want to rebuild it */
- if (rbo->shared->physics_shape && !rebuild) {
- return;
+ return NULL;
}
/* if automatically determining dimensions, use the Object's boundbox
@@ -539,7 +534,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
break;
case RB_SHAPE_CONVEXH:
- /* try to emged collision margin */
+ /* try to embed collision margin */
has_volume = (MIN3(size[0], size[1], size[2]) > 0.0f);
if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && has_volume) {
@@ -555,18 +550,69 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
case RB_SHAPE_TRIMESH:
new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
break;
+ case RB_SHAPE_COMPOUND:
+ new_shape = RB_shape_new_compound();
+ rbCollisionShape *childShape = NULL;
+ float loc[3], rot[4];
+ float mat[4][4];
+ /* Add children to the compound shape */
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, childObject) {
+ if (childObject->parent == ob) {
+ childShape = rigidbody_validate_sim_shape_helper(rbw, childObject);
+ if (childShape) {
+ BKE_object_matrix_local_get(childObject, mat);
+ mat4_to_loc_quat(loc, rot, mat);
+ RB_compound_add_child_shape(new_shape, childShape, loc, rot);
+ }
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+
+ break;
}
- /* use box shape if we can't fall back to old shape */
- if (new_shape == NULL && rbo->shared->physics_shape == NULL) {
+ /* use box shape if it failed to create new shape */
+ if (new_shape == NULL) {
new_shape = RB_shape_new_box(size[0], size[1], size[2]);
}
+ if (new_shape) {
+ RB_shape_set_margin(new_shape, RBO_GET_MARGIN(rbo));
+ }
+
+ return new_shape;
+}
+
+/* Create new physics sim collision shape for object and store it,
+ * or remove the existing one first and replace...
+ */
+static void rigidbody_validate_sim_shape(RigidBodyWorld *rbw, Object *ob, bool rebuild)
+{
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ rbCollisionShape *new_shape = NULL;
+
+ /* sanity check */
+ if (rbo == NULL) {
+ return;
+ }
+
+ /* don't create a new shape if we already have one and don't want to rebuild it */
+ if (rbo->shared->physics_shape && !rebuild) {
+ return;
+ }
+
+ /* Also don't create a shape if this object is parent of a compound shape */
+ if (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) {
+ return;
+ }
+
+ new_shape = rigidbody_validate_sim_shape_helper(rbw, ob);
+
/* assign new collision shape if creation was successful */
if (new_shape) {
if (rbo->shared->physics_shape) {
RB_shape_delete(rbo->shared->physics_shape);
}
rbo->shared->physics_shape = new_shape;
- RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo));
}
}
@@ -750,7 +796,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects,
* but it's needed for constraints to update correctly. */
if (rbo->shared->physics_shape == NULL || rebuild) {
- rigidbody_validate_sim_shape(ob, true);
+ rigidbody_validate_sim_shape(rbw, ob, true);
}
if (rbo->shared->physics_object) {
@@ -760,6 +806,12 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* remove rigid body if it already exists before creating a new one */
if (rbo->shared->physics_object) {
RB_body_delete(rbo->shared->physics_object);
+ rbo->shared->physics_object = NULL;
+ }
+ /* Don't create rigid body object if the parent is a compound shape */
+ if (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) {
+ return;
}
mat4_to_loc_quat(loc, rot, ob->obmat);
@@ -793,7 +845,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
}
- if (rbw && rbw->shared->physics_world) {
+ if (rbw && rbw->shared->physics_world && rbo->shared->physics_object) {
RB_dworld_add_body(rbw->shared->physics_world, rbo->shared->physics_object, rbo->col_groups);
}
}
@@ -1179,9 +1231,12 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
* - object must exist
* - cannot add rigid body if it already exists
*/
- if (ob == NULL || (ob->rigidbody_object != NULL)) {
+ if (ob == NULL) {
return NULL;
}
+ if (ob->rigidbody_object != NULL) {
+ return ob->rigidbody_object;
+ }
/* create new settings data, and link it up */
rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb");
@@ -1530,7 +1585,11 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
int n = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
(void)object;
- n++;
+ /* Ignore if this object is the direct child of an object with a compound shape */
+ if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
+ object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) {
+ n++;
+ }
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
@@ -1541,8 +1600,12 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
int i = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
- rbw->objects[i] = object;
- i++;
+ /* Ignore if this object is the direct child of an object with a compound shape */
+ if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
+ object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) {
+ rbw->objects[i] = object;
+ i++;
+ }
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
@@ -1754,11 +1817,13 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph,
/* refresh shape... */
if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) {
/* mesh/shape data changed, so force shape refresh */
- rigidbody_validate_sim_shape(ob, true);
+ rigidbody_validate_sim_shape(rbw, ob, true);
/* now tell RB sim about it */
/* XXX: we assume that this can only get applied for active/passive shapes
* that will be included as rigidbodies. */
- RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape);
+ if (rbo->shared->physics_object != NULL && rbo->shared->physics_shape != NULL) {
+ RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape);
+ }
}
}
rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
@@ -1817,7 +1882,8 @@ static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBod
Base *base = BKE_view_layer_base_find(view_layer, ob);
RigidBodyOb *rbo = ob->rigidbody_object;
/* Reset kinematic state for transformed objects. */
- if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
+ if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ) &&
+ rbo->shared->physics_object) {
RB_body_set_kinematic_state(rbo->shared->physics_object,
rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo));
@@ -1840,8 +1906,13 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
{
RigidBodyOb *rbo = ob->rigidbody_object;
+ /* True if the shape of this object's parent is of type compound */
+ bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND);
+
/* keep original transform for kinematic and passive objects */
- if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE) {
+ if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE ||
+ obCompoundParent) {
return;
}
@@ -1963,7 +2034,11 @@ void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime
int n = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
(void)object;
- n++;
+ /* Ignore if this object is the direct child of an object with a compound shape */
+ if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
+ object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) {
+ n++;
+ }
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index b0faa555f29..fdec29dd43e 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -127,7 +127,7 @@ static void scene_init_data(ID *id)
mblur_shutter_curve = &scene->r.mblur_shutter_curve;
BKE_curvemapping_set_defaults(mblur_shutter_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(mblur_shutter_curve);
+ BKE_curvemapping_init(mblur_shutter_curve);
BKE_curvemap_reset(mblur_shutter_curve->cm,
&mblur_shutter_curve->clipr,
CURVE_PRESET_MAX,
@@ -140,13 +140,13 @@ static void scene_init_data(ID *id)
/* grease pencil multiframe falloff curve */
scene->toolsettings->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_falloff_curve = scene->toolsettings->gp_sculpt.cur_falloff;
- BKE_curvemapping_initialize(gp_falloff_curve);
+ BKE_curvemapping_init(gp_falloff_curve);
BKE_curvemap_reset(
gp_falloff_curve->cm, &gp_falloff_curve->clipr, CURVE_PRESET_GAUSS, CURVEMAP_SLOPE_POSITIVE);
scene->toolsettings->gp_sculpt.cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_primitive_curve = scene->toolsettings->gp_sculpt.cur_primitive;
- BKE_curvemapping_initialize(gp_primitive_curve);
+ BKE_curvemapping_init(gp_primitive_curve);
BKE_curvemap_reset(gp_primitive_curve->cm,
&gp_primitive_curve->clipr,
CURVE_PRESET_BELL,
@@ -570,6 +570,24 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void scene_foreach_cache(ID *id,
+ IDTypeForeachCacheFunctionCallback function_callback,
+ void *user_data)
+{
+ Scene *scene = (Scene *)id;
+ IDCacheKey key = {
+ .id_session_uuid = id->session_uuid,
+ .offset_in_ID = offsetof(Scene, eevee.light_cache_data),
+ .cache_v = scene->eevee.light_cache_data,
+ };
+
+ function_callback(id,
+ &key,
+ (void **)&scene->eevee.light_cache_data,
+ IDTYPE_CACHE_CB_FLAGS_PERSISTENT,
+ user_data);
+}
+
IDTypeInfo IDType_ID_SCE = {
.id_code = ID_SCE,
.id_filter = FILTER_ID_SCE,
@@ -587,6 +605,7 @@ IDTypeInfo IDType_ID_SCE = {
* support all possible corner cases. */
.make_local = NULL,
.foreach_id = scene_foreach_id,
+ .foreach_cache = scene_foreach_cache,
};
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
@@ -751,7 +770,6 @@ void BKE_scene_copy_data_eevee(Scene *sce_dst, const Scene *sce_src)
Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
{
- const bool is_scene_liboverride = ID_IS_OVERRIDE_LIBRARY(sce);
Scene *sce_copy;
/* TODO this should/could most likely be replaced by call to more generic code at some point...
@@ -822,15 +840,13 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
return sce_copy;
}
else {
- const eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT;
+ eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT;
BKE_id_copy(bmain, (ID *)sce, (ID **)&sce_copy);
id_us_min(&sce_copy->id);
id_us_ensure_real(&sce_copy->id);
- if (duplicate_flags & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(bmain, &sce_copy->id, true);
- }
+ BKE_animdata_duplicate_id_action(bmain, &sce_copy->id, duplicate_flags);
/* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks. */
@@ -841,22 +857,26 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
if (!is_subprocess) {
BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
BKE_main_id_clear_newpoins(bmain);
+ /* In case root duplicated ID is linked, assume we want to get a local copy of it and
+ * duplicate all expected linked data. */
+ if (ID_IS_LINKED(sce)) {
+ duplicate_flags |= USER_DUP_LINKED_ID;
+ }
}
/* Copy Freestyle LineStyle datablocks. */
LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) {
LISTBASE_FOREACH (
FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) {
- BKE_id_copy_for_duplicate(
- bmain, &lineset->linestyle->id, is_scene_liboverride, duplicate_flags);
+ BKE_id_copy_for_duplicate(bmain, (ID *)lineset->linestyle, duplicate_flags);
}
}
/* Full copy of world (included animations) */
- BKE_id_copy_for_duplicate(bmain, &sce->world->id, is_scene_liboverride, duplicate_flags);
+ BKE_id_copy_for_duplicate(bmain, (ID *)sce->world, duplicate_flags);
/* Full copy of GreasePencil. */
- BKE_id_copy_for_duplicate(bmain, &sce->gpd->id, is_scene_liboverride, duplicate_flags);
+ BKE_id_copy_for_duplicate(bmain, (ID *)sce->gpd, duplicate_flags);
/* Deep-duplicate collections and objects (using preferences' settings for which sub-data to
* duplicate along the object itself). */
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index de233a8d473..4a2ad88bb28 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2668,7 +2668,7 @@ static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int heig
}
static void RVIsolateHighlights_float(
- float *in, float *out, int width, int height, float threshold, float boost, float clamp)
+ const float *in, float *out, int width, int height, float threshold, float boost, float clamp)
{
int x, y, index;
float intensity;
@@ -3423,7 +3423,7 @@ static void do_gaussian_blur_effect_byte_x(Sequence *seq,
int y,
int frame_width,
int UNUSED(frame_height),
- unsigned char *rect,
+ const unsigned char *rect,
unsigned char *out)
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
@@ -3473,7 +3473,7 @@ static void do_gaussian_blur_effect_byte_y(Sequence *seq,
int y,
int UNUSED(frame_width),
int frame_height,
- unsigned char *rect,
+ const unsigned char *rect,
unsigned char *out)
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 604cbf476a8..0bf7fffb833 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -57,7 +57,7 @@ typedef void (*modifier_apply_threaded_cb)(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v);
typedef struct ModifierInitData {
@@ -223,7 +223,7 @@ static void whiteBalance_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
int x, y;
@@ -331,7 +331,7 @@ static void curves_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *)data_v;
@@ -396,7 +396,7 @@ static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *m
float black[3] = {0.0f, 0.0f, 0.0f};
float white[3] = {1.0f, 1.0f, 1.0f};
- BKE_curvemapping_initialize(&cmd->curve_mapping);
+ BKE_curvemapping_init(&cmd->curve_mapping);
BKE_curvemapping_premultiply(&cmd->curve_mapping, 0);
BKE_curvemapping_set_black_white(&cmd->curve_mapping, black, white);
@@ -461,7 +461,7 @@ static void hue_correct_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *)data_v;
@@ -525,7 +525,7 @@ static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImB
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
- BKE_curvemapping_initialize(&hcmd->curve_mapping);
+ BKE_curvemapping_init(&hcmd->curve_mapping);
modifier_apply_threaded(ibuf, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
}
@@ -556,7 +556,7 @@ static void brightcontrast_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
BrightContrastThreadData *data = (BrightContrastThreadData *)data_v;
@@ -658,7 +658,7 @@ static void maskmodifier_apply_threaded(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *UNUSED(data_v))
{
int x, y;
@@ -755,7 +755,7 @@ static void tonemapmodifier_apply_threaded_simple(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
AvgLogLum *avg = (AvgLogLum *)data_v;
@@ -814,7 +814,7 @@ static void tonemapmodifier_apply_threaded_photoreceptor(int width,
unsigned char *rect,
float *rect_float,
unsigned char *mask_rect,
- float *mask_rect_float,
+ const float *mask_rect_float,
void *data_v)
{
AvgLogLum *avg = (AvgLogLum *)data_v;
diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c
index 30a371b5b28..ff3829bdebb 100644
--- a/source/blender/blenkernel/intern/seqprefetch.c
+++ b/source/blender/blenkernel/intern/seqprefetch.c
@@ -183,6 +183,10 @@ static float seq_prefetch_cfra(PrefetchJob *pfjob)
{
return pfjob->cfra + pfjob->num_frames_prefetched;
}
+static AnimationEvalContext seq_prefetch_anim_eval_context(PrefetchJob *pfjob)
+{
+ return BKE_animsys_eval_context_construct(pfjob->depsgraph, seq_prefetch_cfra(pfjob));
+}
void BKE_sequencer_prefetch_get_time_range(Scene *scene, int *start, int *end)
{
@@ -435,8 +439,9 @@ static void *seq_prefetch_frames(void *job)
seq_prefetch_update_depsgraph(pfjob);
AnimData *adt = BKE_animdata_from_id(&pfjob->context_cpy.scene->id);
+ AnimationEvalContext anim_eval_context = seq_prefetch_anim_eval_context(pfjob);
BKE_animsys_evaluate_animdata(
- &pfjob->context_cpy.scene->id, adt, seq_prefetch_cfra(pfjob), ADT_RECALC_ALL, false);
+ &pfjob->context_cpy.scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false);
/* This is quite hacky solution:
* We need cross-reference original scene with copy for cache.
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 297d60e5976..b0a8f709399 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -46,6 +46,7 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_path_util.h"
+#include "BLI_session_uuid.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_threads.h"
@@ -114,8 +115,7 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
float cfra,
clock_t begin,
bool use_preprocess,
- const bool is_proxy_image,
- const bool is_preprocessed);
+ const bool is_proxy_image);
static ImBuf *seq_render_strip(const SeqRenderData *context,
SeqRenderState *state,
Sequence *seq,
@@ -1091,6 +1091,64 @@ void BKE_sequence_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, cons
BKE_sequence_calc(scene, seq);
}
+void BKE_sequence_movie_reload_if_needed(struct Main *bmain,
+ struct Scene *scene,
+ struct Sequence *seq,
+ bool *r_was_reloaded,
+ bool *r_can_produce_frames)
+{
+ BLI_assert(seq->type == SEQ_TYPE_MOVIE ||
+ !"This function is only implemented for movie strips.");
+
+ bool must_reload = false;
+
+ /* The Sequence struct allows for multiple anim structs to be associated with one strip. This
+ * function will return true only if there is at least one 'anim' AND all anims can produce
+ * frames. */
+
+ if (BLI_listbase_is_empty(&seq->anims)) {
+ /* No anim present, so reloading is always necessary. */
+ must_reload = true;
+ }
+ else {
+ LISTBASE_FOREACH (StripAnim *, sanim, &seq->anims) {
+ if (!IMB_anim_can_produce_frames(sanim->anim)) {
+ /* Anim cannot produce frames, try reloading. */
+ must_reload = true;
+ break;
+ }
+ };
+ }
+
+ if (!must_reload) {
+ /* There are one or more anims, and all can produce frames. */
+ *r_was_reloaded = false;
+ *r_can_produce_frames = true;
+ return;
+ }
+
+ BKE_sequence_reload_new_file(bmain, scene, seq, true);
+ *r_was_reloaded = true;
+
+ if (BLI_listbase_is_empty(&seq->anims)) {
+ /* No anims present after reloading => no frames can be produced. */
+ *r_can_produce_frames = false;
+ return;
+ }
+
+ /* Check if there are still anims that cannot produce frames. */
+ LISTBASE_FOREACH (StripAnim *, sanim, &seq->anims) {
+ if (!IMB_anim_can_produce_frames(sanim->anim)) {
+ /* There still is an anim that cannot produce frames. */
+ *r_can_produce_frames = false;
+ return;
+ }
+ };
+
+ /* There are one or more anims, and all can produce frames. */
+ *r_can_produce_frames = true;
+}
+
void BKE_sequencer_sort(Scene *scene)
{
/* all strips together per kind, and in order of y location ("machine") */
@@ -1332,30 +1390,6 @@ ListBase *BKE_sequence_seqbase_get(Sequence *seq, int *r_offset)
/*********************** DO THE SEQUENCE *************************/
-static void make_black_ibuf(ImBuf *ibuf)
-{
- unsigned int *rect;
- float *rect_float;
- int tot;
-
- if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) {
- return;
- }
-
- tot = ibuf->x * ibuf->y;
-
- rect = ibuf->rect;
- rect_float = ibuf->rect_float;
-
- if (rect) {
- memset(rect, 0, tot * sizeof(char) * 4);
- }
-
- if (rect_float) {
- memset(rect_float, 0, tot * sizeof(float) * 4);
- }
-}
-
static void multibuf(ImBuf *ibuf, const float fmul)
{
char *rt;
@@ -2415,7 +2449,7 @@ static void color_balance_byte_float(StripColorBalance *cb_,
static void color_balance_float_float(StripColorBalance *cb_,
float *rect_float,
- float *mask_rect_float,
+ const float *mask_rect_float,
int width,
int height,
float mul)
@@ -2657,8 +2691,7 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
Sequence *seq,
float cfra,
ImBuf *ibuf,
- const bool is_proxy_image,
- const bool is_preprocessed)
+ const bool is_proxy_image)
{
Scene *scene = context->scene;
float mul;
@@ -2672,15 +2705,6 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
if (seq->flag & (SEQ_USE_CROP | SEQ_USE_TRANSFORM)) {
StripCrop c = {0};
StripTransform t = {0};
- int sx, sy, dx, dy;
-
- if (is_proxy_image) {
- double f = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
-
- if (f != 1.0) {
- IMB_scalefastImBuf(ibuf, ibuf->x * f, ibuf->y * f);
- }
- }
if (seq->flag & SEQ_USE_CROP && seq->strip->crop) {
c = *seq->strip->crop;
@@ -2689,33 +2713,41 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
t = *seq->strip->transform;
}
- if (is_preprocessed) {
- double xscale = scene->r.xsch ? ((double)context->rectx / (double)scene->r.xsch) : 1.0;
- double yscale = scene->r.ysch ? ((double)context->recty / (double)scene->r.ysch) : 1.0;
- if (seq->flag & SEQ_USE_TRANSFORM) {
- t.xofs *= xscale;
- t.yofs *= yscale;
+ /* Calculate scale factor for current image if needed. */
+ double scale_factor, image_scale_factor = 1.0;
+ if (context->preview_render_size == SEQ_PROXY_RENDER_SIZE_SCENE) {
+ scale_factor = image_scale_factor = (double)scene->r.size / 100;
+ }
+ else {
+ scale_factor = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
+ if (!is_proxy_image) {
+ image_scale_factor = scale_factor;
}
- if (seq->flag & SEQ_USE_CROP) {
- c.left *= xscale;
- c.right *= xscale;
- c.top *= yscale;
- c.bottom *= yscale;
+ }
+
+ if (image_scale_factor != 1.0) {
+ if (context->for_render) {
+ IMB_scaleImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
+ }
+ else {
+ IMB_scalefastImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
}
}
+ t.xofs *= scale_factor;
+ t.yofs *= scale_factor;
+ c.left *= scale_factor;
+ c.right *= scale_factor;
+ c.top *= scale_factor;
+ c.bottom *= scale_factor;
+
+ int sx, sy, dx, dy;
sx = ibuf->x - c.left - c.right;
sy = ibuf->y - c.top - c.bottom;
if (seq->flag & SEQ_USE_TRANSFORM) {
- if (is_preprocessed) {
- dx = context->rectx;
- dy = context->recty;
- }
- else {
- dx = scene->r.xsch;
- dy = scene->r.ysch;
- }
+ dx = context->rectx;
+ dy = context->recty;
}
else {
dx = sx;
@@ -2724,19 +2756,15 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x || t.xofs >= dx ||
t.yofs >= dy) {
- make_black_ibuf(ibuf);
+ return NULL;
}
- else {
- ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
-
- IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
- sequencer_imbuf_assign_spaces(scene, i);
-
- IMB_metadata_copy(i, ibuf);
- IMB_freeImBuf(ibuf);
- ibuf = i;
- }
+ ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
+ IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
+ sequencer_imbuf_assign_spaces(scene, i);
+ IMB_metadata_copy(i, ibuf);
+ IMB_freeImBuf(ibuf);
+ ibuf = i;
}
if (seq->flag & SEQ_FLIPX) {
@@ -3097,7 +3125,7 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context,
if (view_id != context->view_id) {
ibufs_arr[view_id] = seq_render_preprocess_ibuf(
- &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false, false);
+ &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false);
}
}
@@ -3214,7 +3242,7 @@ static ImBuf *seq_render_movie_strip(
if (view_id != context->view_id) {
ibuf_arr[view_id] = seq_render_preprocess_ibuf(
- &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false, false);
+ &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false);
}
}
@@ -3334,7 +3362,9 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr
/* anim-data */
adt = BKE_animdata_from_id(&mask->id);
- BKE_animsys_evaluate_animdata(&mask_temp->id, adt, mask->sfra + nr, ADT_RECALC_ANIM, false);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ context->depsgraph, mask->sfra + nr);
+ BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false);
maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__);
@@ -3804,8 +3834,7 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
float cfra,
clock_t begin,
bool use_preprocess,
- const bool is_proxy_image,
- const bool is_preprocessed)
+ const bool is_proxy_image)
{
if (context->is_proxy_render == false &&
(ibuf->x != context->rectx || ibuf->y != context->recty)) {
@@ -3814,11 +3843,17 @@ static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
if (use_preprocess) {
float cost = seq_estimate_render_cost_end(context->scene, begin);
- BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false);
+
+ /* TODO (Richard): It should be possible to store in cache if image is proxy,
+ * but it adds quite a bit of complexity. Since proxies are fast to read, I would
+ * rather simplify existing code a bit. */
+ if (!is_proxy_image) {
+ BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false);
+ }
/* Reset timer so we can get partial render time. */
begin = seq_estimate_render_cost_begin();
- ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed);
+ ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image);
}
float cost = seq_estimate_render_cost_end(context->scene, begin);
@@ -3834,11 +3869,6 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
ImBuf *ibuf = NULL;
bool use_preprocess = false;
bool is_proxy_image = false;
- /* all effects are handled similarly with the exception of speed effect */
- int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT :
- seq->type;
- bool is_preprocessed = !ELEM(
- type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP);
clock_t begin = seq_estimate_render_cost_begin();
@@ -3855,7 +3885,7 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
if (ibuf) {
use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
ibuf = seq_render_preprocess_ibuf(
- context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image, is_preprocessed);
+ context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image);
}
if (ibuf == NULL) {
@@ -4272,6 +4302,10 @@ void BKE_sequence_invalidate_movieclip_strips(Main *bmain, MovieClip *clip_targe
void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
{
+ if (scene->ed == NULL) {
+ return;
+ }
+
Sequence *seq;
BKE_sequencer_cache_cleanup(scene);
@@ -5319,9 +5353,16 @@ Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine, int type)
seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Sequence Stereo Format");
seq->cache_flag = SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED | SEQ_CACHE_STORE_COMPOSITE;
+ BKE_sequence_session_uuid_generate(seq);
+
return seq;
}
+void BKE_sequence_session_uuid_generate(struct Sequence *sequence)
+{
+ sequence->runtime.session_uuid = BLI_session_uuid_generate();
+}
+
void BKE_sequence_alpha_mode_from_extension(Sequence *seq)
{
if (seq->strip && seq->strip->stripdata) {
@@ -5551,6 +5592,9 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
}
}
+ if (seq_load->flag & SEQ_LOAD_MOVIE_SOUND) {
+ seq_load->channel++;
+ }
seq = BKE_sequence_alloc(seqbasep, seq_load->start_frame, seq_load->channel, SEQ_TYPE_MOVIE);
/* multiview settings */
@@ -5607,11 +5651,8 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
if (seq_load->flag & SEQ_LOAD_MOVIE_SOUND) {
int start_frame_back = seq_load->start_frame;
seq_load->channel--;
-
seq_load->seq_sound = BKE_sequencer_add_sound_strip(C, seqbasep, seq_load);
-
seq_load->start_frame = start_frame_back;
- seq_load->channel++;
}
/* can be NULL */
@@ -5631,6 +5672,10 @@ static Sequence *seq_dupli(const Scene *scene_src,
{
Sequence *seqn = MEM_dupallocN(seq);
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ BKE_sequence_session_uuid_generate(seq);
+ }
+
seq->tmp = seqn;
seqn->strip = MEM_dupallocN(seq->strip);
@@ -5698,7 +5743,7 @@ static Sequence *seq_dupli(const Scene *scene_src,
struct SeqEffectHandle sh;
sh = BKE_sequence_get_effect(seq);
if (sh.copy) {
- sh.copy(seq, seqn, flag);
+ sh.copy(seqn, seq, flag);
}
seqn->strip->stripdata = NULL;
@@ -6013,3 +6058,113 @@ bool BKE_sequencer_check_scene_recursion(Scene *scene, ReportList *reports)
return false;
}
+
+/* Check if "seq_main" (indirectly) uses strip "seq". */
+bool BKE_sequencer_render_loop_check(Sequence *seq_main, Sequence *seq)
+{
+ if (seq_main == seq) {
+ return true;
+ }
+
+ if ((seq_main->seq1 && BKE_sequencer_render_loop_check(seq_main->seq1, seq)) ||
+ (seq_main->seq2 && BKE_sequencer_render_loop_check(seq_main->seq2, seq)) ||
+ (seq_main->seq3 && BKE_sequencer_render_loop_check(seq_main->seq3, seq))) {
+ return true;
+ }
+
+ SequenceModifierData *smd;
+ for (smd = seq_main->modifiers.first; smd; smd = smd->next) {
+ if (smd->mask_sequence && BKE_sequencer_render_loop_check(smd->mask_sequence, seq)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void sequencer_flag_users_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
+{
+ LISTBASE_FOREACH (Sequence *, user_seq, seqbase) {
+ /* Look in metas for usage of seq. */
+ if (user_seq->type == SEQ_TYPE_META) {
+ sequencer_flag_users_for_removal(scene, &user_seq->seqbase, seq);
+ }
+
+ /* Clear seq from modifiers. */
+ SequenceModifierData *smd;
+ for (smd = user_seq->modifiers.first; smd; smd = smd->next) {
+ if (smd->mask_sequence == seq) {
+ smd->mask_sequence = NULL;
+ }
+ }
+
+ /* Remove effects, that use seq. */
+ if ((user_seq->seq1 && user_seq->seq1 == seq) || (user_seq->seq2 && user_seq->seq2 == seq) ||
+ (user_seq->seq3 && user_seq->seq3 == seq)) {
+ user_seq->flag |= SEQ_FLAG_DELETE;
+ /* Strips can be used as mask even if not in same seqbase. */
+ sequencer_flag_users_for_removal(scene, &scene->ed->seqbase, user_seq);
+ }
+ }
+}
+
+/* Flag seq and its users (effects) for removal. */
+void BKE_sequencer_flag_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
+{
+ if (seq == NULL || (seq->flag & SEQ_FLAG_DELETE) != 0) {
+ return;
+ }
+
+ /* Flag and remove meta children. */
+ if (seq->type == SEQ_TYPE_META) {
+ LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) {
+ BKE_sequencer_flag_for_removal(scene, &seq->seqbase, meta_child);
+ }
+ }
+
+ seq->flag |= SEQ_FLAG_DELETE;
+ sequencer_flag_users_for_removal(scene, seqbase, seq);
+}
+
+/* Remove all flagged sequences, return true if sequence is removed. */
+void BKE_sequencer_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
+{
+ LISTBASE_FOREACH_MUTABLE (Sequence *, seq, seqbase) {
+ if (seq->flag & SEQ_FLAG_DELETE) {
+ if (seq->type == SEQ_TYPE_META) {
+ BKE_sequencer_remove_flagged_sequences(scene, &seq->seqbase);
+ }
+ BLI_remlink(seqbase, seq);
+ BKE_sequence_free(scene, seq, true);
+ }
+ }
+}
+
+void BKE_sequencer_check_uuids_unique_and_report(const Scene *scene)
+{
+ if (scene->ed == NULL) {
+ return;
+ }
+
+ struct GSet *used_uuids = BLI_gset_new(
+ BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids");
+
+ const Sequence *sequence;
+ SEQ_BEGIN (scene->ed, sequence) {
+ const SessionUUID *session_uuid = &sequence->runtime.session_uuid;
+ if (!BLI_session_uuid_is_generated(session_uuid)) {
+ printf("Sequence %s does not have UUID generated.\n", sequence->name);
+ continue;
+ }
+
+ if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
+ printf("Sequence %s has duplicate UUID generated.\n", sequence->name);
+ continue;
+ }
+
+ BLI_gset_insert(used_uuids, (void *)session_uuid);
+ }
+ SEQ_END;
+
+ BLI_gset_free(used_uuids, NULL);
+}
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index c4a35141b0d..c0fc8fcb464 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -31,6 +31,7 @@
#include "BLI_float3.hh"
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_rand.h"
#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -47,13 +48,37 @@
#include "BKE_pointcache.h"
#include "BKE_simulation.h"
+#include "NOD_node_tree_multi_function.hh"
#include "NOD_simulation.h"
+#include "BLI_map.hh"
#include "BLT_translation.h"
+#include "FN_attributes_ref.hh"
+#include "FN_multi_function_network_evaluation.hh"
+#include "FN_multi_function_network_optimization.hh"
+
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "SIM_simulation_update.hh"
+
+using StateInitFunction = void (*)(SimulationState *state);
+using StateResetFunction = void (*)(SimulationState *state);
+using StateRemoveFunction = void (*)(SimulationState *state);
+using StateCopyFunction = void (*)(const SimulationState *src, SimulationState *dst);
+
+struct SimulationStateType {
+ const char *name;
+ int size;
+ StateInitFunction init;
+ StateResetFunction reset;
+ StateRemoveFunction remove;
+ StateCopyFunction copy;
+};
+
+static const SimulationStateType *try_get_state_type(blender::StringRefNull type_name);
+
static void simulation_init_data(ID *id)
{
Simulation *simulation = (Simulation *)id;
@@ -63,20 +88,12 @@ static void simulation_init_data(ID *id)
bNodeTree *ntree = ntreeAddTree(nullptr, "Simulation Nodetree", ntreeType_Simulation->idname);
simulation->nodetree = ntree;
-
- /* Add a default particle simulation state for now. */
- ParticleSimulationState *state = (ParticleSimulationState *)MEM_callocN(
- sizeof(ParticleSimulationState), __func__);
- CustomData_reset(&state->attributes);
-
- state->point_cache = BKE_ptcache_add(&state->ptcaches);
- BLI_addtail(&simulation->states, state);
}
static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
{
Simulation *simulation_dst = (Simulation *)id_dst;
- Simulation *simulation_src = (Simulation *)id_src;
+ const Simulation *simulation_src = (const Simulation *)id_src;
/* We always need allocation of our private ID data. */
const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
@@ -89,19 +106,14 @@ static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
}
BLI_listbase_clear(&simulation_dst->states);
-
LISTBASE_FOREACH (const SimulationState *, state_src, &simulation_src->states) {
- switch ((eSimulationStateType)state_src->type) {
- case SIM_STATE_TYPE_PARTICLES: {
- ParticleSimulationState *particle_state_dst = (ParticleSimulationState *)MEM_callocN(
- sizeof(ParticleSimulationState), __func__);
- CustomData_reset(&particle_state_dst->attributes);
-
- BLI_addtail(&simulation_dst->states, particle_state_dst);
- break;
- }
- }
+ SimulationState *state_dst = BKE_simulation_state_add(
+ simulation_dst, state_src->type, state_src->name);
+ BKE_simulation_state_copy_data(state_src, state_dst);
}
+
+ BLI_listbase_clear(&simulation_dst->dependencies);
+ BLI_duplicatelist(&simulation_dst->dependencies, &simulation_src->dependencies);
}
static void simulation_free_data(ID *id)
@@ -116,17 +128,9 @@ static void simulation_free_data(ID *id)
simulation->nodetree = nullptr;
}
- LISTBASE_FOREACH_MUTABLE (SimulationState *, state, &simulation->states) {
- switch ((eSimulationStateType)state->type) {
- case SIM_STATE_TYPE_PARTICLES: {
- ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
- CustomData_free(&particle_state->attributes, particle_state->tot_particles);
- BKE_ptcache_free_list(&particle_state->ptcaches);
- break;
- }
- }
- MEM_freeN(state);
- }
+ BKE_simulation_state_remove_all(simulation);
+
+ BLI_freelistN(&simulation->dependencies);
}
static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -136,6 +140,9 @@ static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
BKE_library_foreach_ID_embedded(data, (ID **)&simulation->nodetree);
}
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ BKE_LIB_FOREACHID_PROCESS_ID(data, dependency->id, IDWALK_CB_USER);
+ }
}
IDTypeInfo IDType_ID_SIM = {
@@ -164,103 +171,203 @@ void *BKE_simulation_add(Main *bmain, const char *name)
return simulation;
}
-namespace blender::bke {
+SimulationState *BKE_simulation_state_add(Simulation *simulation,
+ const char *type,
+ const char *name)
+{
+ BLI_assert(simulation != nullptr);
+ BLI_assert(name != nullptr);
+
+ const SimulationStateType *state_type = try_get_state_type(type);
+ BLI_assert(state_type != nullptr);
+
+ SimulationState *state = (SimulationState *)MEM_callocN(state_type->size, AT);
+ state->type = BLI_strdup(type);
+ state->name = BLI_strdup(name);
+
+ state_type->init(state);
+ BLI_addtail(&simulation->states, state);
+ return state;
+}
-static MutableSpan<float3> get_particle_positions(ParticleSimulationState *state)
+void BKE_simulation_state_remove(Simulation *simulation, SimulationState *state)
{
- return MutableSpan<float3>(
- (float3 *)CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position"),
- state->tot_particles);
+ BLI_assert(simulation != nullptr);
+ BLI_assert(state != nullptr);
+ BLI_assert(BLI_findindex(&simulation->states, state) >= 0);
+
+ BLI_remlink(&simulation->states, state);
+ const SimulationStateType *state_type = try_get_state_type(state->type);
+ BLI_assert(state_type != nullptr);
+ state_type->remove(state);
+ MEM_freeN(state->name);
+ MEM_freeN(state->type);
+ MEM_freeN(state);
}
-static void ensure_attributes_exist(ParticleSimulationState *state)
+void BKE_simulation_state_remove_all(Simulation *simulation)
{
- if (CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position") == nullptr) {
- CustomData_add_layer_named(
- &state->attributes, CD_LOCATION, CD_CALLOC, nullptr, state->tot_particles, "Position");
+ BLI_assert(simulation != nullptr);
+
+ while (!BLI_listbase_is_empty(&simulation->states)) {
+ BKE_simulation_state_remove(simulation, (SimulationState *)simulation->states.first);
}
}
-static void copy_particle_state_to_cow(ParticleSimulationState *state_orig,
- ParticleSimulationState *state_cow)
+void BKE_simulation_state_reset(Simulation *UNUSED(simulation), SimulationState *state)
{
- ensure_attributes_exist(state_cow);
- CustomData_free(&state_cow->attributes, state_cow->tot_particles);
- CustomData_copy(&state_orig->attributes,
- &state_cow->attributes,
- CD_MASK_ALL,
- CD_DUPLICATE,
- state_orig->tot_particles);
- state_cow->current_frame = state_orig->current_frame;
- state_cow->tot_particles = state_orig->tot_particles;
+ BLI_assert(state != nullptr);
+
+ const SimulationStateType *state_type = try_get_state_type(state->type);
+ BLI_assert(state_type != nullptr);
+ state_type->reset(state);
}
-static void simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation)
+void BKE_simulation_state_reset_all(Simulation *simulation)
{
- int current_frame = scene->r.cfra;
+ BLI_assert(simulation != nullptr);
- ParticleSimulationState *state_cow = (ParticleSimulationState *)simulation->states.first;
- ParticleSimulationState *state_orig = (ParticleSimulationState *)state_cow->head.orig_state;
-
- if (current_frame == state_cow->current_frame) {
- return;
+ LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
+ BKE_simulation_state_reset(simulation, state);
}
+}
- /* Number of particles should be stored in the cache, but for now assume it is constant. */
- state_cow->tot_particles = state_orig->tot_particles;
- CustomData_realloc(&state_cow->attributes, state_orig->tot_particles);
- ensure_attributes_exist(state_cow);
+void BKE_simulation_state_copy_data(const SimulationState *src_state, SimulationState *dst_state)
+{
+ BLI_assert(src_state != nullptr);
+ BLI_assert(dst_state != nullptr);
+ BLI_assert(STREQ(src_state->type, dst_state->type));
- PTCacheID pid_cow;
- BKE_ptcache_id_from_sim_particles(&pid_cow, state_cow);
- BKE_ptcache_id_time(&pid_cow, scene, current_frame, nullptr, nullptr, nullptr);
+ const SimulationStateType *state_type = try_get_state_type(src_state->type);
+ BLI_assert(state_type != nullptr);
+ state_type->copy(src_state, dst_state);
+}
- /* If successfull, this will read the state directly into the cow state. */
- int cache_result = BKE_ptcache_read(&pid_cow, current_frame, true);
- if (cache_result == PTCACHE_READ_EXACT) {
- state_cow->current_frame = current_frame;
- return;
+SimulationState *BKE_simulation_state_try_find_by_name(Simulation *simulation, const char *name)
+{
+ if (simulation == nullptr) {
+ return nullptr;
+ }
+ if (name == nullptr) {
+ return nullptr;
}
- /* Below we modify the original state/cache. Only the active depsgraph is allowed to do that. */
- if (!DEG_is_active(depsgraph)) {
- return;
+ LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
+ if (STREQ(state->name, name)) {
+ return state;
+ }
}
+ return nullptr;
+}
- PTCacheID pid_orig;
- BKE_ptcache_id_from_sim_particles(&pid_orig, state_orig);
- BKE_ptcache_id_time(&pid_orig, scene, current_frame, nullptr, nullptr, nullptr);
+SimulationState *BKE_simulation_state_try_find_by_name_and_type(Simulation *simulation,
+ const char *name,
+ const char *type)
+{
+ if (type == nullptr) {
+ return nullptr;
+ }
- if (current_frame == 1) {
- state_orig->tot_particles = 100;
- state_orig->current_frame = 1;
- CustomData_realloc(&state_orig->attributes, state_orig->tot_particles);
- ensure_attributes_exist(state_orig);
+ SimulationState *state = BKE_simulation_state_try_find_by_name(simulation, name);
+ if (state == nullptr) {
+ return nullptr;
+ }
+ if (STREQ(state->type, type)) {
+ return state;
+ }
+ return nullptr;
+}
- MutableSpan<float3> positions = get_particle_positions(state_orig);
- for (uint i : positions.index_range()) {
- positions[i] = {i / 10.0f, 0, 0};
- }
+void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation)
+{
+ blender::sim::update_simulation_in_depsgraph(depsgraph, scene, simulation);
+}
- BKE_ptcache_write(&pid_orig, current_frame);
- copy_particle_state_to_cow(state_orig, state_cow);
+void BKE_simulation_update_dependencies(Simulation *simulation, Main *bmain)
+{
+ bool dependencies_changed = blender::sim::update_simulation_dependencies(simulation);
+ if (dependencies_changed) {
+ DEG_relations_tag_update(bmain);
}
- else if (current_frame == state_orig->current_frame + 1) {
- state_orig->current_frame = current_frame;
- ensure_attributes_exist(state_orig);
- MutableSpan<float3> positions = get_particle_positions(state_orig);
- for (float3 &position : positions) {
- position.z += 0.1f;
- }
+}
- BKE_ptcache_write(&pid_orig, current_frame);
- copy_particle_state_to_cow(state_orig, state_cow);
+using StateTypeMap = blender::Map<std::string, std::unique_ptr<SimulationStateType>>;
+
+template<typename T>
+static void add_state_type(StateTypeMap &map,
+ const char *name,
+ void (*init)(T *state),
+ void (*reset)(T *state),
+ void (*remove)(T *state),
+ void (*copy)(const T *src, T *dst))
+{
+ SimulationStateType state_type{
+ name,
+ (int)sizeof(T),
+ (StateInitFunction)init,
+ (StateResetFunction)reset,
+ (StateRemoveFunction)remove,
+ (StateCopyFunction)copy,
+ };
+ map.add_new(name, std::make_unique<SimulationStateType>(state_type));
+}
+
+static StateTypeMap init_state_types()
+{
+ StateTypeMap map;
+ add_state_type<ParticleSimulationState>(
+ map,
+ SIM_TYPE_NAME_PARTICLE_SIMULATION,
+ [](ParticleSimulationState *state) { CustomData_reset(&state->attributes); },
+ [](ParticleSimulationState *state) {
+ CustomData_free(&state->attributes, state->tot_particles);
+ state->tot_particles = 0;
+ state->next_particle_id = 0;
+ },
+ [](ParticleSimulationState *state) {
+ CustomData_free(&state->attributes, state->tot_particles);
+ },
+ [](const ParticleSimulationState *src, ParticleSimulationState *dst) {
+ CustomData_free(&dst->attributes, dst->tot_particles);
+ dst->tot_particles = src->tot_particles;
+ dst->next_particle_id = src->next_particle_id;
+ CustomData_copy(
+ &src->attributes, &dst->attributes, CD_MASK_ALL, CD_DUPLICATE, src->tot_particles);
+ });
+
+ add_state_type<ParticleMeshEmitterSimulationState>(
+ map,
+ SIM_TYPE_NAME_PARTICLE_MESH_EMITTER,
+ [](ParticleMeshEmitterSimulationState *UNUSED(state)) {},
+ [](ParticleMeshEmitterSimulationState *state) { state->last_birth_time = 0.0f; },
+ [](ParticleMeshEmitterSimulationState *UNUSED(state)) {},
+ [](const ParticleMeshEmitterSimulationState *src, ParticleMeshEmitterSimulationState *dst) {
+ dst->last_birth_time = src->last_birth_time;
+ });
+ return map;
+}
+
+static StateTypeMap &get_state_types()
+{
+ static StateTypeMap state_type_map = init_state_types();
+ return state_type_map;
+}
+
+static const SimulationStateType *try_get_state_type(blender::StringRefNull type_name)
+{
+ std::unique_ptr<SimulationStateType> *type = get_state_types().lookup_ptr_as(type_name);
+ if (type == nullptr) {
+ return nullptr;
}
+ return type->get();
}
-} // namespace blender::bke
+template<> const char *BKE_simulation_get_state_type_name<ParticleSimulationState>()
+{
+ return SIM_TYPE_NAME_PARTICLE_SIMULATION;
+}
-void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation)
+template<> const char *BKE_simulation_get_state_type_name<ParticleMeshEmitterSimulationState>()
{
- blender::bke::simulation_data_update(depsgraph, scene, simulation);
+ return SIM_TYPE_NAME_PARTICLE_MESH_EMITTER;
}
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 9c7abbdf876..b7b325644ca 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -165,24 +165,28 @@ static void free_softbody_intern(SoftBody *sb);
/*physical unit of force is [kg * m / sec^2]*/
-static float sb_grav_force_scale(Object *UNUSED(ob))
-/* since unit of g is [m/sec^2] and F = mass * g we rescale unit mass of node to 1 gramm
- * put it to a function here, so we can add user options later without touching simulation code
+/**
+ * Since unit of g is [m/sec^2] and F = mass * g we re-scale unit mass of node to 1 gram
+ * put it to a function here, so we can add user options later without touching simulation code.
*/
+static float sb_grav_force_scale(Object *UNUSED(ob))
{
return (0.001f);
}
-static float sb_fric_force_scale(Object *UNUSED(ob))
-/* rescaling unit of drag [1 / sec] to somehow reasonable
- * put it to a function here, so we can add user options later without touching simulation code
+/**
+ * Re-scaling unit of drag [1 / sec] to somehow reasonable
+ * put it to a function here, so we can add user options later without touching simulation code.
*/
+static float sb_fric_force_scale(Object *UNUSED(ob))
{
return (0.01f);
}
+/**
+ * Defining the frames to *real* time relation.
+ */
static float sb_time_scale(Object *ob)
-/* defining the frames to *real* time relation */
{
SoftBody *sb = ob->soft; /* is supposed to be there */
if (sb) {
@@ -481,7 +485,6 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
mima->maxy = max_ff(mima->maxy, v[1] + hull);
mima->maxz = max_ff(mima->maxz, v[2] + hull);
}
- return;
}
static void ccd_mesh_free(ccd_Mesh *ccdm)
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 18fd8a10cc1..1fcfc9b060f 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -123,7 +123,7 @@ static void sound_foreach_cache(ID *id,
.cache_v = sound->waveform,
};
- function_callback(id, &key, &sound->waveform, user_data);
+ function_callback(id, &key, &sound->waveform, 0, user_data);
}
IDTypeInfo IDType_ID_SO = {
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index 8455b60c894..46341652544 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -875,7 +875,6 @@ BLI_INLINE void studiolight_spherical_harmonics_eval(StudioLight *sl,
color[i] = studiolight_spherical_harmonics_geomerics_eval(
normal, sh[0][i], sh[1][i], sh[2][i], sh[3][i]);
}
- return;
#else
/* L0 */
mul_v3_v3fl(color, sl->spherical_harmonics_coefs[0], 0.282095f);
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index a1e218390c3..c992990e0a0 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -1618,6 +1618,18 @@ static int prev_adjacent_edge_point_index(const SubdivCCG *subdiv_ccg, const int
return point_index - 1;
}
+/* When the point index corresponds to a grid corner, returns the point index which corresponds to
+ * the corner of the adjacent grid, as the adjacent edge has two separate points for each grid
+ * corner at the middle of the edge. */
+static int adjacent_grid_corner_point_index_on_edge(const SubdivCCG *subdiv_ccg,
+ const int point_index)
+{
+ if (point_index == subdiv_ccg->grid_size) {
+ return point_index - 1;
+ }
+ return point_index + 1;
+}
+
/* Common implementation of neighbor calculation when input coordinate is at the edge between two
* coarse faces, but is not at the coarse vertex. */
static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
@@ -1626,6 +1638,7 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
SubdivCCGNeighbors *r_neighbors)
{
+ const bool is_corner = is_corner_grid_coord(subdiv_ccg, coord);
const int adjacent_edge_index = adjacent_edge_index_from_coord(subdiv_ccg, coord);
BLI_assert(adjacent_edge_index >= 0);
BLI_assert(adjacent_edge_index < subdiv_ccg->num_adjacent_edges);
@@ -1633,15 +1646,27 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
/* 2 neighbor points along the edge, plus one inner point per every adjacent grid. */
const int num_adjacent_faces = adjacent_edge->num_adjacent_faces;
- subdiv_ccg_neighbors_init(
- r_neighbors, num_adjacent_faces + 2, (include_duplicates) ? num_adjacent_faces - 1 : 0);
+ int num_duplicates = 0;
+ if (include_duplicates) {
+ num_duplicates += num_adjacent_faces - 1;
+ if (is_corner) {
+ /* When the coord is a grid corner, add an extra duplicate per adjacent grid in all adjacent
+ * faces to the edge. */
+ num_duplicates += num_adjacent_faces;
+ }
+ }
+ subdiv_ccg_neighbors_init(r_neighbors, num_adjacent_faces + 2, num_duplicates);
const int point_index = adjacent_edge_point_index_from_coord(
subdiv_ccg, coord, adjacent_edge_index);
+ const int point_index_duplicate = adjacent_grid_corner_point_index_on_edge(subdiv_ccg,
+ point_index);
+
const int next_point_index = next_adjacent_edge_point_index(subdiv_ccg, point_index);
const int prev_point_index = prev_adjacent_edge_point_index(subdiv_ccg, point_index);
- for (int i = 0, duplicate_i = num_adjacent_faces; i < num_adjacent_faces; ++i) {
+ int duplicate_i = num_adjacent_faces;
+ for (int i = 0; i < num_adjacent_faces; ++i) {
SubdivCCGCoord *boundary_coords = adjacent_edge->boundary_coords[i];
/* One step into the grid from the edge for each adjacent face. */
SubdivCCGCoord grid_coord = boundary_coords[point_index];
@@ -1657,7 +1682,15 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
r_neighbors->coords[duplicate_i + 2] = grid_coord;
duplicate_i++;
}
+
+ /* When it is a corner, add the duplicate of the adjacent grid in the same face. */
+ if (include_duplicates && is_corner) {
+ SubdivCCGCoord duplicate_corner_grid_coord = boundary_coords[point_index_duplicate];
+ r_neighbors->coords[duplicate_i + 2] = duplicate_corner_grid_coord;
+ duplicate_i++;
+ }
}
+ BLI_assert(duplicate_i - num_adjacent_faces == num_duplicates);
}
/* The corner is at the middle of edge between faces. */
@@ -1834,4 +1867,70 @@ const int *BKE_subdiv_ccg_start_face_grid_index_get(const SubdivCCG *subdiv_ccg)
return subdiv_ccg->cache_.start_face_grid_index;
}
+static void adjacet_vertices_index_from_adjacent_edge(const SubdivCCG *subdiv_ccg,
+ const SubdivCCGCoord *coord,
+ const MLoop *mloop,
+ const MPoly *mpoly,
+ int *r_v1,
+ int *r_v2)
+{
+ const int grid_size_1 = subdiv_ccg->grid_size - 1;
+ const int poly_index = BKE_subdiv_ccg_grid_to_face_index(subdiv_ccg, coord->grid_index);
+ const MPoly *p = &mpoly[poly_index];
+ *r_v1 = mloop[coord->grid_index].v;
+ if (coord->x == grid_size_1) {
+ const MLoop *next = ME_POLY_LOOP_NEXT(mloop, p, coord->grid_index);
+ *r_v2 = next->v;
+ }
+ if (coord->y == grid_size_1) {
+ const MLoop *prev = ME_POLY_LOOP_PREV(mloop, p, coord->grid_index);
+ *r_v2 = prev->v;
+ }
+}
+
+SubdivCCGAdjacencyType BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(const SubdivCCG *subdiv_ccg,
+ const SubdivCCGCoord *coord,
+ const MLoop *mloop,
+ const MPoly *mpoly,
+ int *r_v1,
+ int *r_v2)
+{
+
+ const int grid_size_1 = subdiv_ccg->grid_size - 1;
+ if (is_corner_grid_coord(subdiv_ccg, coord)) {
+ if (coord->x == 0 && coord->y == 0) {
+ /* Grid corner in the center of a poly. */
+ return SUBDIV_CCG_ADJACENT_NONE;
+ }
+ if (coord->x == grid_size_1 && coord->y == grid_size_1) {
+ /* Grid corner adjacent to a coarse mesh vertex. */
+ *r_v1 = *r_v2 = mloop[coord->grid_index].v;
+ return SUBDIV_CCG_ADJACENT_VERTEX;
+ }
+ /* Grid corner adjacent to the middle of a coarse mesh edge. */
+ adjacet_vertices_index_from_adjacent_edge(subdiv_ccg, coord, mloop, mpoly, r_v1, r_v2);
+ return SUBDIV_CCG_ADJACENT_EDGE;
+ }
+
+ if (is_boundary_grid_coord(subdiv_ccg, coord)) {
+ if (!is_inner_edge_grid_coordinate(subdiv_ccg, coord)) {
+ /* Grid boundary adjacent to a coarse mesh edge. */
+ adjacet_vertices_index_from_adjacent_edge(subdiv_ccg, coord, mloop, mpoly, r_v1, r_v2);
+ return SUBDIV_CCG_ADJACENT_EDGE;
+ }
+ }
+ return SUBDIV_CCG_ADJACENT_NONE;
+}
+
+void BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG *subdiv_ccg, int grid_index)
+{
+ if (subdiv_ccg->grid_hidden[grid_index] != NULL) {
+ return;
+ }
+
+ CCGKey key;
+ BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
+ subdiv_ccg->grid_hidden[grid_index] = BLI_BITMAP_NEW(key.grid_area, __func__);
+}
+
/** \} */
diff --git a/source/blender/blenkernel/intern/subdiv_converter.h b/source/blender/blenkernel/intern/subdiv_converter.h
index fb0e84ade13..ea0efe994b5 100644
--- a/source/blender/blenkernel/intern/subdiv_converter.h
+++ b/source/blender/blenkernel/intern/subdiv_converter.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __SUBDIV_CONVERTER_H__
-#define __SUBDIV_CONVERTER_H__
+#pragma once
/** \file
* \ingroup bke
@@ -51,5 +50,3 @@ int BKE_subdiv_converter_vtx_boundary_interpolation_from_settings(const SubdivSe
/* TODO(sergey): Find a way to make it OpenSubdiv_FVarLinearInterpolation,
* without breaking compilation without OpenSubdiv. */
int BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings);
-
-#endif /* __SUBDIV_CONVERTER_H__ */
diff --git a/source/blender/blenkernel/intern/subdiv_inline.h b/source/blender/blenkernel/intern/subdiv_inline.h
index a51a33feb3d..ba45d0a4997 100644
--- a/source/blender/blenkernel/intern/subdiv_inline.h
+++ b/source/blender/blenkernel/intern/subdiv_inline.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __SUBDIV_INLINE_H__
-#define __SUBDIV_INLINE_H__
+#pragma once
#include "BLI_assert.h"
#include "BLI_compiler_compat.h"
@@ -114,5 +113,3 @@ BLI_INLINE float BKE_subdiv_edge_crease_to_sharpness_char(char edge_crease)
const float edge_crease_f = edge_crease / 255.0f;
return BKE_subdiv_edge_crease_to_sharpness_f(edge_crease_f);
}
-
-#endif /* __SUBDIV_INLINE_H__ */
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 97d95cb7e46..f17467e4a26 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -509,7 +509,7 @@ void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingOb
}
}
-/* Check whether there're any tracks in the clipboard. */
+/* Check whether there are any tracks in the clipboard. */
bool BKE_tracking_clipboard_has_tracks(void)
{
return (BLI_listbase_is_empty(&tracking_clipboard.tracks) == false);
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index e09e92588c6..b9c6bb83157 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -215,7 +215,7 @@ static void use_values_from_fcurves(StabContext *ctx, bool toggle)
/* Prepare per call private working area.
* Used for access to possibly animated values: retrieve available F-curves.
*/
-static StabContext *initialize_stabilization_working_context(MovieClip *clip)
+static StabContext *init_stabilization_working_context(MovieClip *clip)
{
StabContext *ctx = MEM_callocN(sizeof(StabContext), "2D stabilization animation runtime data");
ctx->clip = clip;
@@ -841,14 +841,14 @@ static int establish_track_initialization_order(StabContext *ctx, TrackInitOrder
*
* NOTE: when done, this track is marked as initialized
*/
-static void initialize_track_for_stabilization(StabContext *ctx,
- MovieTrackingTrack *track,
- int reference_frame,
- float aspect,
- const float average_translation[2],
- const float pivot[2],
- const float average_angle,
- const float average_scale_step)
+static void init_track_for_stabilization(StabContext *ctx,
+ MovieTrackingTrack *track,
+ int reference_frame,
+ float aspect,
+ const float average_translation[2],
+ const float pivot[2],
+ const float average_angle,
+ const float average_scale_step)
{
float pos[2], angle, len;
TrackStabilizationBase *local_data = access_stabilization_baseline_data(ctx, track);
@@ -876,7 +876,7 @@ static void initialize_track_for_stabilization(StabContext *ctx,
local_data->is_init_for_stabilization = true;
}
-static void initialize_all_tracks(StabContext *ctx, float aspect)
+static void init_all_tracks(StabContext *ctx, float aspect)
{
size_t track_len = 0;
MovieClip *clip = ctx->clip;
@@ -936,14 +936,14 @@ static void initialize_all_tracks(StabContext *ctx, float aspect)
&average_angle,
&average_scale_step);
}
- initialize_track_for_stabilization(ctx,
- track,
- reference_frame,
- aspect,
- average_translation,
- pivot,
- average_angle,
- average_scale_step);
+ init_track_for_stabilization(ctx,
+ track,
+ reference_frame,
+ aspect,
+ average_translation,
+ pivot,
+ average_angle,
+ average_scale_step);
}
cleanup:
@@ -1257,9 +1257,9 @@ static float calculate_autoscale_factor(StabContext *ctx, int size, float aspect
*/
static StabContext *init_stabilizer(MovieClip *clip, int size, float aspect)
{
- StabContext *ctx = initialize_stabilization_working_context(clip);
+ StabContext *ctx = init_stabilization_working_context(clip);
BLI_assert(ctx != NULL);
- initialize_all_tracks(ctx, aspect);
+ init_all_tracks(ctx, aspect);
if (ctx->stab->flag & TRACKING_AUTOSCALE) {
ctx->stab->scale = 1.0;
ctx->stab->scale = calculate_autoscale_factor(ctx, size, aspect);
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index e155dedeef0..0809e8dda6d 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -507,9 +507,7 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack,
/* Might not be final place for this to be called - probably only want to call it from some
* undo handlers, not all of them? */
- if (BKE_lib_override_library_is_enabled()) {
- BKE_lib_override_library_main_operations_create(G_MAIN, false);
- }
+ BKE_lib_override_library_main_operations_create(G_MAIN, false);
/* Remove all undos after (also when 'ustack->step_active == NULL'). */
while (ustack->steps.last != ustack->step_active) {
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index f37feab4b85..efe10b02940 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -1005,7 +1005,6 @@ bool bUnit_ReplaceString(
/* Fix cases like "-1m50cm" which would evaluate to -0.5m without this. */
changed |= unit_distribute_negatives(str, len_max);
- printf("%s\n", str);
/* Try to find a default unit from current or previous string. */
default_unit = unit_detect_from_str(usys, str, str_prev);
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 18859869b4e..633ad250a67 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -218,7 +218,9 @@ static struct VolumeFileCache {
cache.erase(entry);
}
else if (entry.num_tree_users == 0) {
- entry.grid->clear();
+ /* Note we replace the grid rather than clearing, so that if there is
+ * any other shared pointer to the grid it will keep the tree. */
+ entry.grid = entry.grid->copyGridWithNewTree();
entry.is_loaded = false;
}
}
@@ -239,15 +241,14 @@ struct VolumeGrid {
VolumeGrid(const VolumeFileCache::Entry &template_entry) : entry(NULL), is_loaded(false)
{
entry = GLOBAL_CACHE.add_metadata_user(template_entry);
- vdb = entry->grid;
}
- VolumeGrid(const openvdb::GridBase::Ptr &vdb) : vdb(vdb), entry(NULL), is_loaded(true)
+ VolumeGrid(const openvdb::GridBase::Ptr &grid) : entry(NULL), local_grid(grid), is_loaded(true)
{
}
VolumeGrid(const VolumeGrid &other)
- : vdb(other.vdb), entry(other.entry), is_loaded(other.is_loaded)
+ : entry(other.entry), local_grid(other.local_grid), is_loaded(other.is_loaded)
{
if (entry) {
GLOBAL_CACHE.copy_user(*entry, is_loaded);
@@ -330,7 +331,7 @@ struct VolumeGrid {
void clear_reference(const char *UNUSED(volume_name))
{
/* Clear any reference to a grid in the file cache. */
- vdb = vdb->copyGridWithNewTree();
+ local_grid = grid()->copyGridWithNewTree();
if (entry) {
GLOBAL_CACHE.remove_user(*entry, is_loaded);
entry = NULL;
@@ -344,7 +345,7 @@ struct VolumeGrid {
* file cache. Load file grid into memory first if needed. */
load(volume_name, filepath);
/* TODO: avoid deep copy if we are the only user. */
- vdb = vdb->deepCopyGrid();
+ local_grid = grid()->deepCopyGrid();
if (entry) {
GLOBAL_CACHE.remove_user(*entry, is_loaded);
entry = NULL;
@@ -356,7 +357,7 @@ struct VolumeGrid {
{
/* Don't use vdb.getName() since it copies the string, we want a pointer to the
* original so it doesn't get freed out of scope. */
- openvdb::StringMetadata::ConstPtr name_meta = vdb->getMetadata<openvdb::StringMetadata>(
+ openvdb::StringMetadata::ConstPtr name_meta = grid()->getMetadata<openvdb::StringMetadata>(
openvdb::GridBase::META_GRID_NAME);
return (name_meta) ? name_meta->value().c_str() : "";
}
@@ -371,10 +372,22 @@ struct VolumeGrid {
}
}
- /* OpenVDB grid. */
- openvdb::GridBase::Ptr vdb;
- /* File cache entry. */
+ const bool grid_is_loaded() const
+ {
+ return is_loaded;
+ }
+
+ const openvdb::GridBase::Ptr &grid() const
+ {
+ return (entry) ? entry->grid : local_grid;
+ }
+
+ protected:
+ /* File cache entry when grid comes directly from a file and may be shared
+ * with other volume datablocks. */
VolumeFileCache::Entry *entry;
+ /* OpenVDB grid if it's not shared through the file cache. */
+ openvdb::GridBase::Ptr local_grid;
/* Indicates if the tree has been loaded for this grid. Note that vdb.tree()
* may actually be loaded by another user while this is false. But only after
* calling load() and is_loaded changes to true is it safe to access. */
@@ -494,7 +507,7 @@ static void volume_foreach_cache(ID *id,
/* cache_v */ volume->runtime.grids,
};
- function_callback(id, &key, (void **)&volume->runtime.grids, user_data);
+ function_callback(id, &key, (void **)&volume->runtime.grids, 0, user_data);
}
IDTypeInfo IDType_ID_VO = {
@@ -1047,7 +1060,7 @@ void BKE_volume_grid_unload(const Volume *volume, VolumeGrid *grid)
bool BKE_volume_grid_is_loaded(const VolumeGrid *grid)
{
#ifdef WITH_OPENVDB
- return grid->is_loaded;
+ return grid->grid_is_loaded();
#else
UNUSED_VARS(grid);
return true;
@@ -1069,7 +1082,7 @@ const char *BKE_volume_grid_name(const VolumeGrid *volume_grid)
VolumeGridType BKE_volume_grid_type(const VolumeGrid *volume_grid)
{
#ifdef WITH_OPENVDB
- const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+ const openvdb::GridBase::Ptr &grid = volume_grid->grid();
if (grid->isType<openvdb::FloatGrid>()) {
return VOLUME_GRID_FLOAT;
@@ -1138,7 +1151,7 @@ int BKE_volume_grid_channels(const VolumeGrid *grid)
void BKE_volume_grid_transform_matrix(const VolumeGrid *volume_grid, float mat[4][4])
{
#ifdef WITH_OPENVDB
- const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+ const openvdb::GridBase::Ptr &grid = volume_grid->grid();
const openvdb::math::Transform &transform = grid->transform();
/* Perspective not supported for now, getAffineMap() will leave out the
@@ -1162,7 +1175,7 @@ bool BKE_volume_grid_bounds(const VolumeGrid *volume_grid, float min[3], float m
{
#ifdef WITH_OPENVDB
/* TODO: we can get this from grid metadata in some cases? */
- const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+ const openvdb::GridBase::Ptr &grid = volume_grid->grid();
BLI_assert(BKE_volume_grid_is_loaded(volume_grid));
openvdb::CoordBBox coordbbox;
@@ -1287,14 +1300,14 @@ void BKE_volume_grid_remove(Volume *volume, VolumeGrid *grid)
#ifdef WITH_OPENVDB
openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_metadata(const VolumeGrid *grid)
{
- return grid->vdb;
+ return grid->grid();
}
openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const Volume *volume,
VolumeGrid *grid)
{
BKE_volume_grid_load(volume, grid);
- return grid->vdb;
+ return grid->grid();
}
openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const Volume *volume,
@@ -1310,6 +1323,6 @@ openvdb::GridBase::Ptr BKE_volume_grid_openvdb_for_write(const Volume *volume,
grid->duplicate_reference(volume_name, grids.filepath);
}
- return grid->vdb;
+ return grid->grid();
}
#endif
diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h
index c72747a8c51..7057e9ab5bd 100644
--- a/source/blender/blenkernel/nla_private.h
+++ b/source/blender/blenkernel/nla_private.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __NLA_PRIVATE_H__
-#define __NLA_PRIVATE_H__
+#pragma once
#include "BLI_bitmap.h"
#include "BLI_ghash.h"
@@ -32,6 +31,8 @@
extern "C" {
#endif
+struct AnimationEvalContext;
+
/* --------------- NLA Evaluation DataTypes ----------------------- */
/* used for list of strips to accumulate at current time */
@@ -168,13 +169,17 @@ float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode);
/* these functions are only defined here to avoid problems with the order
* in which they get defined. */
-NlaEvalStrip *nlastrips_ctime_get_strip(
- ListBase *list, ListBase *strips, short index, float ctime, const bool flush_to_original);
+NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
+ ListBase *strips,
+ short index,
+ const struct AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original);
void nlastrip_evaluate(PointerRNA *ptr,
NlaEvalData *channels,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const struct AnimationEvalContext *anim_eval_context,
const bool flush_to_original);
void nladata_flush_channels(PointerRNA *ptr,
NlaEvalData *channels,
@@ -184,5 +189,3 @@ void nladata_flush_channels(PointerRNA *ptr,
#ifdef __cplusplus
}
#endif
-
-#endif /* __NLA_PRIVATE_H__ */
diff --git a/source/blender/blenkernel/particle_private.h b/source/blender/blenkernel/particle_private.h
index 6f80089be29..33277d1caac 100644
--- a/source/blender/blenkernel/particle_private.h
+++ b/source/blender/blenkernel/particle_private.h
@@ -21,8 +21,7 @@
* \ingroup bke
*/
-#ifndef __PARTICLE_PRIVATE_H__
-#define __PARTICLE_PRIVATE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -72,5 +71,3 @@ void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
#ifdef __cplusplus
}
#endif
-
-#endif /* __PARTICLE_PRIVATE_H__ */
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index 955a0b8753e..0965cef0d9b 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -24,8 +24,7 @@
* by multiple tracking files but which should not be public.
*/
-#ifndef __TRACKING_PRIVATE_H__
-#define __TRACKING_PRIVATE_H__
+#pragma once
#include "BLI_threads.h"
@@ -152,5 +151,3 @@ void tracking_image_accessor_destroy(TrackingImageAccessor *accessor);
#ifdef __cplusplus
}
#endif
-
-#endif /* __TRACKING_PRIVATE_H__ */
diff --git a/source/blender/blenlib/BLI_alloca.h b/source/blender/blenlib/BLI_alloca.h
index 5297296b7ef..92567ed35fa 100644
--- a/source/blender/blenlib/BLI_alloca.h
+++ b/source/blender/blenlib/BLI_alloca.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ALLOCA_H__
-#define __BLI_ALLOCA_H__
+#pragma once
/** \file
* \ingroup bli
@@ -25,6 +24,8 @@
/* BLI_array_alloca / alloca */
+#include <stdlib.h>
+
#if defined(__GNUC__) || defined(__clang__)
# if defined(__cplusplus) && (__cplusplus > 199711L)
# define BLI_array_alloca(arr, realsize) (decltype(arr)) alloca(sizeof(*arr) * (realsize))
@@ -34,5 +35,3 @@
#else
# define BLI_array_alloca(arr, realsize) alloca(sizeof(*arr) * (realsize))
#endif
-
-#endif /* __BLI_ALLOCA_H__ */
diff --git a/source/blender/blenlib/BLI_allocator.hh b/source/blender/blenlib/BLI_allocator.hh
index d57703f71bc..3f753d1d81d 100644
--- a/source/blender/blenlib/BLI_allocator.hh
+++ b/source/blender/blenlib/BLI_allocator.hh
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ALLOCATOR_HH__
-#define __BLI_ALLOCATOR_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -84,8 +83,8 @@ class RawAllocator {
void *ptr = malloc(size + alignment + sizeof(MemHead));
void *used_ptr = (void *)((uintptr_t)POINTER_OFFSET(ptr, alignment + sizeof(MemHead)) &
~((uintptr_t)alignment - 1));
- uint offset = (uint)((uintptr_t)used_ptr - (uintptr_t)ptr);
- BLI_assert(offset >= sizeof(MemHead));
+ int offset = (int)((intptr_t)used_ptr - (intptr_t)ptr);
+ BLI_assert(offset >= (int)sizeof(MemHead));
((MemHead *)used_ptr - 1)->offset = (int)offset;
return used_ptr;
}
@@ -100,5 +99,3 @@ class RawAllocator {
};
} // namespace blender
-
-#endif /* __BLI_ALLOCATOR_HH__ */
diff --git a/source/blender/blenlib/BLI_args.h b/source/blender/blenlib/BLI_args.h
index 9031cd2ba2f..54b5161f15a 100644
--- a/source/blender/blenlib/BLI_args.h
+++ b/source/blender/blenlib/BLI_args.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_ARGS_H__
-#define __BLI_ARGS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -78,5 +77,3 @@ const char **BLI_argsArgv(struct bArgs *ba);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index 5b85711f8ac..6ea01d45f79 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_ARRAY_H__
-#define __BLI_ARRAY_H__
+#pragma once
/** \file
* \ingroup bli
@@ -173,5 +172,3 @@ void _bli_array_grow_func(void **arr_p,
((void)0)
/** \} */
-
-#endif /* __BLI_ARRAY_H__ */
diff --git a/source/blender/blenlib/BLI_array.hh b/source/blender/blenlib/BLI_array.hh
index ee4e9702779..796123af765 100644
--- a/source/blender/blenlib/BLI_array.hh
+++ b/source/blender/blenlib/BLI_array.hh
@@ -13,8 +13,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ARRAY_HH__
-#define __BLI_ARRAY_HH__
+
+#pragma once
/** \file
* \ingroup bli
@@ -52,11 +52,8 @@ template<
typename T,
/**
* The number of values that can be stored in the array, without doing a heap allocation.
- *
- * When T is large, the small buffer optimization is disabled by default to avoid large
- * unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)),
/**
* The allocator used by this array. Should rarely be changed, except when you don't want that
* MEM_* functions are used internally.
@@ -68,13 +65,13 @@ class Array {
T *data_;
/** Number of elements in the array. */
- uint size_;
+ int64_t size_;
/** Used for allocations when the inline buffer is too small. */
Allocator allocator_;
/** A placeholder buffer that will remain uninitialized until it is used. */
- AlignedBuffer<sizeof(T) * InlineBufferCapacity, alignof(T)> inline_buffer_;
+ TypedBuffer<T, InlineBufferCapacity> inline_buffer_;
public:
/**
@@ -82,23 +79,29 @@ class Array {
*/
Array()
{
- data_ = this->inline_buffer();
+ data_ = inline_buffer_;
size_ = 0;
}
/**
* Create a new array that contains copies of all values.
*/
- Array(Span<T> values)
+ template<typename U, typename std::enable_if_t<std::is_convertible_v<U, T>> * = nullptr>
+ Array(Span<U> values, Allocator allocator = {}) : allocator_(allocator)
{
size_ = values.size();
data_ = this->get_buffer_for_size(values.size());
- uninitialized_copy_n(values.data(), size_, data_);
+ uninitialized_convert_n<U, T>(values.data(), size_, data_);
}
/**
* Create a new array that contains copies of all values.
*/
+ template<typename U, typename std::enable_if_t<std::is_convertible_v<U, T>> * = nullptr>
+ Array(const std::initializer_list<U> &values) : Array(Span<U>(values))
+ {
+ }
+
Array(const std::initializer_list<T> &values) : Array(Span<T>(values))
{
}
@@ -111,7 +114,7 @@ class Array {
* even for non-trivial types. This should not be the default though, because one can easily mess
* up when dealing with uninitialized memory.
*/
- explicit Array(uint size)
+ explicit Array(int64_t size)
{
size_ = size;
data_ = this->get_buffer_for_size(size);
@@ -122,8 +125,9 @@ class Array {
* Create a new array with the given size. All values will be initialized by copying the given
* default.
*/
- Array(uint size, const T &value)
+ Array(int64_t size, const T &value)
{
+ BLI_assert(size >= 0);
size_ = size;
data_ = this->get_buffer_for_size(size);
uninitialized_fill_n(data_, size_, value);
@@ -141,18 +145,15 @@ class Array {
* Usage:
* Array<std::string> my_strings(10, NoInitialization());
*/
- Array(uint size, NoInitialization)
+ Array(int64_t size, NoInitialization)
{
+ BLI_assert(size >= 0);
size_ = size;
data_ = this->get_buffer_for_size(size);
}
- Array(const Array &other) : allocator_(other.allocator_)
+ Array(const Array &other) : Array(other.as_span(), other.allocator_)
{
- size_ = other.size();
-
- data_ = this->get_buffer_for_size(other.size());
- uninitialized_copy_n(other.data(), size_, data_);
}
Array(Array &&other) noexcept : allocator_(other.allocator_)
@@ -167,7 +168,7 @@ class Array {
uninitialized_relocate_n(other.data_, size_, data_);
}
- other.data_ = other.inline_buffer();
+ other.data_ = other.inline_buffer_;
other.size_ = 0;
}
@@ -201,14 +202,16 @@ class Array {
return *this;
}
- T &operator[](uint index)
+ T &operator[](int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < size_);
return data_[index];
}
- const T &operator[](uint index) const
+ const T &operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < size_);
return data_[index];
}
@@ -223,6 +226,18 @@ class Array {
return MutableSpan<T>(data_, size_);
}
+ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<T, U>> * = nullptr>
+ operator Span<U>() const
+ {
+ return Span<U>(data_, size_);
+ }
+
+ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<T, U>> * = nullptr>
+ operator MutableSpan<U>()
+ {
+ return MutableSpan<U>(data_, size_);
+ }
+
Span<T> as_span() const
{
return *this;
@@ -236,7 +251,7 @@ class Array {
/**
* Returns the number of elements in the array.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -250,22 +265,14 @@ class Array {
}
/**
- * Copies the value to all indices in the array.
+ * Copies the given value to every element in the array.
*/
- void fill(const T &value)
+ void fill(const T &value) const
{
initialized_fill_n(data_, size_, value);
}
/**
- * Copies the value to the given indices in the array.
- */
- void fill_indices(Span<uint> indices, const T &value)
- {
- MutableSpan<T>(*this).fill_indices(indices, value);
- }
-
- /**
* Get a pointer to the beginning of the array.
*/
const T *data() const
@@ -326,38 +333,38 @@ class Array {
* Get the value of the InlineBufferCapacity template argument. This is the number of elements
* that can be stored without doing an allocation.
*/
- static uint inline_buffer_capacity()
+ static int64_t inline_buffer_capacity()
{
return InlineBufferCapacity;
}
private:
- T *get_buffer_for_size(uint size)
+ T *get_buffer_for_size(int64_t size)
{
if (size <= InlineBufferCapacity) {
- return this->inline_buffer();
+ return inline_buffer_;
}
else {
return this->allocate(size);
}
}
- T *inline_buffer() const
+ T *allocate(int64_t size)
{
- return (T *)inline_buffer_.ptr();
- }
-
- T *allocate(uint size)
- {
- return (T *)allocator_.allocate(size * sizeof(T), alignof(T), AT);
+ return (T *)allocator_.allocate((size_t)size * sizeof(T), alignof(T), AT);
}
bool uses_inline_buffer() const
{
- return data_ == this->inline_buffer();
+ return data_ == inline_buffer_;
}
};
-} // namespace blender
+/**
+ * Same as a normal Array, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
+using RawArray = Array<T, InlineBufferCapacity, RawAllocator>;
-#endif /* __BLI_ARRAY_HH__ */
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_array_store.h b/source/blender/blenlib/BLI_array_store.h
index a8a7dde63b5..78d718117ba 100644
--- a/source/blender/blenlib/BLI_array_store.h
+++ b/source/blender/blenlib/BLI_array_store.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ARRAY_STORE_H__
-#define __BLI_ARRAY_STORE_H__
+#pragma once
/** \file
* \ingroup bli
@@ -53,5 +52,3 @@ bool BLI_array_store_is_valid(BArrayStore *bs);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_ARRAY_STORE_H__ */
diff --git a/source/blender/blenlib/BLI_array_store_utils.h b/source/blender/blenlib/BLI_array_store_utils.h
index 5b5263bf8a4..771f4f962a7 100644
--- a/source/blender/blenlib/BLI_array_store_utils.h
+++ b/source/blender/blenlib/BLI_array_store_utils.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ARRAY_STORE_UTILS_H__
-#define __BLI_ARRAY_STORE_UTILS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -47,5 +46,3 @@ void BLI_array_store_at_size_calc_memory_usage(struct BArrayStore_AtSize *bs_str
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_ARRAY_STORE_UTILS_H__ */
diff --git a/source/blender/blenlib/BLI_array_utils.h b/source/blender/blenlib/BLI_array_utils.h
index afa9a3d2241..b8d63e7cdc1 100644
--- a/source/blender/blenlib/BLI_array_utils.h
+++ b/source/blender/blenlib/BLI_array_utils.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ARRAY_UTILS_H__
-#define __BLI_ARRAY_UTILS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -93,5 +92,3 @@ bool _bli_array_is_zeroed(const void *arr, unsigned int arr_len, size_t arr_stri
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_ARRAY_UTILS_H__ */
diff --git a/source/blender/blenlib/BLI_asan.h b/source/blender/blenlib/BLI_asan.h
index fdade805c2a..a2a44e164ab 100644
--- a/source/blender/blenlib/BLI_asan.h
+++ b/source/blender/blenlib/BLI_asan.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ADDRESS_SANITIZER_H__
-#define __BLI_ADDRESS_SANITIZER_H__
+#pragma once
/* Clang defines this. */
#ifndef __has_feature
@@ -41,5 +40,3 @@
* Mark a region of memory as usable again.
*/
#define BLI_asan_unpoison(addr, size) ASAN_UNPOISON_MEMORY_REGION(addr, size)
-
-#endif /* __BLI_ADDRESS_SANITIZER_H__ */
diff --git a/source/blender/blenlib/BLI_assert.h b/source/blender/blenlib/BLI_assert.h
index 603be115b35..172a2fb44ca 100644
--- a/source/blender/blenlib/BLI_assert.h
+++ b/source/blender/blenlib/BLI_assert.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ASSERT_H__
-#define __BLI_ASSERT_H__
+#pragma once
/** \file
* \ingroup bli
@@ -30,58 +29,33 @@
extern "C" {
#endif
-#ifndef NDEBUG /* for BLI_assert */
-# include <stdio.h>
-#endif
+/* Utility functions. */
+void _BLI_assert_print_pos(const char *file, const int line, const char *function, const char *id);
+void _BLI_assert_print_backtrace(void);
+void _BLI_assert_abort(void);
#ifdef _MSC_VER
# include <crtdbg.h> /* for _STATIC_ASSERT */
#endif
-/* BLI_assert(), default only to print
- * for aborting need to define WITH_ASSERT_ABORT
- */
-/* For 'abort' only. */
-#include <stdlib.h>
-
#ifndef NDEBUG
-# include "BLI_system.h"
/* _BLI_ASSERT_PRINT_POS */
# if defined(__GNUC__)
-# define _BLI_ASSERT_PRINT_POS(a) \
- fprintf(stderr, \
- "BLI_assert failed: %s:%d, %s(), at \'%s\'\n", \
- __FILE__, \
- __LINE__, \
- __func__, \
- #a)
+# define _BLI_ASSERT_PRINT_POS(a) _BLI_assert_print_pos(__FILE__, __LINE__, __func__, # a)
# elif defined(_MSC_VER)
-# define _BLI_ASSERT_PRINT_POS(a) \
- fprintf(stderr, \
- "BLI_assert failed: %s:%d, %s(), at \'%s\'\n", \
- __FILE__, \
- __LINE__, \
- __FUNCTION__, \
- #a)
+# define _BLI_ASSERT_PRINT_POS(a) _BLI_assert_print_pos(__FILE__, __LINE__, __func__, # a)
# else
-# define _BLI_ASSERT_PRINT_POS(a) \
- fprintf(stderr, "BLI_assert failed: %s:%d, at \'%s\'\n", __FILE__, __LINE__, #a)
+# define _BLI_ASSERT_PRINT_POS(a) _BLI_assert_print_pos(__FILE__, __LINE__, "<?>", # a)
# endif
/* _BLI_ASSERT_ABORT */
# ifdef WITH_ASSERT_ABORT
-# ifdef __GNUC__
-/* Cast to remove 'noreturn' attribute since this suppresses missing return statements,
- * allowing changes to debug builds to accidentally to break release builds. */
-# define _BLI_ASSERT_ABORT ((void (*)(void))(*(((void **)abort))))
-# else
-# define _BLI_ASSERT_ABORT abort
-# endif
+# define _BLI_ASSERT_ABORT _BLI_assert_abort
# else
# define _BLI_ASSERT_ABORT() (void)0
# endif
/* BLI_assert */
# define BLI_assert(a) \
- (void)((!(a)) ? ((BLI_system_backtrace(stderr), \
+ (void)((!(a)) ? ((_BLI_assert_print_backtrace(), \
_BLI_ASSERT_PRINT_POS(a), \
_BLI_ASSERT_ABORT(), \
NULL)) : \
@@ -117,5 +91,3 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_ASSERT_H__ */
diff --git a/source/blender/blenlib/BLI_astar.h b/source/blender/blenlib/BLI_astar.h
index 8a70371cbcb..fe5c4ddad69 100644
--- a/source/blender/blenlib/BLI_astar.h
+++ b/source/blender/blenlib/BLI_astar.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_ASTAR_H__
-#define __BLI_ASTAR_H__
+#pragma once
/** \file
* \ingroup bli
@@ -121,5 +120,3 @@ bool BLI_astar_graph_solve(BLI_AStarGraph *as_graph,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_ASTAR_H__ */
diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h
index 2b811e50efb..61a50662d79 100644
--- a/source/blender/blenlib/BLI_bitmap.h
+++ b/source/blender/blenlib/BLI_bitmap.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_BITMAP_H__
-#define __BLI_BITMAP_H__
+#pragma once
/** \file
* \ingroup bli
@@ -118,5 +117,3 @@ void BLI_bitmap_or_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenlib/BLI_bitmap_draw_2d.h b/source/blender/blenlib/BLI_bitmap_draw_2d.h
index f5f8b28b27f..8331d8fac08 100644
--- a/source/blender/blenlib/BLI_bitmap_draw_2d.h
+++ b/source/blender/blenlib/BLI_bitmap_draw_2d.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_BITMAP_DRAW_2D_H__
-#define __BLI_BITMAP_DRAW_2D_H__
+#pragma once
/** \file
* \ingroup bli
@@ -48,5 +47,3 @@ void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_BITMAP_DRAW_2D_H__ */
diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h
index 6dd1abacf78..a9e8c55b6b4 100644
--- a/source/blender/blenlib/BLI_blenlib.h
+++ b/source/blender/blenlib/BLI_blenlib.h
@@ -28,7 +28,7 @@
* a call to a BLI function that is not prototyped here, please add a
* prototype here. The library offers mathematical operations (mainly
* vector and matrix calculus), an abstraction layer for file i/o,
- * functions for calculating Perlin noise, scanfilling services for
+ * functions for calculating Perlin noise, scan-filling services for
* triangles, and a system for guarded memory
* allocation/deallocation. There is also a patch to make MS Windows
* behave more or less Posix-compliant.
@@ -47,8 +47,7 @@
* standard libraries.
*/
-#ifndef __BLI_BLENLIB_H__
-#define __BLI_BLENLIB_H__
+#pragma once
#include <stdlib.h>
@@ -63,5 +62,3 @@
#include "BLI_fileops.h"
#include "BLI_rect.h"
-
-#endif
diff --git a/source/blender/blenlib/BLI_boxpack_2d.h b/source/blender/blenlib/BLI_boxpack_2d.h
index 762cb7aaa44..c36cbc03928 100644
--- a/source/blender/blenlib/BLI_boxpack_2d.h
+++ b/source/blender/blenlib/BLI_boxpack_2d.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_BOXPACK_2D_H__
-#define __BLI_BOXPACK_2D_H__
+#pragma once
/** \file
* \ingroup bli
@@ -64,5 +63,3 @@ void BLI_box_pack_2d_fixedarea(struct ListBase *boxes,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_BOXPACK_2D_H__ */
diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h
index d81446af14b..fc348c25c46 100644
--- a/source/blender/blenlib/BLI_buffer.h
+++ b/source/blender/blenlib/BLI_buffer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_BUFFER_H__
-#define __BLI_BUFFER_H__
+#pragma once
/** \file
* \ingroup bli
@@ -100,5 +99,3 @@ void _bli_buffer_free(BLI_Buffer *buffer);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_BUFFER_H__ */
diff --git a/source/blender/blenlib/BLI_color.hh b/source/blender/blenlib/BLI_color.hh
index 37f74edcf4c..c0d2f43645d 100644
--- a/source/blender/blenlib/BLI_color.hh
+++ b/source/blender/blenlib/BLI_color.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_COLOR_HH__
-#define __BLI_COLOR_HH__
+#pragma once
#include <iostream>
@@ -51,6 +50,25 @@ struct Color4f {
stream << "(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")";
return stream;
}
+
+ friend bool operator==(const Color4f &a, const Color4f &b)
+ {
+ return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
+ }
+
+ friend bool operator!=(const Color4f &a, const Color4f &b)
+ {
+ return !(a == b);
+ }
+
+ uint64_t hash() const
+ {
+ uint64_t x1 = *(uint32_t *)&r;
+ uint64_t x2 = *(uint32_t *)&g;
+ uint64_t x3 = *(uint32_t *)&b;
+ uint64_t x4 = *(uint32_t *)&a;
+ return (x1 * 1283591) ^ (x2 * 850177) ^ (x3 * 735391) ^ (x4 * 442319);
+ }
};
struct Color4b {
@@ -89,8 +107,22 @@ struct Color4b {
stream << "(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")";
return stream;
}
+
+ friend bool operator==(const Color4b &a, const Color4b &b)
+ {
+ return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
+ }
+
+ friend bool operator!=(const Color4b &a, const Color4b &b)
+ {
+ return !(a == b);
+ }
+
+ uint64_t hash() const
+ {
+ return ((uint64_t)r * 1283591) ^ ((uint64_t)g * 850177) ^ ((uint64_t)b * 735391) ^
+ ((uint64_t)a * 442319);
+ }
};
} // namespace blender
-
-#endif /* __BLI_COLOR_HH__ */
diff --git a/source/blender/blenlib/BLI_compiler_attrs.h b/source/blender/blenlib/BLI_compiler_attrs.h
index 24da0be122c..680c4bc78da 100644
--- a/source/blender/blenlib/BLI_compiler_attrs.h
+++ b/source/blender/blenlib/BLI_compiler_attrs.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_COMPILER_ATTRS_H__
-#define __BLI_COMPILER_ATTRS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -99,5 +98,3 @@
#else
# define ATTR_ALIGN(x) __attribute__((aligned(x)))
#endif
-
-#endif /* __BLI_COMPILER_ATTRS_H__ */
diff --git a/source/blender/blenlib/BLI_compiler_compat.h b/source/blender/blenlib/BLI_compiler_compat.h
index 056ea1a08c6..0870d01872a 100644
--- a/source/blender/blenlib/BLI_compiler_compat.h
+++ b/source/blender/blenlib/BLI_compiler_compat.h
@@ -19,8 +19,8 @@
/* #define typeof() triggers a bug in some clang-format versions, disable format
* for entire file to keep results consistent. */
-#ifndef __BLI_COMPILER_COMPAT_H__
-#define __BLI_COMPILER_COMPAT_H__
+#pragma once
+
/** \file
* \ingroup bli
@@ -56,4 +56,3 @@ template<typename T> static inline T decltype_helper(T x)
# define BLI_NOINLINE
#endif
-#endif /* __BLI_COMPILER_COMPAT_H__ */
diff --git a/source/blender/blenlib/BLI_compiler_typecheck.h b/source/blender/blenlib/BLI_compiler_typecheck.h
index 0a2eddc4ecc..d9c2bfc1d58 100644
--- a/source/blender/blenlib/BLI_compiler_typecheck.h
+++ b/source/blender/blenlib/BLI_compiler_typecheck.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_COMPILER_TYPECHECK_H__
-#define __BLI_COMPILER_TYPECHECK_H__
+#pragma once
/** \file
* \ingroup bli
@@ -692,5 +691,3 @@
/* clang-format on */
#define GENERIC_TYPE_ANY(...) VA_NARGS_CALL_OVERLOAD(_VA_GENERIC_TYPE_ANY, __VA_ARGS__)
-
-#endif /* __BLI_COMPILER_TYPECHECK_H__ */
diff --git a/source/blender/blenlib/BLI_console.h b/source/blender/blenlib/BLI_console.h
index d666de3a8e8..dc07d3df754 100644
--- a/source/blender/blenlib/BLI_console.h
+++ b/source/blender/blenlib/BLI_console.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_CONSOLE_H__
-#define __BLI_CONSOLE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -40,5 +39,3 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_CONSOLE_H__ */
diff --git a/source/blender/blenlib/BLI_convexhull_2d.h b/source/blender/blenlib/BLI_convexhull_2d.h
index 7417c1e3a98..e930117822f 100644
--- a/source/blender/blenlib/BLI_convexhull_2d.h
+++ b/source/blender/blenlib/BLI_convexhull_2d.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_CONVEXHULL_2D_H__
-#define __BLI_CONVEXHULL_2D_H__
+#pragma once
/** \file
* \ingroup bli
@@ -34,5 +33,3 @@ float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_CONVEXHULL_2D_H__ */
diff --git a/source/blender/blenlib/BLI_delaunay_2d.h b/source/blender/blenlib/BLI_delaunay_2d.h
index 95111dbbbf7..a826a6b2677 100644
--- a/source/blender/blenlib/BLI_delaunay_2d.h
+++ b/source/blender/blenlib/BLI_delaunay_2d.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_DELAUNAY_2D_H__
-#define __BLI_DELAUNAY_2D_H__
+#pragma once
/** \file
* \ingroup bli
@@ -209,5 +208,3 @@ void BLI_delaunay_2d_cdt_free(CDT_result *result);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_DELAUNAY_2D_H__ */
diff --git a/source/blender/blenlib/BLI_dial_2d.h b/source/blender/blenlib/BLI_dial_2d.h
index a39543720e6..fdbc3d4430b 100644
--- a/source/blender/blenlib/BLI_dial_2d.h
+++ b/source/blender/blenlib/BLI_dial_2d.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_DIAL_2D_H__
-#define __BLI_DIAL_2D_H__
+#pragma once
/** \file
* \ingroup bli
@@ -38,7 +37,7 @@
* float angle;
* Dial *dial;
*
- * dial = BLI_dial_initialize(start_position, threshold);
+ * dial = BLI_dial_init(start_position, threshold);
*
* angle = BLI_dial_angle(dial, current_position);
*
@@ -52,12 +51,10 @@ extern "C" {
typedef struct Dial Dial;
-Dial *BLI_dial_initialize(const float start_position[2], float threshold);
+Dial *BLI_dial_init(const float start_position[2], float threshold);
float BLI_dial_angle(Dial *dial, const float current_position[2]);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_DIAL_2D_H__ */
diff --git a/source/blender/blenlib/BLI_disjoint_set.hh b/source/blender/blenlib/BLI_disjoint_set.hh
new file mode 100644
index 00000000000..2002577f956
--- /dev/null
+++ b/source/blender/blenlib/BLI_disjoint_set.hh
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * This implements the disjoint set data structure with path compression and union by rank.
+ */
+
+#include "BLI_array.hh"
+
+namespace blender {
+
+class DisjointSet {
+ private:
+ Array<int64_t> parents_;
+ Array<int64_t> ranks_;
+
+ public:
+ /**
+ * Create a new disjoint set with the given size. Initially, every element is in a separate set.
+ */
+ DisjointSet(int64_t size) : parents_(size), ranks_(size, 0)
+ {
+ BLI_assert(size >= 0);
+ for (int64_t i = 0; i < size; i++) {
+ parents_[i] = i;
+ }
+ }
+
+ /**
+ * Join the sets containing elements x and y. Nothing happens when they have been in the same set
+ * before.
+ */
+ void join(int64_t x, int64_t y)
+ {
+ int64_t root1 = this->find_root(x);
+ int64_t root2 = this->find_root(y);
+
+ /* x and y are in the same set already. */
+ if (root1 == root2) {
+ return;
+ }
+
+ /* Implement union by rank heuristic. */
+ if (ranks_[root1] < ranks_[root2]) {
+ std::swap(root1, root2);
+ }
+ parents_[root2] = root1;
+
+ if (ranks_[root1] == ranks_[root2]) {
+ ranks_[root1]++;
+ }
+ }
+
+ /**
+ * Return true when x and y are in the same set.
+ */
+ bool in_same_set(int64_t x, int64_t y)
+ {
+ int64_t root1 = this->find_root(x);
+ int64_t root2 = this->find_root(y);
+ return root1 == root2;
+ }
+
+ /**
+ * Find the element that represents the set containing x currently.
+ */
+ int64_t find_root(int64_t x)
+ {
+ /* Find root by following parents. */
+ int64_t root = x;
+ while (parents_[root] != root) {
+ root = parents_[root];
+ }
+
+ /* Compress path. */
+ while (parents_[x] != root) {
+ int64_t parent = parents_[x];
+ parents_[x] = root;
+ x = parent;
+ }
+
+ return root;
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_dlrbTree.h b/source/blender/blenlib/BLI_dlrbTree.h
index 5db0dd16a34..fc52904d699 100644
--- a/source/blender/blenlib/BLI_dlrbTree.h
+++ b/source/blender/blenlib/BLI_dlrbTree.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_DLRBTREE_H__
-#define __BLI_DLRBTREE_H__
+#pragma once
/** \file
* \ingroup bli
@@ -166,5 +165,3 @@ void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_DLRBTREE_H__ */
diff --git a/source/blender/blenlib/BLI_dot_export.hh b/source/blender/blenlib/BLI_dot_export.hh
index 450cb2ef58c..a026a85dd62 100644
--- a/source/blender/blenlib/BLI_dot_export.hh
+++ b/source/blender/blenlib/BLI_dot_export.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_DOT_EXPORT_HH__
-#define __BLI_DOT_EXPORT_HH__
+#pragma once
/**
* Language grammar: https://www.graphviz.org/doc/info/lang.html
@@ -44,9 +43,8 @@ class NodePort;
class DirectedEdge;
class UndirectedEdge;
class Cluster;
-class AttributeList;
-class AttributeList {
+class Attributes {
private:
Map<std::string, std::string> attributes_;
@@ -57,11 +55,15 @@ class AttributeList {
{
attributes_.add_overwrite(key, value);
}
+
+ void set(StringRef key, float value)
+ {
+ attributes_.add_overwrite(key, std::to_string(value));
+ }
};
class Graph {
private:
- AttributeList attributes_;
Vector<std::unique_ptr<Node>> nodes_;
Vector<std::unique_ptr<Cluster>> clusters_;
@@ -72,19 +74,17 @@ class Graph {
friend Node;
public:
+ Attributes attributes;
+
+ public:
Node &new_node(StringRef label);
Cluster &new_cluster(StringRef label = "");
void export__declare_nodes_and_clusters(std::stringstream &ss) const;
- void set_attribute(StringRef key, StringRef value)
- {
- attributes_.set(key, value);
- }
-
void set_rankdir(Attr_rankdir rankdir)
{
- this->set_attribute("rankdir", rankdir_to_string(rankdir));
+ attributes.set("rankdir", rankdir_to_string(rankdir));
}
void set_random_cluster_bgcolors();
@@ -92,7 +92,6 @@ class Graph {
class Cluster {
private:
- AttributeList attributes_;
Graph &graph_;
Cluster *parent_ = nullptr;
Set<Cluster *> children_;
@@ -101,6 +100,9 @@ class Cluster {
friend Graph;
friend Node;
+ public:
+ Attributes attributes;
+
Cluster(Graph &graph) : graph_(graph)
{
}
@@ -108,9 +110,9 @@ class Cluster {
public:
void export__declare_nodes_and_clusters(std::stringstream &ss) const;
- void set_attribute(StringRef key, StringRef value)
+ std::string name() const
{
- attributes_.set(key, value);
+ return "cluster_" + std::to_string((uintptr_t)this);
}
void set_parent_cluster(Cluster *cluster);
@@ -119,53 +121,52 @@ class Cluster {
this->set_parent_cluster(&cluster);
}
+ Cluster *parent_cluster()
+ {
+ return parent_;
+ }
+
void set_random_cluster_bgcolors();
+
+ bool contains(Node &node) const;
};
class Node {
private:
- AttributeList attributes_;
Graph &graph_;
Cluster *cluster_ = nullptr;
friend Graph;
- Node(Graph &graph) : graph_(graph)
- {
- }
-
public:
- const AttributeList &attributes() const
- {
- return attributes_;
- }
+ Attributes attributes;
- AttributeList &attributes()
+ Node(Graph &graph) : graph_(graph)
{
- return attributes_;
}
+ public:
void set_parent_cluster(Cluster *cluster);
void set_parent_cluster(Cluster &cluster)
{
this->set_parent_cluster(&cluster);
}
- void set_attribute(StringRef key, StringRef value)
+ Cluster *parent_cluster()
{
- attributes_.set(key, value);
+ return cluster_;
}
void set_shape(Attr_shape shape)
{
- this->set_attribute("shape", shape_to_string(shape));
+ attributes.set("shape", shape_to_string(shape));
}
/* See https://www.graphviz.org/doc/info/attrs.html#k:color. */
void set_background_color(StringRef name)
{
- this->set_attribute("fillcolor", name);
- this->set_attribute("style", "filled");
+ attributes.set("fillcolor", name);
+ attributes.set("style", "filled");
}
void export__as_id(std::stringstream &ss) const;
@@ -209,33 +210,35 @@ class NodePort {
class Edge : blender::NonCopyable, blender::NonMovable {
protected:
- AttributeList attributes_;
NodePort a_;
NodePort b_;
public:
- Edge(NodePort a, NodePort b) : a_(std::move(a)), b_(std::move(b))
- {
- }
+ Attributes attributes;
- void set_attribute(StringRef key, StringRef value)
+ public:
+ Edge(NodePort a, NodePort b) : a_(std::move(a)), b_(std::move(b))
{
- attributes_.set(key, value);
}
void set_arrowhead(Attr_arrowType type)
{
- this->set_attribute("arrowhead", arrowType_to_string(type));
+ attributes.set("arrowhead", arrowType_to_string(type));
}
void set_arrowtail(Attr_arrowType type)
{
- this->set_attribute("arrowtail", arrowType_to_string(type));
+ attributes.set("arrowtail", arrowType_to_string(type));
}
void set_dir(Attr_dirType type)
{
- this->set_attribute("dir", dirType_to_string(type));
+ attributes.set("dir", dirType_to_string(type));
+ }
+
+ void set_label(StringRef label)
+ {
+ attributes.set("label", label);
}
};
@@ -269,13 +272,18 @@ class NodeWithSocketsRef {
Span<std::string> input_names,
Span<std::string> output_names);
- NodePort input(uint index) const
+ Node &node()
+ {
+ return *node_;
+ }
+
+ NodePort input(int index) const
{
std::string port = "\"in" + std::to_string(index) + "\"";
return NodePort(*node_, port);
}
- NodePort output(uint index) const
+ NodePort output(int index) const
{
std::string port = "\"out" + std::to_string(index) + "\"";
return NodePort(*node_, port);
@@ -283,5 +291,3 @@ class NodeWithSocketsRef {
};
} // namespace blender::dot
-
-#endif /* __BLI_DOT_EXPORT_HH__ */
diff --git a/source/blender/blenlib/BLI_dot_export_attribute_enums.hh b/source/blender/blenlib/BLI_dot_export_attribute_enums.hh
index 94c7025b2a6..8cbe7a3e6e6 100644
--- a/source/blender/blenlib/BLI_dot_export_attribute_enums.hh
+++ b/source/blender/blenlib/BLI_dot_export_attribute_enums.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_DOT_EXPORT_ATTRIBUTE_ENUMS_HH__
-#define __BLI_DOT_EXPORT_ATTRIBUTE_ENUMS_HH__
+#pragma once
#include "BLI_string_ref.hh"
@@ -119,5 +118,3 @@ inline StringRef dirType_to_string(Attr_dirType value)
}
} // namespace blender::dot
-
-#endif /* __BLI_DOT_EXPORT_ATTRIBUTE_ENUMS_HH__ */
diff --git a/source/blender/blenlib/BLI_dynlib.h b/source/blender/blenlib/BLI_dynlib.h
index 4adffd51e17..628e33b6f02 100644
--- a/source/blender/blenlib/BLI_dynlib.h
+++ b/source/blender/blenlib/BLI_dynlib.h
@@ -21,8 +21,7 @@
* \ingroup bli
*/
-#ifndef __BLI_DYNLIB_H__
-#define __BLI_DYNLIB_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -38,5 +37,3 @@ void BLI_dynlib_close(DynamicLibrary *lib);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_DYNLIB_H__ */
diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h
index cb1f3d58f23..075786c4424 100644
--- a/source/blender/blenlib/BLI_dynstr.h
+++ b/source/blender/blenlib/BLI_dynstr.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_DYNSTR_H__
-#define __BLI_DYNSTR_H__
+#pragma once
/** \file
* \ingroup bli
@@ -64,5 +63,3 @@ void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL();
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_DYNSTR_H__ */
diff --git a/source/blender/blenlib/BLI_easing.h b/source/blender/blenlib/BLI_easing.h
index 73e17be31b7..e6bf8c3bdfa 100644
--- a/source/blender/blenlib/BLI_easing.h
+++ b/source/blender/blenlib/BLI_easing.h
@@ -28,8 +28,7 @@
* All rights reserved.
*/
-#ifndef __BLI_EASING_H__
-#define __BLI_EASING_H__
+#pragma once
/** \file
* \ingroup bli
@@ -80,5 +79,3 @@ float BLI_easing_sine_ease_in_out(float time, float begin, float change, float d
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_EASING_H__ */
diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h
index 0e2d0b538c7..44dc3cf096b 100644
--- a/source/blender/blenlib/BLI_edgehash.h
+++ b/source/blender/blenlib/BLI_edgehash.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_EDGEHASH_H__
-#define __BLI_EDGEHASH_H__
+#pragma once
/** \file
* \ingroup bli
@@ -158,5 +157,3 @@ BLI_INLINE bool BLI_edgesetIterator_isDone(EdgeSetIterator *esi)
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_EDGEHASH_H__ */
diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h
index 316e24cfc6d..70d428147e2 100644
--- a/source/blender/blenlib/BLI_endian_switch_inline.h
+++ b/source/blender/blenlib/BLI_endian_switch_inline.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ENDIAN_SWITCH_INLINE_H__
-#define __BLI_ENDIAN_SWITCH_INLINE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -92,5 +91,3 @@ BLI_INLINE void BLI_endian_switch_double(double *val)
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_ENDIAN_SWITCH_INLINE_H__ */
diff --git a/source/blender/blenlib/BLI_expr_pylike_eval.h b/source/blender/blenlib/BLI_expr_pylike_eval.h
index 1db91ea4205..c074b5d8130 100644
--- a/source/blender/blenlib/BLI_expr_pylike_eval.h
+++ b/source/blender/blenlib/BLI_expr_pylike_eval.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_EXPR_PYLIKE_EVAL_H__
-#define __BLI_EXPR_PYLIKE_EVAL_H__
+#pragma once
/** \file
* \ingroup bli
@@ -57,5 +56,3 @@ eExprPyLike_EvalStatus BLI_expr_pylike_eval(struct ExprPyLike_Parsed *expr,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_EXPR_PYLIKE_EVAL_H__ */
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index fe4600b9121..e61e20ee5e9 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -22,8 +22,7 @@
* \brief File and directory operations.
* */
-#ifndef __BLI_FILEOPS_H__
-#define __BLI_FILEOPS_H__
+#pragma once
#include <stdint.h>
#include <stdio.h>
@@ -189,5 +188,3 @@ void BLI_get_short_name(char short_name[256], const char *filename);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_FILEOPS_H__ */
diff --git a/source/blender/blenlib/BLI_fileops_types.h b/source/blender/blenlib/BLI_fileops_types.h
index 41f916ed0ca..cdae9665f98 100644
--- a/source/blender/blenlib/BLI_fileops_types.h
+++ b/source/blender/blenlib/BLI_fileops_types.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_FILEOPS_TYPES_H__
-#define __BLI_FILEOPS_TYPES_H__
+#pragma once
/** \file
* \ingroup bli
@@ -64,5 +63,3 @@ struct dirlink {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_FILEOPS_TYPES_H__ */
diff --git a/source/blender/blenlib/BLI_float2.hh b/source/blender/blenlib/BLI_float2.hh
index 94da5d18ad2..e55a8de4633 100644
--- a/source/blender/blenlib/BLI_float2.hh
+++ b/source/blender/blenlib/BLI_float2.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_FLOAT2_HH__
-#define __BLI_FLOAT2_HH__
+#pragma once
#include "BLI_float3.hh"
@@ -48,6 +47,34 @@ struct float2 {
return &x;
}
+ float2 &operator+=(const float2 &other)
+ {
+ x += other.x;
+ y += other.y;
+ return *this;
+ }
+
+ float2 &operator-=(const float2 &other)
+ {
+ x -= other.x;
+ y -= other.y;
+ return *this;
+ }
+
+ float2 &operator*=(float factor)
+ {
+ x *= factor;
+ y *= factor;
+ return *this;
+ }
+
+ float2 &operator/=(float divisor)
+ {
+ x /= divisor;
+ y /= divisor;
+ return *this;
+ }
+
friend float2 operator+(const float2 &a, const float2 &b)
{
return {a.x + b.x, a.y + b.y};
@@ -79,8 +106,16 @@ struct float2 {
stream << "(" << v.x << ", " << v.y << ")";
return stream;
}
+
+ friend bool operator==(const float2 &a, const float2 &b)
+ {
+ return a.x == b.x && a.y == b.y;
+ }
+
+ friend bool operator!=(const float2 &a, const float2 &b)
+ {
+ return !(a == b);
+ }
};
} // namespace blender
-
-#endif /* __BLI_FLOAT2_HH__ */
diff --git a/source/blender/blenlib/BLI_float3.hh b/source/blender/blenlib/BLI_float3.hh
index 0edee600ef6..a976e909738 100644
--- a/source/blender/blenlib/BLI_float3.hh
+++ b/source/blender/blenlib/BLI_float3.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_FLOAT3_HH__
-#define __BLI_FLOAT3_HH__
+#pragma once
#include <iostream>
@@ -63,11 +62,12 @@ struct float3 {
return {a.x + b.x, a.y + b.y, a.z + b.z};
}
- void operator+=(const float3 &b)
+ float3 &operator+=(const float3 &b)
{
this->x += b.x;
this->y += b.y;
this->z += b.z;
+ return *this;
}
friend float3 operator-(const float3 &a, const float3 &b)
@@ -80,25 +80,28 @@ struct float3 {
return {-a.x, -a.y, -a.z};
}
- void operator-=(const float3 &b)
+ float3 &operator-=(const float3 &b)
{
this->x -= b.x;
this->y -= b.y;
this->z -= b.z;
+ return *this;
}
- void operator*=(float scalar)
+ float3 &operator*=(float scalar)
{
this->x *= scalar;
this->y *= scalar;
this->z *= scalar;
+ return *this;
}
- void operator*=(const float3 &other)
+ float3 &operator*=(const float3 &other)
{
this->x *= other.x;
this->y *= other.y;
this->z *= other.z;
+ return *this;
}
friend float3 operator*(const float3 &a, const float3 &b)
@@ -128,11 +131,32 @@ struct float3 {
return stream;
}
+ friend bool operator==(const float3 &a, const float3 &b)
+ {
+ return a.x == b.x && a.y == b.y && a.z == b.z;
+ }
+
+ friend bool operator!=(const float3 &a, const float3 &b)
+ {
+ return !(a == b);
+ }
+
float normalize_and_get_length()
{
return normalize_v3(*this);
}
+ /**
+ * Normalizes the vector in place.
+ */
+ void normalize()
+ {
+ normalize_v3(*this);
+ }
+
+ /**
+ * Returns a normalized vector. The original vector is not changed.
+ */
float3 normalized() const
{
float3 result;
@@ -178,6 +202,14 @@ struct float3 {
z = -z;
}
+ uint64_t hash() const
+ {
+ uint64_t x1 = *(uint32_t *)&x;
+ uint64_t x2 = *(uint32_t *)&y;
+ uint64_t x3 = *(uint32_t *)&z;
+ return (x1 * 435109) ^ (x2 * 380867) ^ (x3 * 1059217);
+ }
+
static float dot(const float3 &a, const float3 &b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
@@ -214,5 +246,3 @@ struct float3 {
};
} // namespace blender
-
-#endif /* __BLI_FLOAT3_HH__ */
diff --git a/source/blender/blenlib/BLI_float4x4.hh b/source/blender/blenlib/BLI_float4x4.hh
index 1e9bd12b12b..85d38149bb9 100644
--- a/source/blender/blenlib/BLI_float4x4.hh
+++ b/source/blender/blenlib/BLI_float4x4.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_FLOAT4X4_HH__
-#define __BLI_FLOAT4X4_HH__
+#pragma once
#include "BLI_float3.hh"
#include "BLI_math_matrix.h"
@@ -71,8 +70,8 @@ struct float4x4 {
float4x4 inverted() const
{
- float result[4][4];
- invert_m4_m4(result, values);
+ float4x4 result;
+ invert_m4_m4(result.values, values);
return result;
}
@@ -86,6 +85,18 @@ struct float4x4 {
return this->inverted();
}
+ float4x4 transposed() const
+ {
+ float4x4 result;
+ transpose_m4_m4(result.values, values);
+ return result;
+ }
+
+ float4x4 inverted_transposed_affine() const
+ {
+ return this->inverted_affine().transposed();
+ }
+
struct float3x3_ref {
const float4x4 &data;
@@ -108,8 +119,16 @@ struct float4x4 {
interp_m4_m4m4(result, a.values, b.values, t);
return result;
}
+
+ uint64_t hash() const
+ {
+ uint64_t h = 435109;
+ for (int i = 0; i < 16; i++) {
+ float value = ((const float *)this)[i];
+ h = h * 33 + (*(uint32_t *)&value);
+ }
+ return h;
+ }
};
} // namespace blender
-
-#endif /* __BLI_FLOAT4X4_HH__ */
diff --git a/source/blender/blenlib/BLI_fnmatch.h b/source/blender/blenlib/BLI_fnmatch.h
index 28169c36e23..d09a14621d8 100644
--- a/source/blender/blenlib/BLI_fnmatch.h
+++ b/source/blender/blenlib/BLI_fnmatch.h
@@ -19,8 +19,7 @@
* Bugs can be reported to bug-glibc@prep.ai.mit.edu.
*/
-#ifndef __BLI_FNMATCH_H__
-#define __BLI_FNMATCH_H__
+#pragma once
/** \file
* \ingroup bli
@@ -77,5 +76,3 @@ extern int fnmatch __P((const char *__pattern, const char *__string, int __flags
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_FNMATCH_H__ */
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 141c631381b..cd84dd4f327 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_GHASH_H__
-#define __BLI_GHASH_H__
+#pragma once
/** \file
* \ingroup bli
@@ -371,20 +370,6 @@ unsigned int BLI_ghashutil_uinthash_v4_murmur(const unsigned int key[4]);
bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b);
#define BLI_ghashutil_inthash_v4_cmp BLI_ghashutil_uinthash_v4_cmp
-unsigned int BLI_ghashutil_uinthash_v2(const unsigned int key[2]);
-#define BLI_ghashutil_inthash_v2(key) \
- (CHECK_TYPE_ANY(key, int *, const int *), BLI_ghashutil_uinthash_v2((const unsigned int *)key))
-#define BLI_ghashutil_inthash_v2_p ((GSetHashFP)BLI_ghashutil_uinthash_v2)
-#define BLI_ghashutil_uinthash_v2_p ((GSetHashFP)BLI_ghashutil_uinthash_v2)
-unsigned int BLI_ghashutil_uinthash_v2_murmur(const unsigned int key[2]);
-#define BLI_ghashutil_inthash_v2_murmur(key) \
- (CHECK_TYPE_ANY(key, int *, const int *), \
- BLI_ghashutil_uinthash_v2_murmur((const unsigned int *)key))
-#define BLI_ghashutil_inthash_v2_p_murmur ((GSetHashFP)BLI_ghashutil_uinthash_v2_murmur)
-#define BLI_ghashutil_uinthash_v2_p_murmur ((GSetHashFP)BLI_ghashutil_uinthash_v2_murmur)
-bool BLI_ghashutil_uinthash_v2_cmp(const void *a, const void *b);
-#define BLI_ghashutil_inthash_v2_cmp BLI_ghashutil_uinthash_v2_cmp
-
typedef struct GHashPair {
const void *first;
const void *second;
@@ -430,5 +415,3 @@ GSet *BLI_gset_int_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_GHASH_H__ */
diff --git a/source/blender/blenlib/BLI_gsqueue.h b/source/blender/blenlib/BLI_gsqueue.h
index b69bdb7057c..077d1646d1d 100644
--- a/source/blender/blenlib/BLI_gsqueue.h
+++ b/source/blender/blenlib/BLI_gsqueue.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_GSQUEUE_H__
-#define __BLI_GSQUEUE_H__
+#pragma once
/** \file
* \ingroup bli
@@ -42,5 +41,3 @@ void BLI_gsqueue_free(GSQueue *gq);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_GSQUEUE_H__ */
diff --git a/source/blender/blenlib/BLI_hash.h b/source/blender/blenlib/BLI_hash.h
index 96111ffaf5a..c2be416ef5f 100644
--- a/source/blender/blenlib/BLI_hash.h
+++ b/source/blender/blenlib/BLI_hash.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_HASH_H__
-#define __BLI_HASH_H__
+#pragma once
/** \file
* \ingroup bli
@@ -91,5 +90,3 @@ BLI_INLINE void BLI_hash_pointer_to_color(const void *ptr, int *r, int *g, int *
#ifdef __cplusplus
}
#endif
-
-#endif // __BLI_HASH_H__
diff --git a/source/blender/blenlib/BLI_hash.hh b/source/blender/blenlib/BLI_hash.hh
index 49e619ff1bc..ad3224e037a 100644
--- a/source/blender/blenlib/BLI_hash.hh
+++ b/source/blender/blenlib/BLI_hash.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_HASH_HH__
-#define __BLI_HASH_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -38,7 +37,7 @@
* multiple `operator()` in a specialization of #DefaultHash. All those methods have to compute the
* same hash for values that compare equal.
*
- * The computed hash is an unsigned 32 bit integer. Ideally, the hash function would generate
+ * The computed hash is an unsigned 64 bit integer. Ideally, the hash function would generate
* uniformly random hash values for a set of keys. However, in many cases trivial hash functions
* are faster and produce a good enough distribution. In general it is better when more information
* is in the lower bits of the hash. By choosing a good probing strategy, the effects of a bad hash
@@ -49,7 +48,7 @@
* There are three main ways to provide a hash table implementation with a custom hash function.
*
* - When you want to provide a default hash function for your own custom type: Add a `hash`
- * member function to it. The function should return `uint32_t` and take no arguments. This
+ * member function to it. The function should return `uint64_t` and take no arguments. This
* method will be called by the default implementation of #DefaultHash. It will automatically be
* used by hash table implementations.
*
@@ -58,7 +57,7 @@
* either global or BLI namespace.
*
* template<> struct blender::DefaultHash<TheType> {
- * uint32_t operator()(const TheType &value) const {
+ * uint64_t operator()(const TheType &value) const {
* return ...;
* }
* };
@@ -68,7 +67,7 @@
* table explicitly.
*
* struct MyCustomHash {
- * uint32_t operator()(const TheType &value) const {
+ * uint64_t operator()(const TheType &value) const {
* return ...;
* }
* };
@@ -91,7 +90,7 @@ namespace blender {
* that you have to implement a hash function using one of three strategies listed above.
*/
template<typename T> struct DefaultHash {
- uint32_t operator()(const T &value) const
+ uint64_t operator()(const T &value) const
{
return value.hash();
}
@@ -101,7 +100,7 @@ template<typename T> struct DefaultHash {
* Use the same hash function for const and non const variants of a type.
*/
template<typename T> struct DefaultHash<const T> {
- uint32_t operator()(const T &value) const
+ uint64_t operator()(const T &value) const
{
return DefaultHash<T>{}(value);
}
@@ -109,9 +108,9 @@ template<typename T> struct DefaultHash<const T> {
#define TRIVIAL_DEFAULT_INT_HASH(TYPE) \
template<> struct DefaultHash<TYPE> { \
- uint32_t operator()(TYPE value) const \
+ uint64_t operator()(TYPE value) const \
{ \
- return (uint32_t)value; \
+ return (uint64_t)value; \
} \
}
@@ -127,36 +126,29 @@ TRIVIAL_DEFAULT_INT_HASH(int16_t);
TRIVIAL_DEFAULT_INT_HASH(uint16_t);
TRIVIAL_DEFAULT_INT_HASH(int32_t);
TRIVIAL_DEFAULT_INT_HASH(uint32_t);
-
-template<> struct DefaultHash<uint64_t> {
- uint32_t operator()(uint64_t value) const
- {
- uint32_t low = (uint32_t)value;
- uint32_t high = (uint32_t)(value >> 32);
- return low ^ (high * 0x45d9f3b);
- }
-};
-
-template<> struct DefaultHash<int64_t> {
- uint32_t operator()(uint64_t value) const
- {
- return DefaultHash<uint64_t>{}((uint64_t)value);
- }
-};
+TRIVIAL_DEFAULT_INT_HASH(int64_t);
+TRIVIAL_DEFAULT_INT_HASH(uint64_t);
/**
* One should try to avoid using floats as keys in hash tables, but sometimes it is convenient.
*/
template<> struct DefaultHash<float> {
- uint32_t operator()(float value) const
+ uint64_t operator()(float value) const
{
return *(uint32_t *)&value;
}
};
-inline uint32_t hash_string(StringRef str)
+template<> struct DefaultHash<bool> {
+ uint64_t operator()(bool value) const
+ {
+ return (uint64_t)(value != false) * 1298191;
+ }
+};
+
+inline uint64_t hash_string(StringRef str)
{
- uint32_t hash = 5381;
+ uint64_t hash = 5381;
for (char c : str) {
hash = hash * 33 + c;
}
@@ -168,21 +160,21 @@ template<> struct DefaultHash<std::string> {
* Take a #StringRef as parameter to support heterogeneous lookups in hash table implementations
* when std::string is used as key.
*/
- uint32_t operator()(StringRef value) const
+ uint64_t operator()(StringRef value) const
{
return hash_string(value);
}
};
template<> struct DefaultHash<StringRef> {
- uint32_t operator()(StringRef value) const
+ uint64_t operator()(StringRef value) const
{
return hash_string(value);
}
};
template<> struct DefaultHash<StringRefNull> {
- uint32_t operator()(StringRef value) const
+ uint64_t operator()(StringRef value) const
{
return hash_string(value);
}
@@ -192,30 +184,28 @@ template<> struct DefaultHash<StringRefNull> {
* While we cannot guarantee that the lower 4 bits of a pointer are zero, it is often the case.
*/
template<typename T> struct DefaultHash<T *> {
- uint32_t operator()(const T *value) const
+ uint64_t operator()(const T *value) const
{
uintptr_t ptr = (uintptr_t)value;
- uint32_t hash = (uint32_t)(ptr >> 4);
+ uint64_t hash = (uint64_t)(ptr >> 4);
return hash;
}
};
template<typename T> struct DefaultHash<std::unique_ptr<T>> {
- uint32_t operator()(const std::unique_ptr<T> &value) const
+ uint64_t operator()(const std::unique_ptr<T> &value) const
{
return DefaultHash<T *>{}(value.get());
}
};
template<typename T1, typename T2> struct DefaultHash<std::pair<T1, T2>> {
- uint32_t operator()(const std::pair<T1, T2> &value) const
+ uint64_t operator()(const std::pair<T1, T2> &value) const
{
- uint32_t hash1 = DefaultHash<T1>{}(value.first);
- uint32_t hash2 = DefaultHash<T2>{}(value.second);
+ uint64_t hash1 = DefaultHash<T1>{}(value.first);
+ uint64_t hash2 = DefaultHash<T2>{}(value.second);
return hash1 ^ (hash2 * 33);
}
};
} // namespace blender
-
-#endif /* __BLI_HASH_HH__ */
diff --git a/source/blender/blenlib/BLI_hash_md5.h b/source/blender/blenlib/BLI_hash_md5.h
index b326b17c19b..4a5cd8b19f3 100644
--- a/source/blender/blenlib/BLI_hash_md5.h
+++ b/source/blender/blenlib/BLI_hash_md5.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_HASH_MD5_H__
-#define __BLI_HASH_MD5_H__
+#pragma once
/** \file
* \ingroup bli
@@ -43,5 +42,3 @@ char *BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33]);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_HASH_MD5_H__ */
diff --git a/source/blender/blenlib/BLI_hash_mm2a.h b/source/blender/blenlib/BLI_hash_mm2a.h
index 840ff31dd19..193a78e6293 100644
--- a/source/blender/blenlib/BLI_hash_mm2a.h
+++ b/source/blender/blenlib/BLI_hash_mm2a.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_HASH_MM2A_H__
-#define __BLI_HASH_MM2A_H__
+#pragma once
/** \file
* \ingroup bli
@@ -47,5 +46,3 @@ uint32_t BLI_hash_mm2(const unsigned char *data, size_t len, uint32_t seed);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_HASH_MM2A_H__ */
diff --git a/source/blender/blenlib/BLI_hash_mm3.h b/source/blender/blenlib/BLI_hash_mm3.h
index e76808812bc..99c24f53dd4 100644
--- a/source/blender/blenlib/BLI_hash_mm3.h
+++ b/source/blender/blenlib/BLI_hash_mm3.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_HASH_MM3_H__
-#define __BLI_HASH_MM3_H__
+#pragma once
/** \file
* \ingroup bli
@@ -32,5 +31,3 @@ uint32_t BLI_hash_mm3(const unsigned char *data, size_t len, uint32_t seed);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_HASH_MM2A_H__ */
diff --git a/source/blender/blenlib/BLI_hash_tables.hh b/source/blender/blenlib/BLI_hash_tables.hh
index 5f9e06c5a64..e6026d93e2c 100644
--- a/source/blender/blenlib/BLI_hash_tables.hh
+++ b/source/blender/blenlib/BLI_hash_tables.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_OPEN_ADDRESSING_HH__
-#define __BLI_OPEN_ADDRESSING_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -42,59 +41,64 @@ namespace blender {
* Those should eventually be de-duplicated with functions in BLI_math_base.h.
* \{ */
-inline constexpr int is_power_of_2_i_constexpr(const int n)
+inline constexpr int64_t is_power_of_2_constexpr(const int64_t x)
{
- return (n & (n - 1)) == 0;
+ BLI_assert(x >= 0);
+ return (x & (x - 1)) == 0;
}
-inline constexpr uint32_t log2_floor_u_constexpr(const uint32_t x)
+inline constexpr int64_t log2_floor_constexpr(const int64_t x)
{
- return x <= 1 ? 0 : 1 + log2_floor_u_constexpr(x >> 1);
+ BLI_assert(x >= 0);
+ return x <= 1 ? 0 : 1 + log2_floor_constexpr(x >> 1);
}
-inline constexpr uint32_t log2_ceil_u_constexpr(const uint32_t x)
+inline constexpr int64_t log2_ceil_constexpr(const int64_t x)
{
- return (is_power_of_2_i_constexpr((int)x)) ? log2_floor_u_constexpr(x) :
- log2_floor_u_constexpr(x) + 1;
+ BLI_assert(x >= 0);
+ return (is_power_of_2_constexpr((int)x)) ? log2_floor_constexpr(x) : log2_floor_constexpr(x) + 1;
}
-inline constexpr uint32_t power_of_2_max_u_constexpr(const uint32_t x)
+inline constexpr int64_t power_of_2_max_constexpr(const int64_t x)
{
- return 1u << log2_ceil_u_constexpr(x);
+ BLI_assert(x >= 0);
+ return 1ll << log2_ceil_constexpr(x);
}
template<typename IntT> inline constexpr IntT ceil_division(const IntT x, const IntT y)
{
- BLI_STATIC_ASSERT(!std::is_signed<IntT>::value, "");
+ BLI_assert(x >= 0);
+ BLI_assert(y >= 0);
return x / y + ((x % y) != 0);
}
template<typename IntT> inline constexpr IntT floor_division(const IntT x, const IntT y)
{
- BLI_STATIC_ASSERT(!std::is_signed<IntT>::value, "");
+ BLI_assert(x >= 0);
+ BLI_assert(y >= 0);
return x / y;
}
-inline constexpr uint32_t ceil_division_by_fraction(const uint32_t x,
- const uint32_t numerator,
- const uint32_t denominator)
+inline constexpr int64_t ceil_division_by_fraction(const int64_t x,
+ const int64_t numerator,
+ const int64_t denominator)
{
- return (uint32_t)ceil_division((uint64_t)x * (uint64_t)denominator, (uint64_t)numerator);
+ return (int64_t)ceil_division((uint64_t)x * (uint64_t)denominator, (uint64_t)numerator);
}
-inline constexpr uint32_t floor_multiplication_with_fraction(const uint32_t x,
- const uint32_t numerator,
- const uint32_t denominator)
+inline constexpr int64_t floor_multiplication_with_fraction(const int64_t x,
+ const int64_t numerator,
+ const int64_t denominator)
{
- return (uint32_t)((uint64_t)x * (uint64_t)numerator / (uint64_t)denominator);
+ return (int64_t)((uint64_t)x * (uint64_t)numerator / (uint64_t)denominator);
}
-inline constexpr uint32_t total_slot_amount_for_usable_slots(
- const uint32_t min_usable_slots,
- const uint32_t max_load_factor_numerator,
- const uint32_t max_load_factor_denominator)
+inline constexpr int64_t total_slot_amount_for_usable_slots(
+ const int64_t min_usable_slots,
+ const int64_t max_load_factor_numerator,
+ const int64_t max_load_factor_denominator)
{
- return power_of_2_max_u_constexpr(ceil_division_by_fraction(
+ return power_of_2_max_constexpr(ceil_division_by_fraction(
min_usable_slots, max_load_factor_numerator, max_load_factor_denominator));
}
@@ -121,16 +125,16 @@ class LoadFactor {
BLI_assert(numerator < denominator);
}
- void compute_total_and_usable_slots(uint32_t min_total_slots,
- uint32_t min_usable_slots,
- uint32_t *r_total_slots,
- uint32_t *r_usable_slots) const
+ void compute_total_and_usable_slots(int64_t min_total_slots,
+ int64_t min_usable_slots,
+ int64_t *r_total_slots,
+ int64_t *r_usable_slots) const
{
BLI_assert(is_power_of_2_i((int)min_total_slots));
- uint32_t total_slots = this->compute_total_slots(min_usable_slots, numerator_, denominator_);
+ int64_t total_slots = this->compute_total_slots(min_usable_slots, numerator_, denominator_);
total_slots = std::max(total_slots, min_total_slots);
- const uint32_t usable_slots = floor_multiplication_with_fraction(
+ const int64_t usable_slots = floor_multiplication_with_fraction(
total_slots, numerator_, denominator_);
BLI_assert(min_usable_slots <= usable_slots);
@@ -138,9 +142,9 @@ class LoadFactor {
*r_usable_slots = usable_slots;
}
- static constexpr uint32_t compute_total_slots(uint32_t min_usable_slots,
- uint8_t numerator,
- uint8_t denominator)
+ static constexpr int64_t compute_total_slots(int64_t min_usable_slots,
+ uint8_t numerator,
+ uint8_t denominator)
{
return total_slot_amount_for_usable_slots(min_usable_slots, numerator, denominator);
}
@@ -262,27 +266,27 @@ template<typename Pointer> struct PointerKeyInfo {
class HashTableStats {
private:
- Vector<uint32_t> keys_by_collision_count_;
- uint32_t total_collisions_;
+ Vector<int64_t> keys_by_collision_count_;
+ int64_t total_collisions_;
float average_collisions_;
- uint32_t size_;
- uint32_t capacity_;
- uint32_t removed_amount_;
+ int64_t size_;
+ int64_t capacity_;
+ int64_t removed_amount_;
float load_factor_;
float removed_load_factor_;
- uint32_t size_per_element_;
- uint32_t size_in_bytes_;
+ int64_t size_per_element_;
+ int64_t size_in_bytes_;
const void *address_;
public:
/**
* Requires that the hash table has the following methods:
- * - count_collisions(key) -> uint32_t
- * - size() -> uint32_t
- * - capacity() -> uint32_t
- * - removed_amount() -> uint32_t
- * - size_per_element() -> uint32_t
- * - size_in_bytes() -> uint32_t
+ * - count_collisions(key) -> int64_t
+ * - size() -> int64_t
+ * - capacity() -> int64_t
+ * - removed_amount() -> int64_t
+ * - size_per_element() -> int64_t
+ * - size_in_bytes() -> int64_t
*/
template<typename HashTable, typename Keys>
HashTableStats(const HashTable &hash_table, const Keys &keys)
@@ -296,7 +300,7 @@ class HashTableStats {
address_ = (const void *)&hash_table;
for (const auto &key : keys) {
- uint32_t collisions = hash_table.count_collisions(key);
+ int64_t collisions = hash_table.count_collisions(key);
if (keys_by_collision_count_.size() <= collisions) {
keys_by_collision_count_.append_n_times(0,
collisions - keys_by_collision_count_.size() + 1);
@@ -325,7 +329,7 @@ class HashTableStats {
std::cout << " Size per Slot: " << size_per_element_ << " bytes\n";
std::cout << " Average Collisions: " << average_collisions_ << "\n";
- for (uint32_t collision_count : keys_by_collision_count_.index_range()) {
+ for (int64_t collision_count : keys_by_collision_count_.index_range()) {
std::cout << " " << collision_count
<< " Collisions: " << keys_by_collision_count_[collision_count] << "\n";
}
@@ -348,5 +352,3 @@ struct DefaultEquality {
};
} // namespace blender
-
-#endif /* __BLI_OPEN_ADDRESSING_HH__ */
diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h
index ca5edcbead5..4cfb7945303 100644
--- a/source/blender/blenlib/BLI_heap.h
+++ b/source/blender/blenlib/BLI_heap.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_HEAP_H__
-#define __BLI_HEAP_H__
+#pragma once
/** \file
* \ingroup bli
@@ -61,5 +60,3 @@ bool BLI_heap_is_valid(const Heap *heap);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_HEAP_H__ */
diff --git a/source/blender/blenlib/BLI_heap_simple.h b/source/blender/blenlib/BLI_heap_simple.h
index d2bc542491c..b2a1b5582e5 100644
--- a/source/blender/blenlib/BLI_heap_simple.h
+++ b/source/blender/blenlib/BLI_heap_simple.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_HEAP_SIMPLE_H__
-#define __BLI_HEAP_SIMPLE_H__
+#pragma once
/** \file
* \ingroup bli
@@ -44,5 +43,3 @@ void *BLI_heapsimple_pop_min(HeapSimple *heap) ATTR_NONNULL(1);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_HEAP_SIMPLE_H__ */
diff --git a/source/blender/blenlib/BLI_index_mask.hh b/source/blender/blenlib/BLI_index_mask.hh
index 93bbb269d30..48b01edcd6f 100644
--- a/source/blender/blenlib/BLI_index_mask.hh
+++ b/source/blender/blenlib/BLI_index_mask.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_INDEX_MASK_HH__
-#define __BLI_INDEX_MASK_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -46,7 +45,7 @@ namespace blender {
class IndexMask {
private:
/* The underlying reference to sorted integers. */
- Span<uint> indices_;
+ Span<int64_t> indices_;
public:
/* Creates an IndexMask that contains no indices. */
@@ -57,10 +56,10 @@ class IndexMask {
* This constructor asserts that the given integers are in ascending order and that there are no
* duplicates.
*/
- IndexMask(Span<uint> indices) : indices_(indices)
+ IndexMask(Span<int64_t> indices) : indices_(indices)
{
#ifdef DEBUG
- for (uint i = 1; i < indices.size(); i++) {
+ for (int64_t i = 1; i < indices.size(); i++) {
BLI_assert(indices[i - 1] < indices[i]);
}
#endif
@@ -84,28 +83,28 @@ class IndexMask {
* Do this:
* do_something_with_an_index_mask({3, 4, 5});
*/
- IndexMask(const std::initializer_list<uint> &indices) : IndexMask(Span<uint>(indices))
+ IndexMask(const std::initializer_list<int64_t> &indices) : IndexMask(Span<int64_t>(indices))
{
}
/**
* Creates an IndexMask that references the indices [0, n-1].
*/
- explicit IndexMask(uint n) : IndexMask(IndexRange(n))
+ explicit IndexMask(int64_t n) : IndexMask(IndexRange(n))
{
}
- operator Span<uint>() const
+ operator Span<int64_t>() const
{
return indices_;
}
- const uint *begin() const
+ const int64_t *begin() const
{
return indices_.begin();
}
- const uint *end() const
+ const int64_t *end() const
{
return indices_.end();
}
@@ -114,7 +113,7 @@ class IndexMask {
* Returns the n-th index referenced by this IndexMask. The `index_mask` method returns an
* IndexRange containing all indices that can be used as parameter here.
*/
- uint operator[](uint n) const
+ int64_t operator[](int64_t n) const
{
return indices_[n];
}
@@ -123,7 +122,7 @@ class IndexMask {
* Returns the minimum size an array has to have, if the integers in this IndexMask are going to
* be used as indices in that array.
*/
- uint min_array_size() const
+ int64_t min_array_size() const
{
if (indices_.size() == 0) {
return 0;
@@ -133,7 +132,7 @@ class IndexMask {
}
}
- Span<uint> indices() const
+ Span<int64_t> indices() const
{
return indices_;
}
@@ -167,12 +166,12 @@ class IndexMask {
{
if (this->is_range()) {
IndexRange range = this->as_range();
- for (uint i : range) {
+ for (int64_t i : range) {
callback(i);
}
}
else {
- for (uint i : indices_) {
+ for (int64_t i : indices_) {
callback(i);
}
}
@@ -193,7 +192,7 @@ class IndexMask {
/**
* Returns the largest index that is referenced by this IndexMask.
*/
- uint last() const
+ int64_t last() const
{
return indices_.last();
}
@@ -201,12 +200,10 @@ class IndexMask {
/**
* Returns the number of indices referenced by this IndexMask.
*/
- uint size() const
+ int64_t size() const
{
return indices_.size();
}
};
} // namespace blender
-
-#endif /* __BLI_INDEX_MASK_HH__ */
diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh
index 1ae08e834ae..2b060c986cd 100644
--- a/source/blender/blenlib/BLI_index_range.hh
+++ b/source/blender/blenlib/BLI_index_range.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_INDEX_RANGE_HH__
-#define __BLI_INDEX_RANGE_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -27,29 +26,29 @@
* I'd argue that the second loop is more readable and less error prone than the first one. That is
* not necessarily always the case, but often it is.
*
- * for (uint i = 0; i < 10; i++) {
- * for (uint j = 0; j < 20; j++) {
- * for (uint k = 0; k < 30; k++) {
+ * for (int64_t i = 0; i < 10; i++) {
+ * for (int64_t j = 0; j < 20; j++) {
+ * for (int64_t k = 0; k < 30; k++) {
*
- * for (uint i : IndexRange(10)) {
- * for (uint j : IndexRange(20)) {
- * for (uint k : IndexRange(30)) {
+ * for (int64_t i : IndexRange(10)) {
+ * for (int64_t j : IndexRange(20)) {
+ * for (int64_t k : IndexRange(30)) {
*
* Some containers like blender::Vector have an index_range() method. This will return the
* IndexRange that contains all indices that can be used to access the container. This is
* particularly useful when you want to iterate over the indices and the elements (much like
* Python's enumerate(), just worse). Again, I think the second example here is better:
*
- * for (uint i = 0; i < my_vector_with_a_long_name.size(); i++) {
+ * for (int64_t i = 0; i < my_vector_with_a_long_name.size(); i++) {
* do_something(i, my_vector_with_a_long_name[i]);
*
- * for (uint i : my_vector_with_a_long_name.index_range()) {
+ * for (int64_t i : my_vector_with_a_long_name.index_range()) {
* do_something(i, my_vector_with_a_long_name[i]);
*
* Ideally this could be could be even closer to Python's enumerate(). We might get that in the
* future with newer C++ versions.
*
- * One other important feature is the as_span method. This method returns an Span<uint>
+ * One other important feature is the as_span method. This method returns an Span<int64_t>
* that contains the interval as individual numbers.
*/
@@ -70,18 +69,21 @@ template<typename T> class Span;
class IndexRange {
private:
- uint start_ = 0;
- uint size_ = 0;
+ int64_t start_ = 0;
+ int64_t size_ = 0;
public:
IndexRange() = default;
- explicit IndexRange(uint size) : start_(0), size_(size)
+ explicit IndexRange(int64_t size) : start_(0), size_(size)
{
+ BLI_assert(size >= 0);
}
- IndexRange(uint start, uint size) : start_(start), size_(size)
+ IndexRange(int64_t start, int64_t size) : start_(start), size_(size)
{
+ BLI_assert(start >= 0);
+ BLI_assert(size >= 0);
}
template<typename T>
@@ -91,10 +93,10 @@ class IndexRange {
class Iterator {
private:
- uint current_;
+ int64_t current_;
public:
- Iterator(uint current) : current_(current)
+ Iterator(int64_t current) : current_(current)
{
}
@@ -109,7 +111,7 @@ class IndexRange {
return current_ != iterator.current_;
}
- uint operator*() const
+ int64_t operator*() const
{
return current_;
}
@@ -128,8 +130,9 @@ class IndexRange {
/**
* Access an element in the range.
*/
- uint operator[](uint index) const
+ int64_t operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
return start_ + index;
}
@@ -145,7 +148,7 @@ class IndexRange {
/**
* Get the amount of numbers in the range.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -153,16 +156,18 @@ class IndexRange {
/**
* Create a new range starting at the end of the current one.
*/
- IndexRange after(uint n) const
+ IndexRange after(int64_t n) const
{
+ BLI_assert(n >= 0);
return IndexRange(start_ + size_, n);
}
/**
* Create a new range that ends at the start of the current one.
*/
- IndexRange before(uint n) const
+ IndexRange before(int64_t n) const
{
+ BLI_assert(n >= 0);
return IndexRange(start_ - n, n);
}
@@ -170,7 +175,7 @@ class IndexRange {
* Get the first element in the range.
* Asserts when the range is empty.
*/
- uint first() const
+ int64_t first() const
{
BLI_assert(this->size() > 0);
return start_;
@@ -180,7 +185,7 @@ class IndexRange {
* Get the last element in the range.
* Asserts when the range is empty.
*/
- uint last() const
+ int64_t last() const
{
BLI_assert(this->size() > 0);
return start_ + size_ - 1;
@@ -189,7 +194,7 @@ class IndexRange {
/**
* Get the element one after the end. The returned value is undefined when the range is empty.
*/
- uint one_after_last() const
+ int64_t one_after_last() const
{
return start_ + size_;
}
@@ -197,7 +202,7 @@ class IndexRange {
/**
* Get the first element in the range. The returned value is undefined when the range is empty.
*/
- uint start() const
+ int64_t start() const
{
return start_;
}
@@ -205,7 +210,7 @@ class IndexRange {
/**
* Returns true when the range contains a certain number, otherwise false.
*/
- bool contains(uint value) const
+ bool contains(int64_t value) const
{
return value >= start_ && value < start_ + size_;
}
@@ -213,9 +218,11 @@ class IndexRange {
/**
* Returns a new range, that contains a sub-interval of the current one.
*/
- IndexRange slice(uint start, uint size) const
+ IndexRange slice(int64_t start, int64_t size) const
{
- uint new_start = start_ + start;
+ BLI_assert(start >= 0);
+ BLI_assert(size >= 0);
+ int64_t new_start = start_ + start;
BLI_assert(new_start + size <= start_ + size_ || size == 0);
return IndexRange(new_start, size);
}
@@ -227,7 +234,7 @@ class IndexRange {
/**
* Get read-only access to a memory buffer that contains the range as actual numbers.
*/
- Span<uint> as_span() const;
+ Span<int64_t> as_span() const;
friend std::ostream &operator<<(std::ostream &stream, IndexRange range)
{
@@ -237,5 +244,3 @@ class IndexRange {
};
} // namespace blender
-
-#endif /* __BLI_INDEX_RANGE_HH__ */
diff --git a/source/blender/blenlib/BLI_iterator.h b/source/blender/blenlib/BLI_iterator.h
index ce2311aa3f7..c1cd1c21dac 100644
--- a/source/blender/blenlib/BLI_iterator.h
+++ b/source/blender/blenlib/BLI_iterator.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_ITERATOR_H__
-#define __BLI_ITERATOR_H__
+#pragma once
/** \file
* \ingroup bli
@@ -58,5 +57,3 @@ typedef void (*IteratorBeginCb)(BLI_Iterator *iter, void *data_in);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_ITERATOR_H__ */
diff --git a/source/blender/blenlib/BLI_jitter_2d.h b/source/blender/blenlib/BLI_jitter_2d.h
index fa184916b5b..a0af352ddd2 100644
--- a/source/blender/blenlib/BLI_jitter_2d.h
+++ b/source/blender/blenlib/BLI_jitter_2d.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_JITTER_2D_H__
-#define __BLI_JITTER_2D_H__
+#pragma once
/** \file
* \ingroup bli
@@ -35,5 +34,3 @@ void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float radius2);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_JITTER_2D_H__ */
diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h
index 70fa633eeac..5e317c89625 100644
--- a/source/blender/blenlib/BLI_kdopbvh.h
+++ b/source/blender/blenlib/BLI_kdopbvh.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_KDOPBVH_H__
-#define __BLI_KDOPBVH_H__
+#pragma once
/** \file
* \ingroup bli
@@ -174,6 +173,8 @@ BVHTreeOverlap *BLI_bvhtree_overlap(const BVHTree *tree1,
BVHTree_OverlapCallback callback,
void *userdata);
+int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_tot);
+
int BLI_bvhtree_get_len(const BVHTree *tree);
int BLI_bvhtree_get_tree_type(const BVHTree *tree);
float BLI_bvhtree_get_epsilon(const BVHTree *tree);
@@ -262,5 +263,3 @@ extern const float bvhtree_kdop_axes[13][3];
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_KDOPBVH_H__ */
diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h
index 9ba045fdbf8..76f39dfbacb 100644
--- a/source/blender/blenlib/BLI_kdtree.h
+++ b/source/blender/blenlib/BLI_kdtree.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_KDTREE_H__
-#define __BLI_KDTREE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -73,5 +72,3 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_KDTREE_H__ */
diff --git a/source/blender/blenlib/BLI_lasso_2d.h b/source/blender/blenlib/BLI_lasso_2d.h
index fb661c41784..e920d1189a2 100644
--- a/source/blender/blenlib/BLI_lasso_2d.h
+++ b/source/blender/blenlib/BLI_lasso_2d.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_LASSO_2D_H__
-#define __BLI_LASSO_2D_H__
+#pragma once
/** \file
* \ingroup bli
@@ -47,5 +46,3 @@ bool BLI_lasso_is_edge_inside(const int mcoords[][2],
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_LASSO_2D_H__ */
diff --git a/source/blender/blenlib/BLI_linear_allocator.hh b/source/blender/blenlib/BLI_linear_allocator.hh
index b13d88d5b93..fcc20d483c9 100644
--- a/source/blender/blenlib/BLI_linear_allocator.hh
+++ b/source/blender/blenlib/BLI_linear_allocator.hh
@@ -22,8 +22,7 @@
* memory. When the current buffer is full, it reallocates a new larger buffer and continues.
*/
-#ifndef __BLI_LINEAR_ALLOCATOR_HH__
-#define __BLI_LINEAR_ALLOCATOR_HH__
+#pragma once
#include "BLI_string_ref.hh"
#include "BLI_utility_mixins.hh"
@@ -39,10 +38,10 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
uintptr_t current_begin_;
uintptr_t current_end_;
- uint next_min_alloc_size_;
+ int64_t next_min_alloc_size_;
#ifdef DEBUG
- uint debug_allocated_amount_ = 0;
+ int64_t debug_allocated_amount_ = 0;
#endif
public:
@@ -66,8 +65,9 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
*
* The alignment has to be a power of 2.
*/
- void *allocate(const uint size, const uint alignment)
+ void *allocate(const int64_t size, const int64_t alignment)
{
+ BLI_assert(size >= 0);
BLI_assert(alignment >= 1);
BLI_assert(is_power_of_2_i(alignment));
@@ -105,7 +105,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
*
* This method only allocates memory and does not construct the instance.
*/
- template<typename T> MutableSpan<T> allocate_array(uint size)
+ template<typename T> MutableSpan<T> allocate_array(int64_t size)
{
return MutableSpan<T>((T *)this->allocate(sizeof(T) * size, alignof(T)), size);
}
@@ -141,22 +141,22 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
*/
StringRefNull copy_string(StringRef str)
{
- const uint alloc_size = str.size() + 1;
+ const int64_t alloc_size = str.size() + 1;
char *buffer = (char *)this->allocate(alloc_size, 1);
str.copy(buffer, alloc_size);
return StringRefNull((const char *)buffer);
}
- MutableSpan<void *> allocate_elements_and_pointer_array(uint element_amount,
- uint element_size,
- uint element_alignment)
+ MutableSpan<void *> allocate_elements_and_pointer_array(int64_t element_amount,
+ int64_t element_size,
+ int64_t element_alignment)
{
void *pointer_buffer = this->allocate(element_amount * sizeof(void *), alignof(void *));
void *elements_buffer = this->allocate(element_amount * element_size, element_alignment);
MutableSpan<void *> pointers((void **)pointer_buffer, element_amount);
void *next_element_buffer = elements_buffer;
- for (uint i : IndexRange(element_amount)) {
+ for (int64_t i : IndexRange(element_amount)) {
pointers[i] = next_element_buffer;
next_element_buffer = POINTER_OFFSET(next_element_buffer, element_size);
}
@@ -165,13 +165,13 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
}
template<typename T, typename... Args>
- Span<T *> construct_elements_and_pointer_array(uint n, Args &&... args)
+ Span<T *> construct_elements_and_pointer_array(int64_t n, Args &&... args)
{
MutableSpan<void *> void_pointers = this->allocate_elements_and_pointer_array(
n, sizeof(T), alignof(T));
MutableSpan<T *> pointers = void_pointers.cast<T *>();
- for (uint i : IndexRange(n)) {
+ for (int64_t i : IndexRange(n)) {
new ((void *)pointers[i]) T(std::forward<Args>(args)...);
}
@@ -194,9 +194,9 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
}
private:
- void allocate_new_buffer(uint min_allocation_size)
+ void allocate_new_buffer(int64_t min_allocation_size)
{
- for (uint i : unused_borrowed_buffers_.index_range()) {
+ for (int64_t i : unused_borrowed_buffers_.index_range()) {
Span<char> buffer = unused_borrowed_buffers_[i];
if (buffer.size() >= min_allocation_size) {
unused_borrowed_buffers_.remove_and_reorder(i);
@@ -206,7 +206,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
}
}
- const uint size_in_bytes = power_of_2_min_u(
+ const int64_t size_in_bytes = power_of_2_min_u(
std::max(min_allocation_size, next_min_alloc_size_));
next_min_alloc_size_ = size_in_bytes * 2;
@@ -218,5 +218,3 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
};
} // namespace blender
-
-#endif /* __BLI_LINEAR_ALLOCATOR_HH__ */
diff --git a/source/blender/blenlib/BLI_link_utils.h b/source/blender/blenlib/BLI_link_utils.h
index c0db53ca9a3..a877860cd8d 100644
--- a/source/blender/blenlib/BLI_link_utils.h
+++ b/source/blender/blenlib/BLI_link_utils.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_LINK_UTILS_H__
-#define __BLI_LINK_UTILS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -67,5 +66,3 @@
} \
} \
(void)0
-
-#endif /* __BLI_LINK_UTILS_H__ */
diff --git a/source/blender/blenlib/BLI_linklist.h b/source/blender/blenlib/BLI_linklist.h
index 06796d6592a..25d58a3050c 100644
--- a/source/blender/blenlib/BLI_linklist.h
+++ b/source/blender/blenlib/BLI_linklist.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_LINKLIST_H__
-#define __BLI_LINKLIST_H__
+#pragma once
/** \file
* \ingroup bli
@@ -55,6 +54,7 @@ int BLI_linklist_count(const LinkNode *list) ATTR_WARN_UNUSED_RESULT;
int BLI_linklist_index(const LinkNode *list, void *ptr) ATTR_WARN_UNUSED_RESULT;
LinkNode *BLI_linklist_find(LinkNode *list, int index) ATTR_WARN_UNUSED_RESULT;
+LinkNode *BLI_linklist_find_last(LinkNode *list) ATTR_WARN_UNUSED_RESULT;
void BLI_linklist_reverse(LinkNode **listp) ATTR_NONNULL(1);
@@ -100,5 +100,3 @@ LinkNode *BLI_linklist_sort_r(LinkNode *list,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_LINKLIST_H__ */
diff --git a/source/blender/blenlib/BLI_linklist_lockfree.h b/source/blender/blenlib/BLI_linklist_lockfree.h
index 647b00ec658..142fa1cf243 100644
--- a/source/blender/blenlib/BLI_linklist_lockfree.h
+++ b/source/blender/blenlib/BLI_linklist_lockfree.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_LINKLIST_LOCKFREE_H__
-#define __BLI_LINKLIST_LOCKFREE_H__
+#pragma once
/** \file
* \ingroup bli
@@ -73,5 +72,3 @@ void BLI_linklist_lockfree_insert(LockfreeLinkList *list, LockfreeLinkNode *node
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_LINKLIST_H__ */
diff --git a/source/blender/blenlib/BLI_linklist_stack.h b/source/blender/blenlib/BLI_linklist_stack.h
index 3725682d380..065ed12f353 100644
--- a/source/blender/blenlib/BLI_linklist_stack.h
+++ b/source/blender/blenlib/BLI_linklist_stack.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_LINKLIST_STACK_H__
-#define __BLI_LINKLIST_STACK_H__
+#pragma once
/** \file
* \ingroup bli
@@ -194,5 +193,3 @@
(void)0
/** \} */
-
-#endif /* __BLI_LINKLIST_STACK_H__ */
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index b027acb88da..fa7cf7a1847 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_LISTBASE_H__
-#define __BLI_LISTBASE_H__
+#pragma once
/** \file
* \ingroup bli
@@ -190,5 +189,3 @@ struct LinkData *BLI_genericNodeN(void *data);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_LISTBASE_H__ */
diff --git a/source/blender/blenlib/BLI_listbase_wrapper.hh b/source/blender/blenlib/BLI_listbase_wrapper.hh
index 047099eb36e..00f757d4bc2 100644
--- a/source/blender/blenlib/BLI_listbase_wrapper.hh
+++ b/source/blender/blenlib/BLI_listbase_wrapper.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_LISTBASE_WRAPPER_HH__
-#define __BLI_LISTBASE_WRAPPER_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -96,9 +95,9 @@ template<typename T> class ListBaseWrapper {
return (T *)ptr;
}
- uint index_of(const T *value) const
+ int64_t index_of(const T *value) const
{
- uint index = 0;
+ int64_t index = 0;
for (T *ptr : *this) {
if (ptr == value) {
return index;
@@ -106,10 +105,8 @@ template<typename T> class ListBaseWrapper {
index++;
}
BLI_assert(false);
- return 0;
+ return -1;
}
};
} /* namespace blender */
-
-#endif /* __BLI_LISTBASE_WRAPPER_HH__ */
diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh
index 0a044afe8af..f90d59f45a5 100644
--- a/source/blender/blenlib/BLI_map.hh
+++ b/source/blender/blenlib/BLI_map.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_MAP_HH__
-#define __BLI_MAP_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -92,11 +91,8 @@ template<
* The minimum number of elements that can be stored in this Map without doing a heap
* allocation. This is useful when you expect to have many small maps. However, keep in mind
* that (unlike vector) initializing a map has a O(n) cost in the number of slots.
- *
- * When Key or Value are large, the small buffer optimization is disabled by default to avoid
- * large unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint32_t InlineBufferCapacity = (sizeof(Key) + sizeof(Value) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key) + sizeof(Value)),
/**
* The strategy used to deal with collisions. They are defined in BLI_probing_strategies.hh.
*/
@@ -129,20 +125,20 @@ class Map {
* Slots are either empty, occupied or removed. The number of occupied slots can be computed by
* subtracting the removed slots from the occupied-and-removed slots.
*/
- uint32_t removed_slots_;
- uint32_t occupied_and_removed_slots_;
+ int64_t removed_slots_;
+ int64_t occupied_and_removed_slots_;
/**
* The maximum number of slots that can be used (either occupied or removed) until the set has to
* grow. This is the total number of slots times the max load factor.
*/
- uint32_t usable_slots_;
+ int64_t usable_slots_;
/**
* The number of slots minus one. This is a bit mask that can be used to turn any integer into a
* valid slot index efficiently.
*/
- uint32_t slot_mask_;
+ uint64_t slot_mask_;
/** This is called to hash incoming keys. */
Hash hash_;
@@ -271,10 +267,6 @@ class Map {
{
return this->add_as(std::move(key), std::move(value));
}
-
- /**
- * Same as `add`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey, typename ForwardValue>
bool add_as(ForwardKey &&key, ForwardValue &&value)
{
@@ -305,10 +297,6 @@ class Map {
{
return this->add_overwrite_as(std::move(key), std::move(value));
}
-
- /**
- * Same as `add_overwrite`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey, typename ForwardValue>
bool add_overwrite_as(ForwardKey &&key, ForwardValue &&value)
{
@@ -325,10 +313,6 @@ class Map {
{
return this->contains_as(key);
}
-
- /**
- * Same as `contains`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> bool contains_as(const ForwardKey &key) const
{
return this->contains__impl(key, hash_(key));
@@ -344,10 +328,6 @@ class Map {
{
return this->remove_as(key);
}
-
- /**
- * Same as `remove`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> bool remove_as(const ForwardKey &key)
{
return this->remove__impl(key, hash_(key));
@@ -361,11 +341,6 @@ class Map {
{
this->remove_contained_as(key);
}
-
- /**
- * Same as `remove_contained`, but accepts other key types that are supported by the hash
- * function.
- */
template<typename ForwardKey> void remove_contained_as(const ForwardKey &key)
{
this->remove_contained__impl(key, hash_(key));
@@ -379,10 +354,6 @@ class Map {
{
return this->pop_as(key);
}
-
- /**
- * Same as `pop`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> Value pop_as(const ForwardKey &key)
{
return this->pop__impl(key, hash_(key));
@@ -396,10 +367,6 @@ class Map {
{
return this->pop_try_as(key);
}
-
- /**
- * Same as `pop_try`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> std::optional<Value> pop_try_as(const ForwardKey &key)
{
return this->pop_try__impl(key, hash_(key));
@@ -417,10 +384,6 @@ class Map {
{
return this->pop_default_as(key, std::move(default_value));
}
-
- /**
- * Same as `pop_default`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey, typename ForwardValue>
Value pop_default_as(const ForwardKey &key, ForwardValue &&default_value)
{
@@ -460,10 +423,6 @@ class Map {
{
return this->add_or_modify_as(std::move(key), create_value, modify_value);
}
-
- /**
- * Same as `add_or_modify`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey, typename CreateValueF, typename ModifyValueF>
auto add_or_modify_as(ForwardKey &&key,
const CreateValueF &create_value,
@@ -487,10 +446,6 @@ class Map {
{
return this->lookup_ptr_as(key);
}
-
- /**
- * Same as `lookup_ptr`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> const Value *lookup_ptr_as(const ForwardKey &key) const
{
return this->lookup_ptr__impl(key, hash_(key));
@@ -512,10 +467,6 @@ class Map {
{
return this->lookup_as(key);
}
-
- /**
- * Same as `lookup`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> const Value &lookup_as(const ForwardKey &key) const
{
const Value *ptr = this->lookup_ptr_as(key);
@@ -537,10 +488,6 @@ class Map {
{
return this->lookup_default_as(key, default_value);
}
-
- /**
- * Same as `lookup_default`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey, typename ForwardValue>
Value lookup_default_as(const ForwardKey &key, ForwardValue &&default_value) const
{
@@ -573,11 +520,6 @@ class Map {
{
return this->lookup_or_add_as(std::move(key), std::move(value));
}
-
- /**
- * Same as `lookup_or_add`, but accepts other key types that are supported by the hash
- * function.
- */
template<typename ForwardKey, typename ForwardValue>
Value &lookup_or_add_as(ForwardKey &&key, ForwardValue &&value)
{
@@ -602,11 +544,6 @@ class Map {
{
return this->lookup_or_add_cb_as(std::move(key), create_value);
}
-
- /**
- * Same as `lookup_or_add_cb`, but accepts other key types that are supported by the hash
- * function.
- */
template<typename ForwardKey, typename CreateValueF>
Value &lookup_or_add_cb_as(ForwardKey &&key, const CreateValueF &create_value)
{
@@ -625,11 +562,6 @@ class Map {
{
return this->lookup_or_add_default_as(std::move(key));
}
-
- /**
- * Same as `lookup_or_add_default`, but accepts other key types that are supported by the hash
- * function.
- */
template<typename ForwardKey> Value &lookup_or_add_default_as(ForwardKey &&key)
{
return this->lookup_or_add_cb_as(std::forward<ForwardKey>(key), []() { return Value(); });
@@ -641,8 +573,8 @@ class Map {
*/
template<typename FuncT> void foreach_item(const FuncT &func) const
{
- uint32_t size = slots_.size();
- for (uint32_t i = 0; i < size; i++) {
+ int64_t size = slots_.size();
+ for (int64_t i = 0; i < size; i++) {
const Slot &slot = slots_[i];
if (slot.is_occupied()) {
const Key &key = *slot.key();
@@ -658,10 +590,10 @@ class Map {
*/
template<typename SubIterator> struct BaseIterator {
Slot *slots_;
- uint32_t total_slots_;
- uint32_t current_slot_;
+ int64_t total_slots_;
+ int64_t current_slot_;
- BaseIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ BaseIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: slots_(const_cast<Slot *>(slots)), total_slots_(total_slots), current_slot_(current_slot)
{
}
@@ -685,7 +617,7 @@ class Map {
SubIterator begin() const
{
- for (uint32_t i = 0; i < total_slots_; i++) {
+ for (int64_t i = 0; i < total_slots_; i++) {
if (slots_[i].is_occupied()) {
return SubIterator(slots_, total_slots_, i);
}
@@ -706,7 +638,7 @@ class Map {
class KeyIterator final : public BaseIterator<KeyIterator> {
public:
- KeyIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ KeyIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<KeyIterator>(slots, total_slots, current_slot)
{
}
@@ -719,7 +651,7 @@ class Map {
class ValueIterator final : public BaseIterator<ValueIterator> {
public:
- ValueIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ ValueIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<ValueIterator>(slots, total_slots, current_slot)
{
}
@@ -732,7 +664,7 @@ class Map {
class MutableValueIterator final : public BaseIterator<MutableValueIterator> {
public:
- MutableValueIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ MutableValueIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<MutableValueIterator>(slots, total_slots, current_slot)
{
}
@@ -760,7 +692,7 @@ class Map {
class ItemIterator final : public BaseIterator<ItemIterator> {
public:
- ItemIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ ItemIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<ItemIterator>(slots, total_slots, current_slot)
{
}
@@ -774,7 +706,7 @@ class Map {
class MutableItemIterator final : public BaseIterator<MutableItemIterator> {
public:
- MutableItemIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ MutableItemIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<MutableItemIterator>(slots, total_slots, current_slot)
{
}
@@ -847,7 +779,7 @@ class Map {
/**
* Return the number of key-value-pairs that are stored in the map.
*/
- uint32_t size() const
+ int64_t size() const
{
return occupied_and_removed_slots_ - removed_slots_;
}
@@ -865,7 +797,7 @@ class Map {
/**
* Returns the number of available slots. This is mostly for debugging purposes.
*/
- uint32_t capacity() const
+ int64_t capacity() const
{
return slots_.size();
}
@@ -873,7 +805,7 @@ class Map {
/**
* Returns the amount of removed slots in the set. This is mostly for debugging purposes.
*/
- uint32_t removed_amount() const
+ int64_t removed_amount() const
{
return removed_slots_;
}
@@ -881,7 +813,7 @@ class Map {
/**
* Returns the bytes required per element. This is mostly for debugging purposes.
*/
- uint32_t size_per_element() const
+ int64_t size_per_element() const
{
return sizeof(Slot);
}
@@ -890,16 +822,16 @@ class Map {
* Returns the approximate memory requirements of the map in bytes. This becomes more exact the
* larger the map becomes.
*/
- uint32_t size_in_bytes() const
+ int64_t size_in_bytes() const
{
- return (uint32_t)(sizeof(Slot) * slots_.size());
+ return (int64_t)(sizeof(Slot) * slots_.size());
}
/**
* Potentially resize the map such that the specified number of elements can be added without
* another grow operation.
*/
- void reserve(uint32_t n)
+ void reserve(int64_t n)
{
if (usable_slots_ < n) {
this->realloc_and_reinsert(n);
@@ -919,18 +851,19 @@ class Map {
* Get the number of collisions that the probing strategy has to go through to find the key or
* determine that it is not in the map.
*/
- uint32_t count_collisions(const Key &key) const
+ int64_t count_collisions(const Key &key) const
{
return this->count_collisions__impl(key, hash_(key));
}
private:
- BLI_NOINLINE void realloc_and_reinsert(uint32_t min_usable_slots)
+ BLI_NOINLINE void realloc_and_reinsert(int64_t min_usable_slots)
{
- uint32_t total_slots, usable_slots;
+ int64_t total_slots, usable_slots;
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
- uint32_t new_slot_mask = total_slots - 1;
+ BLI_assert(total_slots >= 1);
+ const uint64_t new_slot_mask = (uint64_t)total_slots - 1;
/**
* Optimize the case when the map was empty beforehand. We can avoid some copies here.
@@ -965,9 +898,9 @@ class Map {
void add_after_grow_and_destruct_old(Slot &old_slot,
SlotArray &new_slots,
- uint32_t new_slot_mask)
+ uint64_t new_slot_mask)
{
- uint32_t hash = old_slot.get_hash(Hash());
+ uint64_t hash = old_slot.get_hash(Hash());
SLOT_PROBING_BEGIN (ProbingStrategy, hash, new_slot_mask, slot_index) {
Slot &slot = new_slots[slot_index];
if (slot.is_empty()) {
@@ -978,7 +911,7 @@ class Map {
SLOT_PROBING_END();
}
- template<typename ForwardKey> bool contains__impl(const ForwardKey &key, uint32_t hash) const
+ template<typename ForwardKey> bool contains__impl(const ForwardKey &key, uint64_t hash) const
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
@@ -992,7 +925,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- void add_new__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ void add_new__impl(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
BLI_assert(!this->contains_as(key));
@@ -1009,7 +942,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- bool add__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ bool add__impl(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
this->ensure_can_add();
@@ -1026,7 +959,7 @@ class Map {
MAP_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool remove__impl(const ForwardKey &key, uint32_t hash)
+ template<typename ForwardKey> bool remove__impl(const ForwardKey &key, uint64_t hash)
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -1041,7 +974,7 @@ class Map {
MAP_SLOT_PROBING_END();
}
- template<typename ForwardKey> void remove_contained__impl(const ForwardKey &key, uint32_t hash)
+ template<typename ForwardKey> void remove_contained__impl(const ForwardKey &key, uint64_t hash)
{
BLI_assert(this->contains_as(key));
@@ -1056,7 +989,7 @@ class Map {
MAP_SLOT_PROBING_END();
}
- template<typename ForwardKey> Value pop__impl(const ForwardKey &key, uint32_t hash)
+ template<typename ForwardKey> Value pop__impl(const ForwardKey &key, uint64_t hash)
{
BLI_assert(this->contains_as(key));
@@ -1073,7 +1006,7 @@ class Map {
}
template<typename ForwardKey>
- std::optional<Value> pop_try__impl(const ForwardKey &key, uint32_t hash)
+ std::optional<Value> pop_try__impl(const ForwardKey &key, uint64_t hash)
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -1090,7 +1023,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- Value pop_default__impl(const ForwardKey &key, ForwardValue &&default_value, uint32_t hash)
+ Value pop_default__impl(const ForwardKey &key, ForwardValue &&default_value, uint64_t hash)
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -1110,11 +1043,11 @@ class Map {
auto add_or_modify__impl(ForwardKey &&key,
const CreateValueF &create_value,
const ModifyValueF &modify_value,
- uint32_t hash) -> decltype(create_value(nullptr))
+ uint64_t hash) -> decltype(create_value(nullptr))
{
using CreateReturnT = decltype(create_value(nullptr));
using ModifyReturnT = decltype(modify_value(nullptr));
- BLI_STATIC_ASSERT((std::is_same<CreateReturnT, ModifyReturnT>::value),
+ BLI_STATIC_ASSERT((std::is_same_v<CreateReturnT, ModifyReturnT>),
"Both callbacks should return the same type.");
this->ensure_can_add();
@@ -1135,7 +1068,7 @@ class Map {
}
template<typename ForwardKey, typename CreateValueF>
- Value &lookup_or_add_cb__impl(ForwardKey &&key, const CreateValueF &create_value, uint32_t hash)
+ Value &lookup_or_add_cb__impl(ForwardKey &&key, const CreateValueF &create_value, uint64_t hash)
{
this->ensure_can_add();
@@ -1153,7 +1086,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- Value &lookup_or_add__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ Value &lookup_or_add__impl(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
this->ensure_can_add();
@@ -1171,7 +1104,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- bool add_overwrite__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ bool add_overwrite__impl(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
auto create_func = [&](Value *ptr) {
new ((void *)ptr) Value(std::forward<ForwardValue>(value));
@@ -1186,7 +1119,7 @@ class Map {
}
template<typename ForwardKey>
- const Value *lookup_ptr__impl(const ForwardKey &key, uint32_t hash) const
+ const Value *lookup_ptr__impl(const ForwardKey &key, uint64_t hash) const
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
@@ -1200,9 +1133,9 @@ class Map {
}
template<typename ForwardKey>
- uint32_t count_collisions__impl(const ForwardKey &key, uint32_t hash) const
+ int64_t count_collisions__impl(const ForwardKey &key, uint64_t hash) const
{
- uint32_t collisions = 0;
+ int64_t collisions = 0;
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -1226,6 +1159,21 @@ class Map {
};
/**
+ * Same as a normal Map, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename Key,
+ typename Value,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key) +
+ sizeof(Value)),
+ typename ProbingStrategy = DefaultProbingStrategy,
+ typename Hash = DefaultHash<Key>,
+ typename IsEqual = DefaultEquality,
+ typename Slot = typename DefaultMapSlot<Key, Value>::type>
+using RawMap =
+ Map<Key, Value, InlineBufferCapacity, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>;
+
+/**
* A wrapper for std::unordered_map with the API of blender::Map. This can be used for
* benchmarking.
*/
@@ -1235,9 +1183,9 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
MapType map_;
public:
- uint32_t size() const
+ int64_t size() const
{
- return (uint32_t)map_.size();
+ return (int64_t)map_.size();
}
bool is_empty() const
@@ -1245,7 +1193,7 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
return map_.empty();
}
- void reserve(uint32_t n)
+ void reserve(int64_t n)
{
map_.reserve(n);
}
@@ -1293,5 +1241,3 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
};
} // namespace blender
-
-#endif /* __BLI_MAP_HH__ */
diff --git a/source/blender/blenlib/BLI_map_slots.hh b/source/blender/blenlib/BLI_map_slots.hh
index c3d88205e0a..25fb92d61a3 100644
--- a/source/blender/blenlib/BLI_map_slots.hh
+++ b/source/blender/blenlib/BLI_map_slots.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_MAP_SLOTS_HH__
-#define __BLI_MAP_SLOTS_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -53,8 +52,8 @@ template<typename Key, typename Value> class SimpleMapSlot {
};
State state_;
- AlignedBuffer<sizeof(Key), alignof(Key)> key_buffer_;
- AlignedBuffer<sizeof(Value), alignof(Value)> value_buffer_;
+ TypedBuffer<Key> key_buffer_;
+ TypedBuffer<Value> value_buffer_;
public:
/**
@@ -71,8 +70,8 @@ template<typename Key, typename Value> class SimpleMapSlot {
~SimpleMapSlot()
{
if (state_ == Occupied) {
- this->key()->~Key();
- this->value()->~Value();
+ key_buffer_.ref().~Key();
+ value_buffer_.ref().~Value();
}
}
@@ -84,8 +83,8 @@ template<typename Key, typename Value> class SimpleMapSlot {
{
state_ = other.state_;
if (other.state_ == Occupied) {
- new ((void *)this->key()) Key(*other.key());
- new ((void *)this->value()) Value(*other.value());
+ new (&key_buffer_) Key(*other.key_buffer_);
+ new (&value_buffer_) Value(*other.value_buffer_);
}
}
@@ -98,8 +97,8 @@ template<typename Key, typename Value> class SimpleMapSlot {
{
state_ = other.state_;
if (other.state_ == Occupied) {
- new ((void *)this->key()) Key(std::move(*other.key()));
- new ((void *)this->value()) Value(std::move(*other.value()));
+ new (&key_buffer_) Key(std::move(*other.key_buffer_));
+ new (&value_buffer_) Value(std::move(*other.value_buffer_));
}
}
@@ -108,7 +107,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
*/
Key *key()
{
- return (Key *)key_buffer_.ptr();
+ return key_buffer_;
}
/**
@@ -116,7 +115,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
*/
const Key *key() const
{
- return (const Key *)key_buffer_.ptr();
+ return key_buffer_;
}
/**
@@ -124,7 +123,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
*/
Value *value()
{
- return (Value *)value_buffer_.ptr();
+ return value_buffer_;
}
/**
@@ -132,7 +131,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
*/
const Value *value() const
{
- return (const Value *)value_buffer_.ptr();
+ return value_buffer_;
}
/**
@@ -155,25 +154,25 @@ template<typename Key, typename Value> class SimpleMapSlot {
* Returns the hash of the currently stored key. In this simple map slot implementation, we just
* computed the hash here. Other implementations might store the hash in the slot instead.
*/
- template<typename Hash> uint32_t get_hash(const Hash &hash)
+ template<typename Hash> uint64_t get_hash(const Hash &hash)
{
BLI_assert(this->is_occupied());
- return hash(*this->key());
+ return hash(*key_buffer_);
}
/**
* Move the other slot into this slot and destruct it. We do destruction here, because this way
* we can avoid a comparison with the state, since we know the slot is occupied.
*/
- void relocate_occupied_here(SimpleMapSlot &other, uint32_t UNUSED(hash))
+ void relocate_occupied_here(SimpleMapSlot &other, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
state_ = Occupied;
- new ((void *)this->key()) Key(std::move(*other.key()));
- new ((void *)this->value()) Value(std::move(*other.value()));
- other.key()->~Key();
- other.value()->~Value();
+ new (&key_buffer_) Key(std::move(*other.key_buffer_));
+ new (&value_buffer_) Value(std::move(*other.value_buffer_));
+ other.key_buffer_.ref().~Key();
+ other.value_buffer_.ref().~Value();
}
/**
@@ -181,10 +180,10 @@ template<typename Key, typename Value> class SimpleMapSlot {
* key. The hash can be used by other slot implementations to determine inequality faster.
*/
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint32_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
{
if (state_ == Occupied) {
- return is_equal(key, *this->key());
+ return is_equal(key, *key_buffer_);
}
return false;
}
@@ -194,22 +193,22 @@ template<typename Key, typename Value> class SimpleMapSlot {
* constructed by calling the constructor with the given key/value as parameter.
*/
template<typename ForwardKey, typename ForwardValue>
- void occupy(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ void occupy(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
BLI_assert(!this->is_occupied());
this->occupy_without_value(std::forward<ForwardKey>(key), hash);
- new ((void *)this->value()) Value(std::forward<ForwardValue>(value));
+ new (&value_buffer_) Value(std::forward<ForwardValue>(value));
}
/**
* Change the state of this slot from empty/removed to occupied, but leave the value
* uninitialized. The caller is responsible to construct the value afterwards.
*/
- template<typename ForwardKey> void occupy_without_value(ForwardKey &&key, uint32_t UNUSED(hash))
+ template<typename ForwardKey> void occupy_without_value(ForwardKey &&key, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
state_ = Occupied;
- new ((void *)this->key()) Key(std::forward<ForwardKey>(key));
+ new (&key_buffer_) Key(std::forward<ForwardKey>(key));
}
/**
@@ -220,8 +219,8 @@ template<typename Key, typename Value> class SimpleMapSlot {
{
BLI_assert(this->is_occupied());
state_ = Removed;
- this->key()->~Key();
- this->value()->~Value();
+ key_buffer_.ref().~Key();
+ value_buffer_.ref().~Value();
}
};
@@ -236,7 +235,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot {
private:
Key key_ = KeyInfo::get_empty();
- AlignedBuffer<sizeof(Value), alignof(Value)> value_buffer_;
+ TypedBuffer<Value> value_buffer_;
public:
IntrusiveMapSlot() = default;
@@ -244,21 +243,21 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
~IntrusiveMapSlot()
{
if (KeyInfo::is_not_empty_or_removed(key_)) {
- this->value()->~Value();
+ value_buffer_.ref().~Value();
}
}
IntrusiveMapSlot(const IntrusiveMapSlot &other) : key_(other.key_)
{
if (KeyInfo::is_not_empty_or_removed(key_)) {
- new ((void *)this->value()) Value(*other.value());
+ new (&value_buffer_) Value(*other.value_buffer_);
}
}
IntrusiveMapSlot(IntrusiveMapSlot &&other) noexcept : key_(other.key_)
{
if (KeyInfo::is_not_empty_or_removed(key_)) {
- new ((void *)this->value()) Value(std::move(*other.value()));
+ new (&value_buffer_) Value(std::move(*other.value_buffer_));
}
}
@@ -274,12 +273,12 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
Value *value()
{
- return (Value *)value_buffer_.ptr();
+ return value_buffer_;
}
const Value *value() const
{
- return (const Value *)value_buffer_.ptr();
+ return value_buffer_;
}
bool is_occupied() const
@@ -292,39 +291,39 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
return KeyInfo::is_empty(key_);
}
- template<typename Hash> uint32_t get_hash(const Hash &hash)
+ template<typename Hash> uint64_t get_hash(const Hash &hash)
{
BLI_assert(this->is_occupied());
- return hash(*this->key());
+ return hash(key_);
}
- void relocate_occupied_here(IntrusiveMapSlot &other, uint32_t UNUSED(hash))
+ void relocate_occupied_here(IntrusiveMapSlot &other, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
key_ = std::move(other.key_);
- new ((void *)this->value()) Value(std::move(*other.value()));
+ new (&value_buffer_) Value(std::move(*other.value_buffer_));
other.key_.~Key();
- other.value()->~Value();
+ other.value_buffer_.ref().~Value();
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint32_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
{
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
return is_equal(key, key_);
}
template<typename ForwardKey, typename ForwardValue>
- void occupy(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ void occupy(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
this->occupy_without_value(std::forward<ForwardKey>(key), hash);
- new ((void *)this->value()) Value(std::forward<ForwardValue>(value));
+ new (&value_buffer_) Value(std::forward<ForwardValue>(value));
}
- template<typename ForwardKey> void occupy_without_value(ForwardKey &&key, uint32_t UNUSED(hash))
+ template<typename ForwardKey> void occupy_without_value(ForwardKey &&key, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
@@ -335,7 +334,7 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
{
BLI_assert(this->is_occupied());
KeyInfo::remove(key_);
- this->value()->~Value();
+ value_buffer_.ref().~Value();
}
};
@@ -357,5 +356,3 @@ template<typename Key, typename Value> struct DefaultMapSlot<Key *, Value> {
};
} // namespace blender
-
-#endif /* __BLI_MAP_SLOTS_HH__ */
diff --git a/source/blender/blenlib/BLI_math.h b/source/blender/blenlib/BLI_math.h
index f8de8b7ed53..51833d081d0 100644
--- a/source/blender/blenlib/BLI_math.h
+++ b/source/blender/blenlib/BLI_math.h
@@ -20,8 +20,7 @@
*
* */
-#ifndef __BLI_MATH_H__
-#define __BLI_MATH_H__
+#pragma once
/** \file
* \ingroup bli
@@ -73,5 +72,3 @@
#include "BLI_math_solvers.h"
#include "BLI_math_statistics.h"
#include "BLI_math_vector.h"
-
-#endif /* __BLI_MATH_H__ */
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index c456ab0ecef..f407da3133f 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -20,8 +20,7 @@
*
* */
-#ifndef __BLI_MATH_BASE_H__
-#define __BLI_MATH_BASE_H__
+#pragma once
/** \file
* \ingroup bli
@@ -289,5 +288,3 @@ double double_round(double x, int ndigits);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_BASE_H__ */
diff --git a/source/blender/blenlib/BLI_math_base_safe.h b/source/blender/blenlib/BLI_math_base_safe.h
new file mode 100644
index 00000000000..1d6590b2faa
--- /dev/null
+++ b/source/blender/blenlib/BLI_math_base_safe.h
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * This file provides safe alternatives to common math functions like sqrt, powf.
+ * In this context "safe" means that the output is not NaN if the input is not NaN.
+ */
+
+#include "BLI_math_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+MINLINE float safe_divide(float a, float b);
+MINLINE float safe_modf(float a, float b);
+MINLINE float safe_logf(float a, float base);
+MINLINE float safe_sqrtf(float a);
+MINLINE float safe_inverse_sqrtf(float a);
+MINLINE float safe_asinf(float a);
+MINLINE float safe_acosf(float a);
+MINLINE float safe_powf(float base, float exponent);
+
+#ifdef __cplusplus
+}
+#endif
+
+#if BLI_MATH_DO_INLINE
+# include "intern/math_base_safe_inline.c"
+#endif
diff --git a/source/blender/blenlib/BLI_math_bits.h b/source/blender/blenlib/BLI_math_bits.h
index 0283622ca89..b602900bedc 100644
--- a/source/blender/blenlib/BLI_math_bits.h
+++ b/source/blender/blenlib/BLI_math_bits.h
@@ -15,8 +15,7 @@
*
* */
-#ifndef __BLI_MATH_BITS_H__
-#define __BLI_MATH_BITS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -68,5 +67,3 @@ MINLINE float xor_fl(float x, int y);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_BITS_H__ */
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index ba95da4092e..943f0fc764f 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -20,8 +20,7 @@
*
* */
-#ifndef __BLI_MATH_COLOR_H__
-#define __BLI_MATH_COLOR_H__
+#pragma once
/** \file
* \ingroup bli
@@ -148,8 +147,12 @@ void blackbody_temperature_to_rgb_table(float *r_table, int width, float min, fl
/********* lift/gamma/gain / ASC-CDL conversion ***********/
-void lift_gamma_gain_to_asc_cdl(
- float *lift, float *gamma, float *gain, float *offset, float *slope, float *power);
+void lift_gamma_gain_to_asc_cdl(const float *lift,
+ const float *gamma,
+ const float *gain,
+ float *offset,
+ float *slope,
+ float *power);
#if BLI_MATH_DO_INLINE
# include "intern/math_color_inline.c"
@@ -158,5 +161,3 @@ void lift_gamma_gain_to_asc_cdl(
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_COLOR_H__ */
diff --git a/source/blender/blenlib/BLI_math_color_blend.h b/source/blender/blenlib/BLI_math_color_blend.h
index 60ada1e4509..d5e4eedb1a6 100644
--- a/source/blender/blenlib/BLI_math_color_blend.h
+++ b/source/blender/blenlib/BLI_math_color_blend.h
@@ -20,8 +20,7 @@
*
* */
-#ifndef __BLI_MATH_COLOR_BLEND_H__
-#define __BLI_MATH_COLOR_BLEND_H__
+#pragma once
/** \file
* \ingroup bli
@@ -151,5 +150,3 @@ MINLINE void blend_color_interpolate_float(float dst[4],
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_COLOR_BLEND_H__ */
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index f51486c5e7b..3d1edb9c3b1 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -20,8 +20,7 @@
*
* */
-#ifndef __BLI_MATH_GEOM_H__
-#define __BLI_MATH_GEOM_H__
+#pragma once
/** \file
* \ingroup bli
@@ -454,11 +453,11 @@ bool isect_ray_seg_v2(const float ray_origin[2],
float *r_lambda,
float *r_u);
-bool isect_ray_seg_v3(const float ray_origin[3],
- const float ray_direction[3],
- const float v0[3],
- const float v1[3],
- float *r_lambda);
+bool isect_ray_line_v3(const float ray_origin[3],
+ const float ray_direction[3],
+ const float v0[3],
+ const float v1[3],
+ float *r_lambda);
/* point in polygon */
bool isect_point_poly_v2(const float pt[2],
@@ -671,6 +670,13 @@ void projmat_dimensions(const float projmat[4][4],
float *r_top,
float *r_near,
float *r_far);
+void projmat_dimensions_db(const float projmat[4][4],
+ double *r_left,
+ double *r_right,
+ double *r_bottom,
+ double *r_top,
+ double *r_near,
+ double *r_far);
void projmat_from_subregion(const float projmat[4][4],
const int win_size[2],
@@ -818,5 +824,3 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_GEOM_H__ */
diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h
index 3e32a517471..506386f8d25 100644
--- a/source/blender/blenlib/BLI_math_inline.h
+++ b/source/blender/blenlib/BLI_math_inline.h
@@ -20,8 +20,7 @@
*
* */
-#ifndef __BLI_MATH_INLINE_H__
-#define __BLI_MATH_INLINE_H__
+#pragma once
/** \file
* \ingroup bli
@@ -56,5 +55,3 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_INLINE_H__ */
diff --git a/source/blender/blenlib/BLI_math_interp.h b/source/blender/blenlib/BLI_math_interp.h
index 0f3032fa625..3e9839b4d3a 100644
--- a/source/blender/blenlib/BLI_math_interp.h
+++ b/source/blender/blenlib/BLI_math_interp.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_MATH_INTERP_H__
-#define __BLI_MATH_INTERP_H__
+#pragma once
/** \file
* \ingroup bli
@@ -95,5 +94,3 @@ void BLI_ewa_filter(const int width,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_INTERP_H__ */
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 2d11797bc34..a00fdaa0ae9 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -19,8 +19,7 @@
* The Original Code is: some of this file.
* */
-#ifndef __BLI_MATH_MATRIX_H__
-#define __BLI_MATH_MATRIX_H__
+#pragma once
/** \file
* \ingroup bli
@@ -64,7 +63,7 @@ void swap_m3m3(float A[3][3], float B[3][3]);
void swap_m4m4(float A[4][4], float B[4][4]);
/* Build index shuffle matrix */
-void shuffle_m4(float R[4][4], int index[4]);
+void shuffle_m4(float R[4][4], const int index[4]);
/******************************** Arithmetic *********************************/
@@ -399,5 +398,3 @@ void print_m4(const char *str, const float M[4][4]);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_MATRIX_H__ */
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index b7ae35b2e23..61708528e24 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -20,8 +20,7 @@
*
* */
-#ifndef __BLI_MATH_ROTATION_H__
-#define __BLI_MATH_ROTATION_H__
+#pragma once
/** \file
* \ingroup bli
@@ -246,5 +245,3 @@ bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3]
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_ROTATION_H__ */
diff --git a/source/blender/blenlib/BLI_math_solvers.h b/source/blender/blenlib/BLI_math_solvers.h
index 193bbdd4e8c..9b2d1eedec7 100644
--- a/source/blender/blenlib/BLI_math_solvers.h
+++ b/source/blender/blenlib/BLI_math_solvers.h
@@ -17,8 +17,7 @@
* All rights reserved.
* */
-#ifndef __BLI_MATH_SOLVERS_H__
-#define __BLI_MATH_SOLVERS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -76,5 +75,3 @@ bool BLI_newton3d_solve(Newton3D_DeltaFunc func_delta,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_SOLVERS_H__ */
diff --git a/source/blender/blenlib/BLI_math_statistics.h b/source/blender/blenlib/BLI_math_statistics.h
index a9f9ae39506..aebc445002b 100644
--- a/source/blender/blenlib/BLI_math_statistics.h
+++ b/source/blender/blenlib/BLI_math_statistics.h
@@ -17,8 +17,7 @@
* All rights reserved.
* */
-#ifndef __BLI_MATH_STATISTICS_H__
-#define __BLI_MATH_STATISTICS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -57,5 +56,3 @@ void BLI_covariance_m3_v3n(const float (*cos_v3)[3],
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_STATISTICS_H__ */
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index d46c02a961c..1ccfe5d86b1 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -20,8 +20,7 @@
*
* */
-#ifndef __BLI_MATH_VECTOR_H__
-#define __BLI_MATH_VECTOR_H__
+#pragma once
/** \file
* \ingroup bli
@@ -133,6 +132,7 @@ MINLINE void sub_v3_v3v3_db(double r[3], const double a[3], const double b[3]);
MINLINE void sub_v4_v4(float r[4], const float a[4]);
MINLINE void sub_v4_v4v4(float r[4], const float a[4], const float b[4]);
+MINLINE void sub_v2db_v2fl_v2fl(double r[2], const float a[2], const float b[2]);
MINLINE void sub_v3db_v3fl_v3fl(double r[3], const float a[3], const float b[3]);
MINLINE void mul_v2_fl(float r[2], float f);
@@ -205,6 +205,7 @@ MINLINE double dot_v3db_v3fl(const double a[3], const float b[3]) ATTR_WARN_UNUS
MINLINE double dot_v3v3_db(const double a[3], const double b[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
+MINLINE double cross_v2v2_db(const double a[2], const double b[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3]);
MINLINE void cross_v3_v3v3_db(double r[3], const double a[3], const double b[3]);
@@ -221,6 +222,7 @@ MINLINE float len_manhattan_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE int len_manhattan_v2_int(const int v[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_manhattan_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT;
+MINLINE double len_v2_db(const double v[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE double len_v2v2_db(const double a[2], const double b[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE float len_v2v2_int(const int v1[2], const int v2[2]);
@@ -523,5 +525,3 @@ void mul_vn_db(double *array_tar, const int size, const double f);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MATH_VECTOR_H__ */
diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h
index e0aff82e874..87a320e336d 100644
--- a/source/blender/blenlib/BLI_memarena.h
+++ b/source/blender/blenlib/BLI_memarena.h
@@ -21,8 +21,7 @@
* \ingroup bli
*/
-#ifndef __BLI_MEMARENA_H__
-#define __BLI_MEMARENA_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -55,5 +54,3 @@ void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MEMARENA_H__ */
diff --git a/source/blender/blenlib/BLI_memblock.h b/source/blender/blenlib/BLI_memblock.h
index 8f66ee3b9cb..cb6b31d54e0 100644
--- a/source/blender/blenlib/BLI_memblock.h
+++ b/source/blender/blenlib/BLI_memblock.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_MEMBLOCK_H__
-#define __BLI_MEMBLOCK_H__
+#pragma once
/** \file
* \ingroup bli
@@ -63,5 +62,3 @@ void *BLI_memblock_elem_get(BLI_memblock *mblk, int chunk, int elem) ATTR_WARN_U
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MEMBLOCK_H__ */
diff --git a/source/blender/blenlib/BLI_memiter.h b/source/blender/blenlib/BLI_memiter.h
index 4aa9cdb6b6c..c7a715309e1 100644
--- a/source/blender/blenlib/BLI_memiter.h
+++ b/source/blender/blenlib/BLI_memiter.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_MEMITER_H__
-#define __BLI_MEMITER_H__
+#pragma once
/** \file
* \ingroup bli
@@ -69,5 +68,3 @@ void *BLI_memiter_iter_step_size(BLI_memiter_handle *iter, uint *r_size) ATTR_WA
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MEMITER_H__ */
diff --git a/source/blender/blenlib/BLI_memory_utils.hh b/source/blender/blenlib/BLI_memory_utils.hh
index 44d25340778..d663bf4038d 100644
--- a/source/blender/blenlib/BLI_memory_utils.hh
+++ b/source/blender/blenlib/BLI_memory_utils.hh
@@ -14,67 +14,90 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_MEMORY_UTILS_HH__
-#define __BLI_MEMORY_UTILS_HH__
+#pragma once
/** \file
* \ingroup bli
+ * Some of the functions below have very similar alternatives in the standard library. However, it
+ * is rather annoying to use those when debugging. Therefore, some more specialized and easier to
+ * debug functions are provided here.
*/
#include <memory>
#include <new>
+#include <type_traits>
#include "BLI_utildefines.h"
namespace blender {
/**
- * Call the default constructor on n consecutive elements. For trivially constructible types, this
- * does nothing.
+ * Call the destructor on n consecutive values. For trivially destructible types, this does
+ * nothing.
+ *
+ * Exception Safety: Destructors shouldn't throw exceptions.
*
* Before:
- * ptr: uninitialized
- * After:
* ptr: initialized
+ * After:
+ * ptr: uninitialized
*/
-template<typename T> void default_construct_n(T *ptr, uint n)
+template<typename T> void destruct_n(T *ptr, int64_t n)
{
+ BLI_assert(n >= 0);
+
+ static_assert(std::is_nothrow_destructible_v<T>,
+ "This should be true for all types. Destructors are noexcept by default.");
+
/* This is not strictly necessary, because the loop below will be optimized away anyway. It is
* nice to make behavior this explicitly, though. */
- if (std::is_trivially_constructible<T>::value) {
+ if (std::is_trivially_destructible_v<T>) {
return;
}
- for (uint i = 0; i < n; i++) {
- new ((void *)(ptr + i)) T;
+ for (int64_t i = 0; i < n; i++) {
+ ptr[i].~T();
}
}
/**
- * Call the destructor on n consecutive values. For trivially destructible types, this does
- * nothing.
+ * Call the default constructor on n consecutive elements. For trivially constructible types, this
+ * does nothing.
+ *
+ * Exception Safety: Strong.
*
* Before:
- * ptr: initialized
- * After:
* ptr: uninitialized
+ * After:
+ * ptr: initialized
*/
-template<typename T> void destruct_n(T *ptr, uint n)
+template<typename T> void default_construct_n(T *ptr, int64_t n)
{
+ BLI_assert(n >= 0);
+
/* This is not strictly necessary, because the loop below will be optimized away anyway. It is
* nice to make behavior this explicitly, though. */
- if (std::is_trivially_destructible<T>::value) {
+ if (std::is_trivially_constructible_v<T>) {
return;
}
- for (uint i = 0; i < n; i++) {
- ptr[i].~T();
+ int64_t current = 0;
+ try {
+ for (; current < n; current++) {
+ new ((void *)(ptr + current)) T;
+ }
+ }
+ catch (...) {
+ destruct_n(ptr, current);
+ throw;
}
}
/**
* Copy n values from src to dst.
*
+ * Exception Safety: Basic.
+ *
* Before:
* src: initialized
* dst: initialized
@@ -82,9 +105,11 @@ template<typename T> void destruct_n(T *ptr, uint n)
* src: initialized
* dst: initialized
*/
-template<typename T> void initialized_copy_n(const T *src, uint n, T *dst)
+template<typename T> void initialized_copy_n(const T *src, int64_t n, T *dst)
{
- for (uint i = 0; i < n; i++) {
+ BLI_assert(n >= 0);
+
+ for (int64_t i = 0; i < n; i++) {
dst[i] = src[i];
}
}
@@ -92,6 +117,8 @@ template<typename T> void initialized_copy_n(const T *src, uint n, T *dst)
/**
* Copy n values from src to dst.
*
+ * Exception Safety: Strong.
+ *
* Before:
* src: initialized
* dst: uninitialized
@@ -99,16 +126,56 @@ template<typename T> void initialized_copy_n(const T *src, uint n, T *dst)
* src: initialized
* dst: initialized
*/
-template<typename T> void uninitialized_copy_n(const T *src, uint n, T *dst)
+template<typename T> void uninitialized_copy_n(const T *src, int64_t n, T *dst)
{
- for (uint i = 0; i < n; i++) {
- new ((void *)(dst + i)) T(src[i]);
+ BLI_assert(n >= 0);
+
+ int64_t current = 0;
+ try {
+ for (; current < n; current++) {
+ new ((void *)(dst + current)) T(src[current]);
+ }
+ }
+ catch (...) {
+ destruct_n(dst, current);
+ throw;
+ }
+}
+
+/**
+ * Convert n values from type `From` to type `To`.
+ *
+ * Exception Safety: Strong.
+ *
+ * Before:
+ * src: initialized
+ * dst: uninitialized
+ * After:
+ * src: initialized
+ * dst: initialized
+ */
+template<typename From, typename To>
+void uninitialized_convert_n(const From *src, int64_t n, To *dst)
+{
+ BLI_assert(n >= 0);
+
+ int64_t current = 0;
+ try {
+ for (; current < n; current++) {
+ new ((void *)(dst + current)) To((To)src[current]);
+ }
+ }
+ catch (...) {
+ destruct_n(dst, current);
+ throw;
}
}
/**
* Move n values from src to dst.
*
+ * Exception Safety: Basic.
+ *
* Before:
* src: initialized
* dst: initialized
@@ -116,9 +183,11 @@ template<typename T> void uninitialized_copy_n(const T *src, uint n, T *dst)
* src: initialized, moved-from
* dst: initialized
*/
-template<typename T> void initialized_move_n(T *src, uint n, T *dst)
+template<typename T> void initialized_move_n(T *src, int64_t n, T *dst)
{
- for (uint i = 0; i < n; i++) {
+ BLI_assert(n >= 0);
+
+ for (int64_t i = 0; i < n; i++) {
dst[i] = std::move(src[i]);
}
}
@@ -126,6 +195,8 @@ template<typename T> void initialized_move_n(T *src, uint n, T *dst)
/**
* Move n values from src to dst.
*
+ * Exception Safety: Basic.
+ *
* Before:
* src: initialized
* dst: uninitialized
@@ -133,10 +204,19 @@ template<typename T> void initialized_move_n(T *src, uint n, T *dst)
* src: initialized, moved-from
* dst: initialized
*/
-template<typename T> void uninitialized_move_n(T *src, uint n, T *dst)
+template<typename T> void uninitialized_move_n(T *src, int64_t n, T *dst)
{
- for (uint i = 0; i < n; i++) {
- new ((void *)(dst + i)) T(std::move(src[i]));
+ BLI_assert(n >= 0);
+
+ int64_t current = 0;
+ try {
+ for (; current < n; current++) {
+ new ((void *)(dst + current)) T(std::move(src[current]));
+ }
+ }
+ catch (...) {
+ destruct_n(dst, current);
+ throw;
}
}
@@ -144,6 +224,8 @@ template<typename T> void uninitialized_move_n(T *src, uint n, T *dst)
* Relocate n values from src to dst. Relocation is a move followed by destruction of the src
* value.
*
+ * Exception Safety: Basic.
+ *
* Before:
* src: initialized
* dst: initialized
@@ -151,8 +233,10 @@ template<typename T> void uninitialized_move_n(T *src, uint n, T *dst)
* src: uninitialized
* dst: initialized
*/
-template<typename T> void initialized_relocate_n(T *src, uint n, T *dst)
+template<typename T> void initialized_relocate_n(T *src, int64_t n, T *dst)
{
+ BLI_assert(n >= 0);
+
initialized_move_n(src, n, dst);
destruct_n(src, n);
}
@@ -161,6 +245,8 @@ template<typename T> void initialized_relocate_n(T *src, uint n, T *dst)
* Relocate n values from src to dst. Relocation is a move followed by destruction of the src
* value.
*
+ * Exception Safety: Basic.
+ *
* Before:
* src: initialized
* dst: uninitialized
@@ -168,8 +254,10 @@ template<typename T> void initialized_relocate_n(T *src, uint n, T *dst)
* src: uninitialized
* dst: initialized
*/
-template<typename T> void uninitialized_relocate_n(T *src, uint n, T *dst)
+template<typename T> void uninitialized_relocate_n(T *src, int64_t n, T *dst)
{
+ BLI_assert(n >= 0);
+
uninitialized_move_n(src, n, dst);
destruct_n(src, n);
}
@@ -177,14 +265,18 @@ template<typename T> void uninitialized_relocate_n(T *src, uint n, T *dst)
/**
* Copy the value to n consecutive elements.
*
+ * Exception Safety: Basic.
+ *
* Before:
* dst: initialized
* After:
* dst: initialized
*/
-template<typename T> void initialized_fill_n(T *dst, uint n, const T &value)
+template<typename T> void initialized_fill_n(T *dst, int64_t n, const T &value)
{
- for (uint i = 0; i < n; i++) {
+ BLI_assert(n >= 0);
+
+ for (int64_t i = 0; i < n; i++) {
dst[i] = value;
}
}
@@ -192,15 +284,26 @@ template<typename T> void initialized_fill_n(T *dst, uint n, const T &value)
/**
* Copy the value to n consecutive elements.
*
+ * Exception Safety: Strong.
+ *
* Before:
* dst: uninitialized
* After:
* dst: initialized
*/
-template<typename T> void uninitialized_fill_n(T *dst, uint n, const T &value)
+template<typename T> void uninitialized_fill_n(T *dst, int64_t n, const T &value)
{
- for (uint i = 0; i < n; i++) {
- new ((void *)(dst + i)) T(value);
+ BLI_assert(n >= 0);
+
+ int64_t current = 0;
+ try {
+ for (; current < n; current++) {
+ new ((void *)(dst + current)) T(value);
+ }
+ }
+ catch (...) {
+ destruct_n(dst, current);
+ throw;
}
}
@@ -218,12 +321,8 @@ template<typename T> struct DestructValueAtAddress {
template<typename T> using destruct_ptr = std::unique_ptr<T, DestructValueAtAddress<T>>;
/**
- * An `AlignedBuffer` is simply a byte array with the given size and alignment. The buffer will
+ * An `AlignedBuffer` is a byte array with at least the given size and alignment. The buffer will
* not be initialized by the default constructor.
- *
- * This can be used to reserve memory for C++ objects whose lifetime is different from the
- * lifetime of the object they are embedded in. It's used by containers with small buffer
- * optimization and hash table implementations.
*/
template<size_t Size, size_t Alignment> class alignas(Alignment) AlignedBuffer {
private:
@@ -231,6 +330,16 @@ template<size_t Size, size_t Alignment> class alignas(Alignment) AlignedBuffer {
char buffer_[(Size > 0) ? Size : 1];
public:
+ operator void *()
+ {
+ return (void *)buffer_;
+ }
+
+ operator const void *() const
+ {
+ return (void *)buffer_;
+ }
+
void *ptr()
{
return (void *)buffer_;
@@ -243,12 +352,79 @@ template<size_t Size, size_t Alignment> class alignas(Alignment) AlignedBuffer {
};
/**
+ * This can be used to reserve memory for C++ objects whose lifetime is different from the
+ * lifetime of the object they are embedded in. It's used by containers with small buffer
+ * optimization and hash table implementations.
+ */
+template<typename T, int64_t Size = 1> class TypedBuffer {
+ private:
+ AlignedBuffer<sizeof(T) * (size_t)Size, alignof(T)> buffer_;
+
+ public:
+ operator T *()
+ {
+ return (T *)&buffer_;
+ }
+
+ operator const T *() const
+ {
+ return (const T *)&buffer_;
+ }
+
+ T &operator*()
+ {
+ return *(T *)&buffer_;
+ }
+
+ const T &operator*() const
+ {
+ return *(const T *)&buffer_;
+ }
+
+ T *ptr()
+ {
+ return (T *)&buffer_;
+ }
+
+ const T *ptr() const
+ {
+ return (const T *)&buffer_;
+ }
+
+ T &ref()
+ {
+ return *(T *)&buffer_;
+ }
+
+ const T &ref() const
+ {
+ return *(const T *)&buffer_;
+ }
+};
+
+/**
* This can be used by container constructors. A parameter of this type should be used to indicate
* that the constructor does not construct the elements.
*/
class NoInitialization {
};
-} // namespace blender
+/**
+ * Helper variable that checks if a pointer type can be converted into another pointer type without
+ * issues. Possible issues are casting away const and casting a pointer to a child class.
+ * Adding const or casting to a parent class is fine.
+ */
+template<typename From, typename To>
+inline constexpr bool is_convertible_pointer_v =
+ std::is_convertible_v<From, To> &&std::is_pointer_v<From> &&std::is_pointer_v<To>;
-#endif /* __BLI_MEMORY_UTILS_HH__ */
+/**
+ * Inline buffers for small-object-optimization should be disable by default. Otherwise we might
+ * get large unexpected allocations on the stack.
+ */
+inline constexpr int64_t default_inline_buffer_capacity(size_t element_size)
+{
+ return ((int64_t)element_size < 100) ? 4 : 0;
+}
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h
index 3749f9e1b76..3ee6f182593 100644
--- a/source/blender/blenlib/BLI_mempool.h
+++ b/source/blender/blenlib/BLI_mempool.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_MEMPOOL_H__
-#define __BLI_MEMPOOL_H__
+#pragma once
/** \file
* \ingroup bli
@@ -97,5 +96,3 @@ void BLI_mempool_iter_threadsafe_free(BLI_mempool_iter *iter_arr) ATTR_NONNULL()
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_MEMPOOL_H__ */
diff --git a/source/blender/blenlib/BLI_multi_value_map.hh b/source/blender/blenlib/BLI_multi_value_map.hh
new file mode 100644
index 00000000000..018f080e633
--- /dev/null
+++ b/source/blender/blenlib/BLI_multi_value_map.hh
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * A `blender::MultiValueMap<Key, Value>` is an unordered associative container that stores
+ * key-value pairs. It is different from `blender::Map` in that it can store multiple values for
+ * the same key. The list of values that corresponds to a specific key can contain duplicates
+ * and their order is maintained.
+ *
+ * This data structure is different from a `std::multi_map`, because multi_map can store the same
+ * key more than once and MultiValueMap can't.
+ *
+ * Currently, this class exists mainly for convenience. There are no performance benefits over
+ * using Map<Key, Vector<Value>>. In the future, a better implementation for this data structure
+ * can be developed.
+ */
+
+#include "BLI_map.hh"
+#include "BLI_vector.hh"
+
+namespace blender {
+
+template<typename Key, typename Value> class MultiValueMap {
+ private:
+ using MapType = Map<Key, Vector<Value>>;
+ MapType map_;
+
+ public:
+ /**
+ * Add a new value for the given key. If the map contains the key already, the value will be
+ * appended to the list of corresponding values.
+ */
+ void add(const Key &key, const Value &value)
+ {
+ this->add_as(key, value);
+ }
+ void add(const Key &key, Value &&value)
+ {
+ this->add_as(key, std::move(value));
+ }
+ void add(Key &&key, const Value &value)
+ {
+ this->add_as(std::move(key), value);
+ }
+ void add(Key &&key, Value &&value)
+ {
+ this->add_as(std::move(key), std::move(value));
+ }
+ template<typename ForwardKey, typename ForwardValue>
+ void add_as(ForwardKey &&key, ForwardValue &&value)
+ {
+ Vector<Value> &vector = map_.lookup_or_add_default_as(std::forward<ForwardKey>(key));
+ vector.append(std::forward<ForwardValue>(value));
+ }
+
+ /**
+ * Add all given values to the key.
+ */
+ void add_multiple(const Key &key, Span<Value> values)
+ {
+ this->add_multiple_as(key, values);
+ }
+ void add_multiple(Key &&key, Span<Value> values)
+ {
+ this->add_multiple_as(std::move(key), values);
+ }
+ template<typename ForwardKey> void add_multiple_as(ForwardKey &&key, Span<Value> values)
+ {
+ Vector<Value> &vector = map_.lookup_or_add_default_as(std::forward<ForwardKey>(key));
+ vector.extend(values);
+ }
+
+ /**
+ * Get a span to all the values that are stored for the given key.
+ */
+ Span<Value> lookup(const Key &key) const
+ {
+ return this->lookup_as(key);
+ }
+ template<typename ForwardKey> Span<Value> lookup_as(const ForwardKey &key) const
+ {
+ const Vector<Value> *vector = map_.lookup_ptr_as(key);
+ if (vector != nullptr) {
+ return vector->as_span();
+ }
+ return {};
+ }
+
+ /**
+ * Note: This signature will change when the implementation changes.
+ */
+ typename MapType::ItemIterator items() const
+ {
+ return map_.items();
+ }
+
+ /**
+ * Note: This signature will change when the implementation changes.
+ */
+ typename MapType::KeyIterator keys() const
+ {
+ return map_.keys();
+ }
+
+ /**
+ * Note: This signature will change when the implementation changes.
+ */
+ typename MapType::ValueIterator values() const
+ {
+ return map_.values();
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_noise.h b/source/blender/blenlib/BLI_noise.h
index 32731ff24fc..cb66b0552df 100644
--- a/source/blender/blenlib/BLI_noise.h
+++ b/source/blender/blenlib/BLI_noise.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_NOISE_H__
-#define __BLI_NOISE_H__
+#pragma once
/** \file
* \ingroup bli
@@ -79,5 +78,3 @@ void cellNoiseV(float x, float y, float z, float r_ca[3]);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 30823773d6c..05c256ccf1c 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BLI_PATH_UTIL_H__
-#define __BLI_PATH_UTIL_H__
+#pragma once
/** \file
* \ingroup bli
@@ -158,5 +157,3 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_PATH_UTIL_H__ */
diff --git a/source/blender/blenlib/BLI_polyfill_2d.h b/source/blender/blenlib/BLI_polyfill_2d.h
index cb12b73c1d5..ca63ea5af87 100644
--- a/source/blender/blenlib/BLI_polyfill_2d.h
+++ b/source/blender/blenlib/BLI_polyfill_2d.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_POLYFILL_2D_H__
-#define __BLI_POLYFILL_2D_H__
+#pragma once
/** \file
* \ingroup bli
@@ -45,5 +44,3 @@ void BLI_polyfill_calc(const float (*coords)[2],
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_POLYFILL_2D_H__ */
diff --git a/source/blender/blenlib/BLI_polyfill_2d_beautify.h b/source/blender/blenlib/BLI_polyfill_2d_beautify.h
index 94c4b412225..2c5296269ae 100644
--- a/source/blender/blenlib/BLI_polyfill_2d_beautify.h
+++ b/source/blender/blenlib/BLI_polyfill_2d_beautify.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_POLYFILL_2D_BEAUTIFY_H__
-#define __BLI_POLYFILL_2D_BEAUTIFY_H__
+#pragma once
/** \file
* \ingroup bli
@@ -51,5 +50,3 @@ float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2],
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_POLYFILL_2D_BEAUTIFY_H__ */
diff --git a/source/blender/blenlib/BLI_probing_strategies.hh b/source/blender/blenlib/BLI_probing_strategies.hh
index d2b16ac3516..a37a979b754 100644
--- a/source/blender/blenlib/BLI_probing_strategies.hh
+++ b/source/blender/blenlib/BLI_probing_strategies.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_PROBING_STRATEGIES_HH__
-#define __BLI_PROBING_STRATEGIES_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -25,17 +24,17 @@
* values based on an initial hash value.
*
* A probing strategy has to implement the following methods:
- * - Constructor(uint32_t hash): Start a new probing sequence based on the given hash.
- * - get() const -> uint32_t: Get the current value in the sequence.
+ * - Constructor(uint64_t hash): Start a new probing sequence based on the given hash.
+ * - get() const -> uint64_t: Get the current value in the sequence.
* - next() -> void: Update the internal state, so that the next value can be accessed with get().
- * - linear_steps() -> uint32_t: Returns number of linear probing steps that should be done.
+ * - linear_steps() -> int64_t: Returns number of linear probing steps that should be done.
*
* Using linear probing steps between larger jumps can result in better performance, due to
* improved cache usage. It's a way of getting the benefits or linear probing without the
* clustering issues. However, more linear steps can also make things slower when the initial hash
* produces many collisions.
*
- * Every probing strategy has to guarantee, that every possible uint32_t is returned eventually.
+ * Every probing strategy has to guarantee, that every possible uint64_t is returned eventually.
* This is necessary for correctness. If this is not the case, empty slots might not be found.
*
* The SLOT_PROBING_BEGIN and SLOT_PROBING_END macros can be used to implement a loop that iterates
@@ -65,10 +64,10 @@ namespace blender {
*/
class LinearProbingStrategy {
private:
- uint32_t hash_;
+ uint64_t hash_;
public:
- LinearProbingStrategy(const uint32_t hash) : hash_(hash)
+ LinearProbingStrategy(const uint64_t hash) : hash_(hash)
{
}
@@ -77,12 +76,12 @@ class LinearProbingStrategy {
hash_++;
}
- uint32_t get() const
+ uint64_t get() const
{
return hash_;
}
- uint32_t linear_steps() const
+ int64_t linear_steps() const
{
return UINT32_MAX;
}
@@ -101,12 +100,12 @@ class LinearProbingStrategy {
*/
class QuadraticProbingStrategy {
private:
- uint32_t original_hash_;
- uint32_t current_hash_;
- uint32_t iteration_;
+ uint64_t original_hash_;
+ uint64_t current_hash_;
+ uint64_t iteration_;
public:
- QuadraticProbingStrategy(const uint32_t hash)
+ QuadraticProbingStrategy(const uint64_t hash)
: original_hash_(hash), current_hash_(hash), iteration_(1)
{
}
@@ -117,12 +116,12 @@ class QuadraticProbingStrategy {
iteration_++;
}
- uint32_t get() const
+ uint64_t get() const
{
return current_hash_;
}
- uint32_t linear_steps() const
+ int64_t linear_steps() const
{
return 1;
}
@@ -138,13 +137,13 @@ class QuadraticProbingStrategy {
* PreShuffle: When true, the initial call to next() will be done to the constructor. This can help
* when the hash function has put little information into the lower bits.
*/
-template<uint32_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingStrategy {
+template<uint64_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingStrategy {
private:
- uint32_t hash_;
- uint32_t perturb_;
+ uint64_t hash_;
+ uint64_t perturb_;
public:
- PythonProbingStrategy(const uint32_t hash) : hash_(hash), perturb_(hash)
+ PythonProbingStrategy(const uint64_t hash) : hash_(hash), perturb_(hash)
{
if (PreShuffle) {
this->next();
@@ -157,12 +156,12 @@ template<uint32_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingS
hash_ = 5 * hash_ + 1 + perturb_;
}
- uint32_t get() const
+ uint64_t get() const
{
return hash_;
}
- uint32_t linear_steps() const
+ int64_t linear_steps() const
{
return LinearSteps;
}
@@ -173,13 +172,13 @@ template<uint32_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingS
* method. This way more bits are taken into account earlier. After a couple of collisions (that
* should happen rarely), it will fallback to a sequence that hits every slot.
*/
-template<uint32_t LinearSteps = 2, bool PreShuffle = false> class ShuffleProbingStrategy {
+template<uint64_t LinearSteps = 2, bool PreShuffle = false> class ShuffleProbingStrategy {
private:
- uint32_t hash_;
- uint32_t perturb_;
+ uint64_t hash_;
+ uint64_t perturb_;
public:
- ShuffleProbingStrategy(const uint32_t hash) : hash_(hash), perturb_(hash)
+ ShuffleProbingStrategy(const uint64_t hash) : hash_(hash), perturb_(hash)
{
if (PreShuffle) {
this->next();
@@ -197,12 +196,12 @@ template<uint32_t LinearSteps = 2, bool PreShuffle = false> class ShuffleProbing
}
}
- uint32_t get() const
+ uint64_t get() const
{
return hash_;
}
- uint32_t linear_steps() const
+ int64_t linear_steps() const
{
return LinearSteps;
}
@@ -233,10 +232,10 @@ using DefaultProbingStrategy = PythonProbingStrategy<>;
#define SLOT_PROBING_BEGIN(PROBING_STRATEGY, HASH, MASK, R_SLOT_INDEX) \
PROBING_STRATEGY probing_strategy(HASH); \
do { \
- uint32_t linear_offset = 0; \
- uint32_t current_hash = probing_strategy.get(); \
+ int64_t linear_offset = 0; \
+ uint64_t current_hash = probing_strategy.get(); \
do { \
- uint32_t R_SLOT_INDEX = (current_hash + linear_offset) & MASK;
+ int64_t R_SLOT_INDEX = (int64_t)((current_hash + (uint64_t)linear_offset) & MASK);
#define SLOT_PROBING_END() \
} while (++linear_offset < probing_strategy.linear_steps()); \
@@ -246,5 +245,3 @@ using DefaultProbingStrategy = PythonProbingStrategy<>;
// clang-format on
} // namespace blender
-
-#endif /* __BLI_PROBING_STRATEGIES_HH__ */
diff --git a/source/blender/blenlib/BLI_quadric.h b/source/blender/blenlib/BLI_quadric.h
index 1383a19ed1f..fdb7d1e67ac 100644
--- a/source/blender/blenlib/BLI_quadric.h
+++ b/source/blender/blenlib/BLI_quadric.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_QUADRIC_H__
-#define __BLI_QUADRIC_H__
+#pragma once
/** \file
* \ingroup bli
@@ -50,5 +49,3 @@ bool BLI_quadric_optimize(const Quadric *q, double v[3], const double epsilon);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_QUADRIC_H__ */
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h
index ae78ea3af16..78a323c2431 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_RAND_H__
-#define __BLI_RAND_H__
+#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_sys_types.h"
@@ -105,16 +104,14 @@ int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread) ATTR_WARN_UNUSED_R
/** Return the _n_th number of the given low-discrepancy sequence. */
void BLI_halton_1d(unsigned int prime, double offset, int n, double *r);
-void BLI_halton_2d(unsigned int prime[2], double offset[2], int n, double *r);
-void BLI_halton_3d(unsigned int prime[3], double offset[3], int n, double *r);
+void BLI_halton_2d(const unsigned int prime[2], double offset[2], int n, double *r);
+void BLI_halton_3d(const unsigned int prime[3], double offset[3], int n, double *r);
void BLI_hammersley_1d(unsigned int n, double *r);
/** Return the whole low-discrepancy sequence up to _n_. */
-void BLI_halton_2d_sequence(unsigned int prime[2], double offset[2], int n, double *r);
+void BLI_halton_2d_sequence(const unsigned int prime[2], double offset[2], int n, double *r);
void BLI_hammersley_2d_sequence(unsigned int n, double *r);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_RAND_H__ */
diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh
new file mode 100644
index 00000000000..b3c9c376141
--- /dev/null
+++ b/source/blender/blenlib/BLI_rand.hh
@@ -0,0 +1,144 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#pragma once
+
+#include "BLI_float2.hh"
+#include "BLI_float3.hh"
+#include "BLI_math.h"
+#include "BLI_span.hh"
+#include "BLI_utildefines.h"
+
+namespace blender {
+
+class RandomNumberGenerator {
+ private:
+ uint64_t x_;
+
+ public:
+ RandomNumberGenerator(uint32_t seed = 0)
+ {
+ this->seed(seed);
+ }
+
+ /**
+ * Set the seed for future random numbers.
+ */
+ void seed(uint32_t seed)
+ {
+ constexpr uint64_t lowseed = 0x330E;
+ x_ = (((uint64_t)seed) << 16) | lowseed;
+ }
+
+ void seed_random(uint32_t seed);
+
+ uint32_t get_uint32()
+ {
+ this->step();
+ return (uint32_t)(x_ >> 17);
+ }
+
+ int32_t get_int32()
+ {
+ this->step();
+ return (int32_t)(x_ >> 17);
+ }
+
+ /**
+ * \return Random value (0..N), but never N.
+ */
+ int32_t get_int32(int32_t max_exclusive)
+ {
+ BLI_assert(max_exclusive > 0);
+ return this->get_int32() % max_exclusive;
+ }
+
+ /**
+ * \return Random value (0..1), but never 1.0.
+ */
+ double get_double()
+ {
+ return (double)this->get_int32() / 0x80000000;
+ }
+
+ /**
+ * \return Random value (0..1), but never 1.0.
+ */
+ float get_float()
+ {
+ return (float)this->get_int32() / 0x80000000;
+ }
+
+ template<typename T> void shuffle(MutableSpan<T> values)
+ {
+ /* Cannot shuffle arrays of this size yet. */
+ BLI_assert(values.size() <= INT32_MAX);
+
+ for (int i = values.size() - 1; i >= 2; i--) {
+ int j = this->get_int32(i);
+ if (i != j) {
+ std::swap(values[i], values[j]);
+ }
+ }
+ }
+
+ /**
+ * Compute uniformly distributed barycentric coordinates.
+ */
+ float3 get_barycentric_coordinates()
+ {
+ float rand1 = this->get_float();
+ float rand2 = this->get_float();
+
+ if (rand1 + rand2 > 1.0f) {
+ rand1 = 1.0f - rand1;
+ rand2 = 1.0f - rand2;
+ }
+
+ return float3(rand1, rand2, 1.0f - rand1 - rand2);
+ }
+
+ float2 get_unit_float2();
+ float3 get_unit_float3();
+ float2 get_triangle_sample(float2 v1, float2 v2, float2 v3);
+ void get_bytes(MutableSpan<char> r_bytes);
+
+ /**
+ * Simulate getting \a n random values.
+ */
+ void skip(int64_t n)
+ {
+ while (n--) {
+ this->step();
+ }
+ }
+
+ private:
+ void step()
+ {
+ constexpr uint64_t multiplier = 0x5DEECE66Dll;
+ constexpr uint64_t addend = 0xB;
+ constexpr uint64_t mask = 0x0000FFFFFFFFFFFFll;
+
+ x_ = (multiplier * x_ + addend) & mask;
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index b1faae03583..ae3eb9d2144 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_RECT_H__
-#define __BLI_RECT_H__
+#pragma once
/** \file
* \ingroup bli
@@ -63,6 +62,7 @@ void BLI_rcti_translate(struct rcti *rect, int x, int y);
void BLI_rcti_recenter(struct rcti *rect, int x, int y);
void BLI_rctf_recenter(struct rctf *rect, float x, float y);
void BLI_rcti_resize(struct rcti *rect, int x, int y);
+void BLI_rcti_pad(struct rcti *rect, int pad_x, int pad_y);
void BLI_rctf_resize(struct rctf *rect, float x, float y);
void BLI_rcti_scale(rcti *rect, const float scale);
void BLI_rctf_scale(rctf *rect, const float scale);
@@ -165,5 +165,3 @@ BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_RECT_H__ */
diff --git a/source/blender/blenlib/BLI_resource_collector.hh b/source/blender/blenlib/BLI_resource_collector.hh
new file mode 100644
index 00000000000..20180f3b2c9
--- /dev/null
+++ b/source/blender/blenlib/BLI_resource_collector.hh
@@ -0,0 +1,148 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * A ResourceCollector holds an arbitrary set of resources, that will be destructed and/or freed
+ * when the ResourceCollector is destructed. This is useful when some object has to take ownership
+ * of other objects, but it does not know the type of those other objects.
+ *
+ * Resources owned by the ResourceCollector will be freed in reverse order. That allows resources
+ * that are added later to depend on resources that have been added before.
+ */
+
+#include "BLI_linear_allocator.hh"
+#include "BLI_utility_mixins.hh"
+#include "BLI_vector.hh"
+
+namespace blender {
+
+class ResourceCollector : NonCopyable, NonMovable {
+ private:
+ struct ResourceData {
+ void *data;
+ void (*free)(void *data);
+ const char *debug_name;
+ };
+
+ LinearAllocator<> m_allocator;
+ Vector<ResourceData> m_resources;
+
+ public:
+ ResourceCollector() = default;
+
+ ~ResourceCollector()
+ {
+ /* Free in reversed order. */
+ for (int64_t i = m_resources.size(); i--;) {
+ ResourceData &data = m_resources[i];
+ data.free(data.data);
+ }
+ }
+
+ /**
+ * Pass ownership of the resource to the ResourceCollector. It will be destructed and freed when
+ * the collector is destructed.
+ */
+ template<typename T> void add(std::unique_ptr<T> resource, const char *name)
+ {
+ BLI_assert(resource.get() != nullptr);
+ this->add(
+ resource.release(),
+ [](void *data) {
+ T *typed_data = reinterpret_cast<T *>(data);
+ delete typed_data;
+ },
+ name);
+ }
+
+ /**
+ * Pass ownership of the resource to the ResourceCollector. It will be destructed when the
+ * collector is destructed.
+ */
+ template<typename T> void add(destruct_ptr<T> resource, const char *name)
+ {
+ /* There is no need to keep track of such types. */
+ if (std::is_trivially_destructible_v<T>) {
+ resource.release();
+ return;
+ }
+
+ BLI_assert(resource.get() != nullptr);
+ this->add(
+ resource.release(),
+ [](void *data) {
+ T *typed_data = reinterpret_cast<T *>(data);
+ typed_data->~T();
+ },
+ name);
+ }
+
+ /**
+ * Pass ownership of some resource to the ResourceCollector. The given free function will be
+ * called when the collector is destructed.
+ */
+ void add(void *userdata, void (*free)(void *), const char *name)
+ {
+ ResourceData data;
+ data.debug_name = name;
+ data.data = userdata;
+ data.free = free;
+ m_resources.append(data);
+ }
+
+ /**
+ * Returns a reference to a linear allocator that is owned by the ResourcesCollector. Memory
+ * allocated through this allocator will be freed when the collector is destructed.
+ */
+ LinearAllocator<> &linear_allocator()
+ {
+ return m_allocator;
+ }
+
+ /**
+ * Utility method to construct an instance of type T that will be owned by the ResourceCollector.
+ */
+ template<typename T, typename... Args> T &construct(const char *name, Args &&... args)
+ {
+ T *value = m_allocator.construct<T>(std::forward<Args>(args)...);
+ this->add(destruct_ptr<T>(value), name);
+ return *value;
+ }
+
+ /**
+ * Print the names of all the resources that are owned by this ResourceCollector. This can be
+ * useful for debugging.
+ */
+ void print(StringRef name) const
+ {
+ if (m_resources.size() == 0) {
+ std::cout << "\"" << name << "\" has no resources.\n";
+ return;
+ }
+ else {
+ std::cout << "Resources for \"" << name << "\":\n";
+ for (const ResourceData &data : m_resources) {
+ std::cout << " " << data.data << ": " << data.debug_name << '\n';
+ }
+ }
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h
index 376ea9d88de..cf74bc14cac 100644
--- a/source/blender/blenlib/BLI_scanfill.h
+++ b/source/blender/blenlib/BLI_scanfill.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_SCANFILL_H__
-#define __BLI_SCANFILL_H__
+#pragma once
/** \file
* \ingroup bli
@@ -131,5 +130,3 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenlib/BLI_session_uuid.h b/source/blender/blenlib/BLI_session_uuid.h
new file mode 100644
index 00000000000..05355a85b39
--- /dev/null
+++ b/source/blender/blenlib/BLI_session_uuid.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "DNA_session_uuid_types.h"
+
+/* Generate new UUID which is unique throughout the Blender session. */
+SessionUUID BLI_session_uuid_generate(void);
+
+/* Check whether the UUID is properly generated. */
+bool BLI_session_uuid_is_generated(const SessionUUID *uuid);
+
+/* Check whether two UUIDs are identical. */
+bool BLI_session_uuid_is_equal(const SessionUUID *lhs, const SessionUUID *rhs);
+
+uint64_t BLI_session_uuid_hash_uint64(const SessionUUID *uuid);
+
+/* Utility functions to make it possible to create GHash/GSet with UUID as a key. */
+uint BLI_session_uuid_ghash_hash(const void *uuid_v);
+bool BLI_session_uuid_ghash_compare(const void *lhs_v, const void *rhs_v);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+
+namespace blender {
+
+inline const bool operator==(const SessionUUID &lhs, const SessionUUID &rhs)
+{
+ return BLI_session_uuid_is_equal(&lhs, &rhs);
+}
+
+template<typename T> struct DefaultHash;
+
+template<> struct DefaultHash<SessionUUID> {
+ uint64_t operator()(const SessionUUID &value) const
+ {
+ return BLI_session_uuid_hash_uint64(&value);
+ }
+};
+
+} // namespace blender
+
+#endif
diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh
index 09b2d170eea..eb4e258b679 100644
--- a/source/blender/blenlib/BLI_set.hh
+++ b/source/blender/blenlib/BLI_set.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_SET_HH__
-#define __BLI_SET_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -89,11 +88,8 @@ template<
* The minimum number of elements that can be stored in this Set without doing a heap
* allocation. This is useful when you expect to have many small sets. However, keep in mind
* that (unlike vector) initializing a set has a O(n) cost in the number of slots.
- *
- * When Key is large, the small buffer optimization is disabled by default to avoid large
- * unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint32_t InlineBufferCapacity = (sizeof(Key) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key)),
/**
* The strategy used to deal with collisions. They are defined in BLI_probing_strategies.hh.
*/
@@ -128,20 +124,20 @@ class Set {
* Slots are either empty, occupied or removed. The number of occupied slots can be computed by
* subtracting the removed slots from the occupied-and-removed slots.
*/
- uint32_t removed_slots_;
- uint32_t occupied_and_removed_slots_;
+ int64_t removed_slots_;
+ int64_t occupied_and_removed_slots_;
/**
* The maximum number of slots that can be used (either occupied or removed) until the set has to
* grow. This is the total number of slots times the max load factor.
*/
- uint32_t usable_slots_;
+ int64_t usable_slots_;
/**
* The number of slots minus one. This is a bit mask that can be used to turn any integer into a
* valid slot index efficiently.
*/
- uint32_t slot_mask_;
+ uint64_t slot_mask_;
/** This is called to hash incoming keys. */
Hash hash_;
@@ -260,10 +256,6 @@ class Set {
{
return this->add_as(std::move(key));
}
-
- /**
- * Same as `add`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> bool add_as(ForwardKey &&key)
{
return this->add__impl(std::forward<ForwardKey>(key), hash_(key));
@@ -303,13 +295,53 @@ class Set {
{
return this->contains_as(key);
}
+ template<typename ForwardKey> bool contains_as(const ForwardKey &key) const
+ {
+ return this->contains__impl(key, hash_(key));
+ }
/**
- * Same as `contains`, but accepts other key types that are supported by the hash function.
+ * Returns the key that is stored in the set that compares equal to the given key. This invokes
+ * undefined behavior when the key is not in the set.
*/
- template<typename ForwardKey> bool contains_as(const ForwardKey &key) const
+ const Key &lookup_key(const Key &key) const
{
- return this->contains__impl(key, hash_(key));
+ return this->lookup_key_as(key);
+ }
+ template<typename ForwardKey> const Key &lookup_key_as(const ForwardKey &key) const
+ {
+ return this->lookup_key__impl(key, hash_(key));
+ }
+
+ /**
+ * Returns the key that is stored in the set that compares equal to the given key. If the key is
+ * not in the set, the given default value is returned instead.
+ */
+ const Key &lookup_key_default(const Key &key, const Key &default_value) const
+ {
+ return this->lookup_key_default_as(key, default_value);
+ }
+ template<typename ForwardKey>
+ const Key &lookup_key_default_as(const ForwardKey &key, const Key &default_key) const
+ {
+ const Key *ptr = this->lookup_key_ptr__impl(key, hash_(key));
+ if (ptr == nullptr) {
+ return default_key;
+ }
+ return *ptr;
+ }
+
+ /**
+ * Returns a pointer to the key that is stored in the set that compares equal to the given key.
+ * If the key is not in the set, nullptr is returned instead.
+ */
+ const Key *lookup_key_ptr(const Key &key) const
+ {
+ return this->lookup_key_ptr_as(key);
+ }
+ template<typename ForwardKey> const Key *lookup_key_ptr_as(const ForwardKey &key) const
+ {
+ return this->lookup_key_ptr__impl(key, hash_(key));
}
/**
@@ -321,10 +353,6 @@ class Set {
{
return this->remove_as(key);
}
-
- /**
- * Same as `remove`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> bool remove_as(const ForwardKey &key)
{
return this->remove__impl(key, hash_(key));
@@ -337,11 +365,6 @@ class Set {
{
this->remove_contained_as(key);
}
-
- /**
- * Same as `remove_contained`, but accepts other key types that are supported by the hash
- * function.
- */
template<typename ForwardKey> void remove_contained_as(const ForwardKey &key)
{
this->remove_contained__impl(key, hash_(key));
@@ -357,11 +380,11 @@ class Set {
class Iterator {
private:
const Slot *slots_;
- uint32_t total_slots_;
- uint32_t current_slot_;
+ int64_t total_slots_;
+ int64_t current_slot_;
public:
- Iterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ Iterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: slots_(slots), total_slots_(total_slots), current_slot_(current_slot)
{
}
@@ -391,7 +414,7 @@ class Set {
Iterator begin() const
{
- for (uint32_t i = 0; i < slots_.size(); i++) {
+ for (int64_t i = 0; i < slots_.size(); i++) {
if (slots_[i].is_occupied()) {
return Iterator(slots_.data(), slots_.size(), i);
}
@@ -417,7 +440,7 @@ class Set {
* Get the number of collisions that the probing strategy has to go through to find the key or
* determine that it is not in the set.
*/
- uint32_t count_collisions(const Key &key) const
+ int64_t count_collisions(const Key &key) const
{
return this->count_collisions__impl(key, hash_(key));
}
@@ -443,7 +466,7 @@ class Set {
/**
* Returns the number of keys stored in the set.
*/
- uint32_t size() const
+ int64_t size() const
{
return occupied_and_removed_slots_ - removed_slots_;
}
@@ -459,7 +482,7 @@ class Set {
/**
* Returns the number of available slots. This is mostly for debugging purposes.
*/
- uint32_t capacity() const
+ int64_t capacity() const
{
return slots_.size();
}
@@ -467,7 +490,7 @@ class Set {
/**
* Returns the amount of removed slots in the set. This is mostly for debugging purposes.
*/
- uint32_t removed_amount() const
+ int64_t removed_amount() const
{
return removed_slots_;
}
@@ -475,7 +498,7 @@ class Set {
/**
* Returns the bytes required per element. This is mostly for debugging purposes.
*/
- uint32_t size_per_element() const
+ int64_t size_per_element() const
{
return sizeof(Slot);
}
@@ -484,7 +507,7 @@ class Set {
* Returns the approximate memory requirements of the set in bytes. This is more correct for
* larger sets.
*/
- uint32_t size_in_bytes() const
+ int64_t size_in_bytes() const
{
return sizeof(Slot) * slots_.size();
}
@@ -493,7 +516,7 @@ class Set {
* Potentially resize the set such that it can hold the specified number of keys without another
* grow operation.
*/
- void reserve(const uint32_t n)
+ void reserve(const int64_t n)
{
if (usable_slots_ < n) {
this->realloc_and_reinsert(n);
@@ -527,12 +550,13 @@ class Set {
}
private:
- BLI_NOINLINE void realloc_and_reinsert(const uint32_t min_usable_slots)
+ BLI_NOINLINE void realloc_and_reinsert(const int64_t min_usable_slots)
{
- uint32_t total_slots, usable_slots;
+ int64_t total_slots, usable_slots;
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
- const uint32_t new_slot_mask = total_slots - 1;
+ BLI_assert(total_slots >= 1);
+ const uint64_t new_slot_mask = (uint64_t)total_slots - 1;
/**
* Optimize the case when the set was empty beforehand. We can avoid some copies here.
@@ -568,9 +592,9 @@ class Set {
void add_after_grow_and_destruct_old(Slot &old_slot,
SlotArray &new_slots,
- const uint32_t new_slot_mask)
+ const uint64_t new_slot_mask)
{
- const uint32_t hash = old_slot.get_hash(Hash());
+ const uint64_t hash = old_slot.get_hash(Hash());
SLOT_PROBING_BEGIN (ProbingStrategy, hash, new_slot_mask, slot_index) {
Slot &slot = new_slots[slot_index];
@@ -583,7 +607,7 @@ class Set {
}
template<typename ForwardKey>
- bool contains__impl(const ForwardKey &key, const uint32_t hash) const
+ bool contains__impl(const ForwardKey &key, const uint64_t hash) const
{
SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
@@ -596,7 +620,34 @@ class Set {
SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> void add_new__impl(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey>
+ const Key &lookup_key__impl(const ForwardKey &key, const uint64_t hash) const
+ {
+ BLI_assert(this->contains_as(key));
+
+ SET_SLOT_PROBING_BEGIN (hash, slot) {
+ if (slot.contains(key, is_equal_, hash)) {
+ return *slot.key();
+ }
+ }
+ SET_SLOT_PROBING_END();
+ }
+
+ template<typename ForwardKey>
+ const Key *lookup_key_ptr__impl(const ForwardKey &key, const uint64_t hash) const
+ {
+ SET_SLOT_PROBING_BEGIN (hash, slot) {
+ if (slot.contains(key, is_equal_, hash)) {
+ return slot.key();
+ }
+ if (slot.is_empty()) {
+ return nullptr;
+ }
+ }
+ SET_SLOT_PROBING_END();
+ }
+
+ template<typename ForwardKey> void add_new__impl(ForwardKey &&key, const uint64_t hash)
{
BLI_assert(!this->contains_as(key));
@@ -612,7 +663,7 @@ class Set {
SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool add__impl(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey> bool add__impl(ForwardKey &&key, const uint64_t hash)
{
this->ensure_can_add();
@@ -629,7 +680,7 @@ class Set {
SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool remove__impl(const ForwardKey &key, const uint32_t hash)
+ template<typename ForwardKey> bool remove__impl(const ForwardKey &key, const uint64_t hash)
{
SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -645,7 +696,7 @@ class Set {
}
template<typename ForwardKey>
- void remove_contained__impl(const ForwardKey &key, const uint32_t hash)
+ void remove_contained__impl(const ForwardKey &key, const uint64_t hash)
{
BLI_assert(this->contains_as(key));
removed_slots_++;
@@ -660,9 +711,9 @@ class Set {
}
template<typename ForwardKey>
- uint32_t count_collisions__impl(const ForwardKey &key, const uint32_t hash) const
+ int64_t count_collisions__impl(const ForwardKey &key, const uint64_t hash) const
{
- uint32_t collisions = 0;
+ int64_t collisions = 0;
SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -695,9 +746,9 @@ template<typename Key> class StdUnorderedSetWrapper {
SetType set_;
public:
- uint32_t size() const
+ int64_t size() const
{
- return (uint32_t)set_.size();
+ return (int64_t)set_.size();
}
bool is_empty() const
@@ -705,7 +756,7 @@ template<typename Key> class StdUnorderedSetWrapper {
return set_.empty();
}
- void reserve(uint32_t n)
+ void reserve(int64_t n)
{
set_.reserve(n);
}
@@ -766,6 +817,16 @@ template<typename Key> class StdUnorderedSetWrapper {
}
};
-} // namespace blender
+/**
+ * Same as a normal Set, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename Key,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key)),
+ typename ProbingStrategy = DefaultProbingStrategy,
+ typename Hash = DefaultHash<Key>,
+ typename IsEqual = DefaultEquality,
+ typename Slot = typename DefaultSetSlot<Key>::type>
+using RawSet = Set<Key, InlineBufferCapacity, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>;
-#endif /* __BLI_SET_HH__ */
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_set_slots.hh b/source/blender/blenlib/BLI_set_slots.hh
index 9719f322693..ee5da17fcaf 100644
--- a/source/blender/blenlib/BLI_set_slots.hh
+++ b/source/blender/blenlib/BLI_set_slots.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_SET_SLOTS_HH__
-#define __BLI_SET_SLOTS_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -51,7 +50,7 @@ template<typename Key> class SimpleSetSlot {
};
State state_;
- AlignedBuffer<sizeof(Key), alignof(Key)> buffer_;
+ TypedBuffer<Key> key_buffer_;
public:
/**
@@ -68,7 +67,7 @@ template<typename Key> class SimpleSetSlot {
~SimpleSetSlot()
{
if (state_ == Occupied) {
- this->key()->~Key();
+ key_buffer_.ref().~Key();
}
}
@@ -80,7 +79,7 @@ template<typename Key> class SimpleSetSlot {
{
state_ = other.state_;
if (other.state_ == Occupied) {
- new ((void *)this->key()) Key(*other.key());
+ new (&key_buffer_) Key(*other.key_buffer_);
}
}
@@ -93,7 +92,7 @@ template<typename Key> class SimpleSetSlot {
{
state_ = other.state_;
if (other.state_ == Occupied) {
- new ((void *)this->key()) Key(std::move(*other.key()));
+ new (&key_buffer_) Key(std::move(*other.key_buffer_));
}
}
@@ -102,7 +101,7 @@ template<typename Key> class SimpleSetSlot {
*/
Key *key()
{
- return (Key *)buffer_.ptr();
+ return key_buffer_;
}
/**
@@ -110,7 +109,7 @@ template<typename Key> class SimpleSetSlot {
*/
const Key *key() const
{
- return (const Key *)buffer_.ptr();
+ return key_buffer_;
}
/**
@@ -133,23 +132,23 @@ template<typename Key> class SimpleSetSlot {
* Return the hash of the currently stored key. In this simple set slot implementation, we just
* compute the hash here. Other implementations might store the hash in the slot instead.
*/
- template<typename Hash> uint32_t get_hash(const Hash &hash) const
+ template<typename Hash> uint64_t get_hash(const Hash &hash) const
{
BLI_assert(this->is_occupied());
- return hash(*this->key());
+ return hash(*key_buffer_);
}
/**
* Move the other slot into this slot and destruct it. We do destruction here, because this way
* we can avoid a comparison with the state, since we know the slot is occupied.
*/
- void relocate_occupied_here(SimpleSetSlot &other, uint32_t UNUSED(hash))
+ void relocate_occupied_here(SimpleSetSlot &other, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
state_ = Occupied;
- new ((void *)this->key()) Key(std::move(*other.key()));
- other.key()->~Key();
+ new (&key_buffer_) Key(std::move(*other.key_buffer_));
+ other.key_buffer_.ref().~Key();
}
/**
@@ -157,10 +156,10 @@ template<typename Key> class SimpleSetSlot {
* key. The hash is used by other slot implementations to determine inequality faster.
*/
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint32_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
{
if (state_ == Occupied) {
- return is_equal(key, *this->key());
+ return is_equal(key, *key_buffer_);
}
return false;
}
@@ -169,11 +168,11 @@ template<typename Key> class SimpleSetSlot {
* Change the state of this slot from empty/removed to occupied. The key has to be constructed
* by calling the constructor with the given key as parameter.
*/
- template<typename ForwardKey> void occupy(ForwardKey &&key, uint32_t UNUSED(hash))
+ template<typename ForwardKey> void occupy(ForwardKey &&key, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
state_ = Occupied;
- new ((void *)this->key()) Key(std::forward<ForwardKey>(key));
+ new (&key_buffer_) Key(std::forward<ForwardKey>(key));
}
/**
@@ -183,7 +182,7 @@ template<typename Key> class SimpleSetSlot {
{
BLI_assert(this->is_occupied());
state_ = Removed;
- this->key()->~Key();
+ key_buffer_.ref().~Key();
}
};
@@ -199,9 +198,9 @@ template<typename Key> class HashedSetSlot {
Removed = 2,
};
- uint32_t hash_;
+ uint64_t hash_;
State state_;
- AlignedBuffer<sizeof(Key), alignof(Key)> buffer_;
+ TypedBuffer<Key> key_buffer_;
public:
HashedSetSlot()
@@ -212,7 +211,7 @@ template<typename Key> class HashedSetSlot {
~HashedSetSlot()
{
if (state_ == Occupied) {
- this->key()->~Key();
+ key_buffer_.ref().~Key();
}
}
@@ -221,7 +220,7 @@ template<typename Key> class HashedSetSlot {
state_ = other.state_;
if (other.state_ == Occupied) {
hash_ = other.hash_;
- new ((void *)this->key()) Key(*other.key());
+ new (&key_buffer_) Key(*other.key_buffer_);
}
}
@@ -230,18 +229,18 @@ template<typename Key> class HashedSetSlot {
state_ = other.state_;
if (other.state_ == Occupied) {
hash_ = other.hash_;
- new ((void *)this->key()) Key(std::move(*other.key()));
+ new (&key_buffer_) Key(std::move(*other.key_buffer_));
}
}
Key *key()
{
- return (Key *)buffer_.ptr();
+ return key_buffer_;
}
const Key *key() const
{
- return (const Key *)buffer_.ptr();
+ return key_buffer_;
}
bool is_occupied() const
@@ -254,47 +253,47 @@ template<typename Key> class HashedSetSlot {
return state_ == Empty;
}
- template<typename Hash> uint32_t get_hash(const Hash &UNUSED(hash)) const
+ template<typename Hash> uint64_t get_hash(const Hash &UNUSED(hash)) const
{
BLI_assert(this->is_occupied());
return hash_;
}
- void relocate_occupied_here(HashedSetSlot &other, const uint32_t hash)
+ void relocate_occupied_here(HashedSetSlot &other, const uint64_t hash)
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
state_ = Occupied;
hash_ = hash;
- new ((void *)this->key()) Key(std::move(*other.key()));
- other.key()->~Key();
+ new (&key_buffer_) Key(std::move(*other.key_buffer_));
+ key_buffer_.ref().~Key();
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint32_t hash) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t hash) const
{
/* hash_ might be uninitialized here, but that is ok. */
if (hash_ == hash) {
if (state_ == Occupied) {
- return is_equal(key, *this->key());
+ return is_equal(key, *key_buffer_);
}
}
return false;
}
- template<typename ForwardKey> void occupy(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t hash)
{
BLI_assert(!this->is_occupied());
state_ = Occupied;
hash_ = hash;
- new ((void *)this->key()) Key(std::forward<ForwardKey>(key));
+ new (&key_buffer_) Key(std::forward<ForwardKey>(key));
}
void remove()
{
BLI_assert(this->is_occupied());
state_ = Removed;
- this->key()->~Key();
+ key_buffer_.ref().~Key();
}
};
@@ -336,13 +335,13 @@ template<typename Key, typename KeyInfo> class IntrusiveSetSlot {
return KeyInfo::is_empty(key_);
}
- template<typename Hash> uint32_t get_hash(const Hash &hash) const
+ template<typename Hash> uint64_t get_hash(const Hash &hash) const
{
BLI_assert(this->is_occupied());
return hash(key_);
}
- void relocate_occupied_here(IntrusiveSetSlot &other, const uint32_t UNUSED(hash))
+ void relocate_occupied_here(IntrusiveSetSlot &other, const uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
@@ -351,13 +350,13 @@ template<typename Key, typename KeyInfo> class IntrusiveSetSlot {
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint32_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t UNUSED(hash)) const
{
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
return is_equal(key_, key);
}
- template<typename ForwardKey> void occupy(ForwardKey &&key, const uint32_t UNUSED(hash))
+ template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
@@ -411,5 +410,3 @@ template<typename Key> struct DefaultSetSlot<Key *> {
};
} // namespace blender
-
-#endif /* __BLI_SET_SLOTS_HH__ */
diff --git a/source/blender/blenlib/BLI_smallhash.h b/source/blender/blenlib/BLI_smallhash.h
index cb0330d1bad..daea2fcd914 100644
--- a/source/blender/blenlib/BLI_smallhash.h
+++ b/source/blender/blenlib/BLI_smallhash.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_SMALLHASH_H__
-#define __BLI_SMALLHASH_H__
+#pragma once
/** \file
* \ingroup bli
@@ -81,5 +80,3 @@ double BLI_smallhash_calc_quality(SmallHash *sh);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_SMALLHASH_H__ */
diff --git a/source/blender/blenlib/BLI_sort.h b/source/blender/blenlib/BLI_sort.h
index 08e61915a83..969816086e2 100644
--- a/source/blender/blenlib/BLI_sort.h
+++ b/source/blender/blenlib/BLI_sort.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_SORT_H__
-#define __BLI_SORT_H__
+#pragma once
/** \file
* \ingroup bli
@@ -39,5 +38,3 @@ void BLI_qsort_r(void *a, size_t n, size_t es, BLI_sort_cmp_t cmp, void *thunk)
__attribute__((nonnull(1, 5)))
#endif
;
-
-#endif /* __BLI_SORT_H__ */
diff --git a/source/blender/blenlib/BLI_sort_utils.h b/source/blender/blenlib/BLI_sort_utils.h
index 9c99f893a1f..e54252f4e1b 100644
--- a/source/blender/blenlib/BLI_sort_utils.h
+++ b/source/blender/blenlib/BLI_sort_utils.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_SORT_UTILS_H__
-#define __BLI_SORT_UTILS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -64,5 +63,3 @@ int BLI_sortutil_cmp_ptr_reverse(const void *a_, const void *b_);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_SORT_UTILS_H__ */
diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index 92d3124e01d..5aee0028846 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_SPAN_HH__
-#define __BLI_SPAN_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -87,8 +86,8 @@ namespace blender {
*/
template<typename T> class Span {
private:
- const T *start_ = nullptr;
- uint size_ = 0;
+ const T *data_ = nullptr;
+ int64_t size_ = 0;
public:
/**
@@ -96,8 +95,15 @@ template<typename T> class Span {
*/
Span() = default;
- Span(const T *start, uint size) : start_(start), size_(size)
+ Span(const T *start, int64_t size) : data_(start), size_(size)
{
+ BLI_assert(size >= 0);
+ }
+
+ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr>
+ Span(const U *start, int64_t size) : data_((const T *)start), size_(size)
+ {
+ BLI_assert(size >= 0);
}
/**
@@ -111,11 +117,11 @@ template<typename T> class Span {
* Span<int> span = {1, 2, 3, 4};
* call_function_with_array(span);
*/
- Span(const std::initializer_list<T> &list) : Span(list.begin(), (uint)list.size())
+ Span(const std::initializer_list<T> &list) : Span(list.begin(), (int64_t)list.size())
{
}
- Span(const std::vector<T> &vector) : Span(vector.data(), (uint)vector.size())
+ Span(const std::vector<T> &vector) : Span(vector.data(), (int64_t)vector.size())
{
}
@@ -128,9 +134,8 @@ template<typename T> class Span {
* Span<T *> -> Span<const T *>
* Span<Derived *> -> Span<Base *>
*/
- template<typename U,
- typename std::enable_if<std::is_convertible<U *, T>::value>::type * = nullptr>
- Span(Span<U *> array) : Span((T *)array.data(), array.size())
+ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr>
+ Span(Span<U> array) : data_((T *)array.data()), size_(array.size())
{
}
@@ -138,10 +143,12 @@ template<typename T> class Span {
* Returns a contiguous part of the array. This invokes undefined behavior when the slice does
* not stay within the bounds of the array.
*/
- Span slice(uint start, uint size) const
+ Span slice(int64_t start, int64_t size) const
{
+ BLI_assert(start >= 0);
+ BLI_assert(size >= 0);
BLI_assert(start + size <= this->size() || size == 0);
- return Span(start_ + start, size);
+ return Span(data_ + start, size);
}
Span slice(IndexRange range) const
@@ -153,8 +160,9 @@ template<typename T> class Span {
* Returns a new Span with n elements removed from the beginning. This invokes undefined
* behavior when the array is too small.
*/
- Span drop_front(uint n) const
+ Span drop_front(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(n, this->size() - n);
}
@@ -163,8 +171,9 @@ template<typename T> class Span {
* Returns a new Span with n elements removed from the beginning. This invokes undefined
* behavior when the array is too small.
*/
- Span drop_back(uint n) const
+ Span drop_back(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(0, this->size() - n);
}
@@ -173,8 +182,9 @@ template<typename T> class Span {
* Returns a new Span that only contains the first n elements. This invokes undefined
* behavior when the array is too small.
*/
- Span take_front(uint n) const
+ Span take_front(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(0, n);
}
@@ -183,8 +193,9 @@ template<typename T> class Span {
* Returns a new Span that only contains the last n elements. This invokes undefined
* behavior when the array is too small.
*/
- Span take_back(uint n) const
+ Span take_back(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(this->size() - n, n);
}
@@ -195,33 +206,34 @@ template<typename T> class Span {
*/
const T *data() const
{
- return start_;
+ return data_;
}
const T *begin() const
{
- return start_;
+ return data_;
}
const T *end() const
{
- return start_ + size_;
+ return data_ + size_;
}
/**
* Access an element in the array. This invokes undefined behavior when the index is out of
* bounds.
*/
- const T &operator[](uint index) const
+ const T &operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < size_);
- return start_[index];
+ return data_[index];
}
/**
* Returns the number of elements in the referenced array.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -237,7 +249,7 @@ template<typename T> class Span {
/**
* Returns the number of bytes referenced by this Span.
*/
- uint size_in_bytes() const
+ int64_t size_in_bytes() const
{
return sizeof(T) * size_;
}
@@ -269,9 +281,9 @@ template<typename T> class Span {
* Does a linear search to count how often the value is in the array.
* Returns the number of occurrences.
*/
- uint count(const T &value) const
+ int64_t count(const T &value) const
{
- uint counter = 0;
+ int64_t counter = 0;
for (const T &element : *this) {
if (element == value) {
counter++;
@@ -287,7 +299,7 @@ template<typename T> class Span {
const T &first() const
{
BLI_assert(size_ > 0);
- return start_[0];
+ return data_[0];
}
/**
@@ -297,17 +309,17 @@ template<typename T> class Span {
const T &last() const
{
BLI_assert(size_ > 0);
- return start_[size_ - 1];
+ return data_[size_ - 1];
}
/**
* Returns the element at the given index. If the index is out of range, return the fallback
* value.
*/
- T get(uint index, const T &fallback) const
+ T get(int64_t index, const T &fallback) const
{
- if (index < size_) {
- return start_[index];
+ if (index < size_ && index >= 0) {
+ return data_[index];
}
return fallback;
}
@@ -322,10 +334,10 @@ template<typename T> class Span {
* changed. */
BLI_assert(size_ < 1000);
- for (uint i = 0; i < size_; i++) {
- const T &value = start_[i];
- for (uint j = i + 1; j < size_; j++) {
- if (value == start_[j]) {
+ for (int64_t i = 0; i < size_; i++) {
+ const T &value = data_[i];
+ for (int64_t j = i + 1; j < size_; j++) {
+ if (value == data_[j]) {
return true;
}
}
@@ -344,8 +356,8 @@ template<typename T> class Span {
* changed. */
BLI_assert(size_ < 1000);
- for (uint i = 0; i < size_; i++) {
- const T &value = start_[i];
+ for (int64_t i = 0; i < size_; i++) {
+ const T &value = data_[i];
if (other.contains(value)) {
return true;
}
@@ -357,20 +369,20 @@ template<typename T> class Span {
* Returns the index of the first occurrence of the given value. This invokes undefined behavior
* when the value is not in the array.
*/
- uint first_index(const T &search_value) const
+ int64_t first_index(const T &search_value) const
{
- const int index = this->first_index_try(search_value);
+ const int64_t index = this->first_index_try(search_value);
BLI_assert(index >= 0);
- return (uint)index;
+ return (int64_t)index;
}
/**
* Returns the index of the first occurrence of the given value or -1 if it does not exist.
*/
- int first_index_try(const T &search_value) const
+ int64_t first_index_try(const T &search_value) const
{
- for (uint i = 0; i < size_; i++) {
- if (start_[i] == search_value) {
+ for (int64_t i = 0; i < size_; i++) {
+ if (data_[i] == search_value) {
return i;
}
}
@@ -392,8 +404,8 @@ template<typename T> class Span {
template<typename NewT> Span<NewT> cast() const
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
- uint new_size = size_ * sizeof(T) / sizeof(NewT);
- return Span<NewT>(reinterpret_cast<const NewT *>(start_), new_size);
+ int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
+ return Span<NewT>(reinterpret_cast<const NewT *>(data_), new_size);
}
/**
@@ -426,28 +438,13 @@ template<typename T> class Span {
*/
template<typename T> class MutableSpan {
private:
- T *start_;
- uint size_;
+ T *data_;
+ int64_t size_;
public:
MutableSpan() = default;
- MutableSpan(T *start, const uint size) : start_(start), size_(size)
- {
- }
-
- /**
- * Reference an initializer_list. Note that the data in the initializer_list is only valid until
- * the expression containing it is fully computed.
- *
- * Do:
- * call_function_with_array({1, 2, 3, 4});
- *
- * Don't:
- * MutableSpan<int> span = {1, 2, 3, 4};
- * call_function_with_array(span);
- */
- MutableSpan(std::initializer_list<T> &list) : MutableSpan(list.begin(), list.size())
+ MutableSpan(T *start, const int64_t size) : data_(start), size_(size)
{
}
@@ -461,13 +458,13 @@ template<typename T> class MutableSpan {
operator Span<T>() const
{
- return Span<T>(start_, size_);
+ return Span<T>(data_, size_);
}
/**
* Returns the number of elements in the array.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -477,18 +474,18 @@ template<typename T> class MutableSpan {
*/
void fill(const T &value)
{
- initialized_fill_n(start_, size_, value);
+ initialized_fill_n(data_, size_, value);
}
/**
* Replace a subset of all elements with the given value. This invokes undefined behavior when
* one of the indices is out of bounds.
*/
- void fill_indices(Span<uint> indices, const T &value)
+ void fill_indices(Span<int64_t> indices, const T &value)
{
- for (uint i : indices) {
+ for (int64_t i : indices) {
BLI_assert(i < size_);
- start_[i] = value;
+ data_[i] = value;
}
}
@@ -498,40 +495,40 @@ template<typename T> class MutableSpan {
*/
T *data() const
{
- return start_;
+ return data_;
}
T *begin() const
{
- return start_;
+ return data_;
}
T *end() const
{
- return start_ + size_;
+ return data_ + size_;
}
- T &operator[](const uint index) const
+ T &operator[](const int64_t index) const
{
BLI_assert(index < this->size());
- return start_[index];
+ return data_[index];
}
/**
* Returns a contiguous part of the array. This invokes undefined behavior when the slice would
* go out of bounds.
*/
- MutableSpan slice(const uint start, const uint length) const
+ MutableSpan slice(const int64_t start, const int64_t length) const
{
BLI_assert(start + length <= this->size());
- return MutableSpan(start_ + start, length);
+ return MutableSpan(data_ + start, length);
}
/**
* Returns a new MutableSpan with n elements removed from the beginning. This invokes
* undefined behavior when the array is too small.
*/
- MutableSpan drop_front(const uint n) const
+ MutableSpan drop_front(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(n, this->size() - n);
@@ -541,7 +538,7 @@ template<typename T> class MutableSpan {
* Returns a new MutableSpan with n elements removed from the end. This invokes undefined
* behavior when the array is too small.
*/
- MutableSpan drop_back(const uint n) const
+ MutableSpan drop_back(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(0, this->size() - n);
@@ -551,7 +548,7 @@ template<typename T> class MutableSpan {
* Returns a new MutableSpan that only contains the first n elements. This invokes undefined
* behavior when the array is too small.
*/
- MutableSpan take_front(const uint n) const
+ MutableSpan take_front(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(0, n);
@@ -561,7 +558,7 @@ template<typename T> class MutableSpan {
* Return a new MutableSpan that only contains the last n elements. This invokes undefined
* behavior when the array is too small.
*/
- MutableSpan take_back(const uint n) const
+ MutableSpan take_back(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(this->size() - n, n);
@@ -573,7 +570,7 @@ template<typename T> class MutableSpan {
*/
Span<T> as_span() const
{
- return Span<T>(start_, size_);
+ return Span<T>(data_, size_);
}
/**
@@ -592,7 +589,33 @@ template<typename T> class MutableSpan {
T &last() const
{
BLI_assert(size_ > 0);
- return start_[size_ - 1];
+ return data_[size_ - 1];
+ }
+
+ /**
+ * Does a linear search to count how often the value is in the array.
+ * Returns the number of occurrences.
+ */
+ int64_t count(const T &value) const
+ {
+ int64_t counter = 0;
+ for (const T &element : *this) {
+ if (element == value) {
+ counter++;
+ }
+ }
+ return counter;
+ }
+
+ /**
+ * Copy all values from another span into this span. This invokes undefined behavior when the
+ * destination contains uninitialized data and T is not trivially copy constructible.
+ * The size of both spans is expected to be the same.
+ */
+ void copy_from(Span<T> values)
+ {
+ BLI_assert(size_ == values.size());
+ initialized_copy_n(values.data(), size_, data_);
}
/**
@@ -601,27 +624,19 @@ template<typename T> class MutableSpan {
template<typename NewT> MutableSpan<NewT> cast() const
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
- uint new_size = size_ * sizeof(T) / sizeof(NewT);
- return MutableSpan<NewT>(reinterpret_cast<NewT *>(start_), new_size);
+ int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
+ return MutableSpan<NewT>(reinterpret_cast<NewT *>(data_), new_size);
}
};
/**
- * Shorthand to make use of automatic template parameter deduction.
- */
-template<typename T> Span<T> ref_c_array(const T *array, uint size)
-{
- return Span<T>(array, size);
-}
-
-/**
* Utilities to check that arrays have the same size in debug builds.
*/
template<typename T1, typename T2> void assert_same_size(const T1 &v1, const T2 &v2)
{
UNUSED_VARS_NDEBUG(v1, v2);
#ifdef DEBUG
- uint size = v1.size();
+ int64_t size = v1.size();
BLI_assert(size == v1.size());
BLI_assert(size == v2.size());
#endif
@@ -632,7 +647,7 @@ void assert_same_size(const T1 &v1, const T2 &v2, const T3 &v3)
{
UNUSED_VARS_NDEBUG(v1, v2, v3);
#ifdef DEBUG
- uint size = v1.size();
+ int64_t size = v1.size();
BLI_assert(size == v1.size());
BLI_assert(size == v2.size());
BLI_assert(size == v3.size());
@@ -640,5 +655,3 @@ void assert_same_size(const T1 &v1, const T2 &v2, const T3 &v3)
}
} /* namespace blender */
-
-#endif /* __BLI_SPAN_HH__ */
diff --git a/source/blender/blenlib/BLI_stack.h b/source/blender/blenlib/BLI_stack.h
index 9fc25e378a3..b00bc0a2e57 100644
--- a/source/blender/blenlib/BLI_stack.h
+++ b/source/blender/blenlib/BLI_stack.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_STACK_H__
-#define __BLI_STACK_H__
+#pragma once
/** \file
* \ingroup bli
@@ -55,5 +54,3 @@ bool BLI_stack_is_empty(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NON
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_STACK_H__ */
diff --git a/source/blender/blenlib/BLI_stack.hh b/source/blender/blenlib/BLI_stack.hh
index 50be9357a01..5fa7867e176 100644
--- a/source/blender/blenlib/BLI_stack.hh
+++ b/source/blender/blenlib/BLI_stack.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_STACK_HH__
-#define __BLI_STACK_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -60,7 +59,7 @@ template<typename T> struct StackChunk {
/** Pointer to one element past the end of the referenced buffer. */
T *capacity_end;
- uint capacity() const
+ int64_t capacity() const
{
return capacity_end - begin;
}
@@ -73,11 +72,8 @@ template<
* The number of values that can be stored in this stack, without doing a heap allocation.
* Sometimes it can make sense to increase this value a lot. The memory in the inline buffer is
* not initialized when it is not needed.
- *
- * When T is large, the small buffer optimization is disabled by default to avoid large
- * unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)),
/**
* The allocator used by this stack. Should rarely be changed, except when you don't want that
* MEM_* is used internally.
@@ -103,10 +99,10 @@ class Stack {
/**
* Number of elements in the entire stack. The sum of initialized element counts in the chunks.
*/
- uint size_;
+ int64_t size_;
/** The buffer used to implement small object optimization. */
- AlignedBuffer<sizeof(T) * InlineBufferCapacity, alignof(T)> inline_buffer_;
+ TypedBuffer<T, InlineBufferCapacity> inline_buffer_;
/**
* A chunk referencing the inline buffer. This is always the bottom-most chunk.
@@ -123,14 +119,12 @@ class Stack {
*/
Stack(Allocator allocator = {}) : allocator_(allocator)
{
- T *inline_buffer = this->inline_buffer();
-
inline_chunk_.below = nullptr;
inline_chunk_.above = nullptr;
- inline_chunk_.begin = inline_buffer;
- inline_chunk_.capacity_end = inline_buffer + InlineBufferCapacity;
+ inline_chunk_.begin = inline_buffer_;
+ inline_chunk_.capacity_end = inline_buffer_ + InlineBufferCapacity;
- top_ = inline_buffer;
+ top_ = inline_buffer_;
top_chunk_ = &inline_chunk_;
size_ = 0;
}
@@ -168,15 +162,19 @@ class Stack {
Stack(Stack &&other) noexcept : Stack(other.allocator_)
{
- uninitialized_relocate_n(
- other.inline_buffer(), std::min(other.size_, InlineBufferCapacity), this->inline_buffer());
+ uninitialized_relocate_n<T>(
+ other.inline_buffer_, std::min(other.size_, InlineBufferCapacity), inline_buffer_);
inline_chunk_.above = other.inline_chunk_.above;
size_ = other.size_;
+ if (inline_chunk_.above != nullptr) {
+ inline_chunk_.above->below = &inline_chunk_;
+ }
+
if (size_ <= InlineBufferCapacity) {
top_chunk_ = &inline_chunk_;
- top_ = this->inline_buffer() + size_;
+ top_ = inline_buffer_ + size_;
}
else {
top_chunk_ = other.top_chunk_;
@@ -296,8 +294,8 @@ class Stack {
this->activate_next_chunk(remaining_values.size());
}
- const uint remaining_capacity = top_chunk_->capacity_end - top_;
- const uint amount = std::min(remaining_values.size(), remaining_capacity);
+ const int64_t remaining_capacity = top_chunk_->capacity_end - top_;
+ const int64_t amount = std::min(remaining_values.size(), remaining_capacity);
uninitialized_copy_n(remaining_values.data(), amount, top_);
top_ += amount;
@@ -318,7 +316,7 @@ class Stack {
/**
* Returns the number of elements in the stack.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -335,11 +333,6 @@ class Stack {
}
private:
- T *inline_buffer() const
- {
- return (T *)inline_buffer_.ptr();
- }
-
/**
* Changes top_chunk_ to point to a new chunk that is above the current one. The new chunk might
* be smaller than the given size_hint. This happens when a chunk that has been allocated before
@@ -347,11 +340,11 @@ class Stack {
*
* This invokes undefined behavior when the currently active chunk is not full.
*/
- void activate_next_chunk(const uint size_hint)
+ void activate_next_chunk(const int64_t size_hint)
{
BLI_assert(top_ == top_chunk_->capacity_end);
if (top_chunk_->above == nullptr) {
- const uint new_capacity = std::max(size_hint, top_chunk_->capacity() * 2 + 10);
+ const int64_t new_capacity = std::max(size_hint, top_chunk_->capacity() * 2 + 10);
/* Do a single memory allocation for the Chunk and the array it references. */
void *buffer = allocator_.allocate(
@@ -384,6 +377,11 @@ class Stack {
}
};
-} /* namespace blender */
+/**
+ * Same as a normal Stack, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
+using RawStack = Stack<T, InlineBufferCapacity, RawAllocator>;
-#endif /* __BLI_STACK_HH__ */
+} /* namespace blender */
diff --git a/source/blender/blenlib/BLI_strict_flags.h b/source/blender/blenlib/BLI_strict_flags.h
index cf7888d3c5e..6cee6b64797 100644
--- a/source/blender/blenlib/BLI_strict_flags.h
+++ b/source/blender/blenlib/BLI_strict_flags.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_STRICT_FLAGS_H__
-#define __BLI_STRICT_FLAGS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -53,5 +52,3 @@
# pragma warning(error : 4305) /* truncation from 'type1' to 'type2' */
# pragma warning(error : 4389) /* signed/unsigned mismatch */
#endif
-
-#endif /* __BLI_STRICT_FLAGS_H__ */
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 00e4e3485d1..d1fab065959 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_STRING_H__
-#define __BLI_STRING_H__
+#pragma once
/** \file
* \ingroup bli
@@ -206,5 +205,3 @@ int BLI_string_find_split_words(const char *str,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_STRING_H__ */
diff --git a/source/blender/blenlib/BLI_string_cursor_utf8.h b/source/blender/blenlib/BLI_string_cursor_utf8.h
index f8afff214a3..e78c7b56cf7 100644
--- a/source/blender/blenlib/BLI_string_cursor_utf8.h
+++ b/source/blender/blenlib/BLI_string_cursor_utf8.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_STRING_CURSOR_UTF8_H__
-#define __BLI_STRING_CURSOR_UTF8_H__
+#pragma once
/** \file
* \ingroup bli
@@ -59,5 +58,3 @@ void BLI_str_cursor_step_utf32(const char32_t *str,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_STRING_CURSOR_UTF8_H__ */
diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh
index bcf2d20338e..8bf4821f72a 100644
--- a/source/blender/blenlib/BLI_string_ref.hh
+++ b/source/blender/blenlib/BLI_string_ref.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_STRING_REF_HH__
-#define __BLI_STRING_REF_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -60,9 +59,9 @@ class StringRef;
class StringRefBase {
protected:
const char *data_;
- uint size_;
+ int64_t size_;
- StringRefBase(const char *data, const uint size) : data_(data), size_(size)
+ StringRefBase(const char *data, const int64_t size) : data_(data), size_(size)
{
}
@@ -70,7 +69,7 @@ class StringRefBase {
/**
* Return the (byte-)length of the referenced string, without any null-terminator.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -94,7 +93,7 @@ class StringRefBase {
*/
operator std::string() const
{
- return std::string(data_, size_);
+ return std::string(data_, (size_t)size_);
}
const char *begin() const
@@ -114,7 +113,7 @@ class StringRefBase {
*/
void unsafe_copy(char *dst) const
{
- memcpy(dst, data_, size_);
+ memcpy(dst, data_, (size_t)size_);
dst[size_] = '\0';
}
@@ -122,7 +121,7 @@ class StringRefBase {
* Copy the string into a buffer. The copied string will be null-terminated. This invokes
* undefined behavior when dst_size is too small. (Should we define the behavior?)
*/
- void copy(char *dst, const uint dst_size) const
+ void copy(char *dst, const int64_t dst_size) const
{
if (size_ < dst_size) {
this->unsafe_copy(dst);
@@ -137,7 +136,7 @@ class StringRefBase {
* Copy the string into a char array. The copied string will be null-terminated. This invokes
* undefined behavior when dst is too small.
*/
- template<uint N> void copy(char (&dst)[N])
+ template<size_t N> void copy(char (&dst)[N])
{
this->copy(dst, N);
}
@@ -152,7 +151,7 @@ class StringRefBase {
*/
bool endswith(StringRef suffix) const;
- StringRef substr(uint start, const uint size) const;
+ StringRef substr(int64_t start, const int64_t size) const;
};
/**
@@ -168,7 +167,7 @@ class StringRefNull : public StringRefBase {
/**
* Construct a StringRefNull from a null terminated c-string. The pointer must not point to NULL.
*/
- StringRefNull(const char *str) : StringRefBase(str, (uint)strlen(str))
+ StringRefNull(const char *str) : StringRefBase(str, (int64_t)strlen(str))
{
BLI_assert(str != NULL);
BLI_assert(data_[size_] == '\0');
@@ -178,28 +177,39 @@ class StringRefNull : public StringRefBase {
* Construct a StringRefNull from a null terminated c-string. This invokes undefined behavior
* when the given size is not the correct size of the string.
*/
- StringRefNull(const char *str, const uint size) : StringRefBase(str, size)
+ StringRefNull(const char *str, const int64_t size) : StringRefBase(str, size)
{
- BLI_assert((uint)strlen(str) == size);
+ BLI_assert((int64_t)strlen(str) == size);
}
/**
* Reference a std::string. Remember that when the std::string is destructed, the StringRefNull
* will point to uninitialized memory.
*/
- StringRefNull(const std::string &str) : StringRefNull(str.data())
+ StringRefNull(const std::string &str) : StringRefNull(str.c_str())
{
}
/**
* Get the char at the given index.
*/
- char operator[](const uint index) const
+ char operator[](const int64_t index) const
{
+ BLI_assert(index >= 0);
/* Use '<=' instead of just '<', so that the null character can be accessed as well. */
BLI_assert(index <= size_);
return data_[index];
}
+
+ /**
+ * Returns the beginning of a null-terminated char array.
+ *
+ * This is like ->data(), but can only be called on a StringRefNull.
+ */
+ const char *c_str() const
+ {
+ return data_;
+ }
};
/**
@@ -221,11 +231,11 @@ class StringRef : public StringRefBase {
/**
* Create a StringRef from a null-terminated c-string.
*/
- StringRef(const char *str) : StringRefBase(str, str ? (uint)strlen(str) : 0)
+ StringRef(const char *str) : StringRefBase(str, str ? (int64_t)strlen(str) : 0)
{
}
- StringRef(const char *str, const uint length) : StringRefBase(str, length)
+ StringRef(const char *str, const int64_t length) : StringRefBase(str, length)
{
}
@@ -234,7 +244,7 @@ class StringRef : public StringRefBase {
* second point points to a smaller address than the first one.
*/
StringRef(const char *begin, const char *one_after_end)
- : StringRefBase(begin, (uint)(one_after_end - begin))
+ : StringRefBase(begin, (int64_t)(one_after_end - begin))
{
BLI_assert(begin <= one_after_end);
}
@@ -243,15 +253,16 @@ class StringRef : public StringRefBase {
* Reference a std::string. Remember that when the std::string is destructed, the StringRef
* will point to uninitialized memory.
*/
- StringRef(const std::string &str) : StringRefBase(str.data(), (uint)str.size())
+ StringRef(const std::string &str) : StringRefBase(str.data(), (int64_t)str.size())
{
}
/**
* Return a new StringRef that does not contain the first n chars.
*/
- StringRef drop_prefix(const uint n) const
+ StringRef drop_prefix(const int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= size_);
return StringRef(data_ + n, size_ - n);
}
@@ -269,8 +280,9 @@ class StringRef : public StringRefBase {
/**
* Get the char at the given index.
*/
- char operator[](uint index) const
+ char operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < size_);
return data_[index];
}
@@ -287,7 +299,7 @@ inline std::ostream &operator<<(std::ostream &stream, StringRef ref)
inline std::ostream &operator<<(std::ostream &stream, StringRefNull ref)
{
- stream << std::string(ref.data(), ref.size());
+ stream << std::string(ref.data(), (size_t)ref.size());
return stream;
}
@@ -305,7 +317,7 @@ inline bool operator==(StringRef a, StringRef b)
if (a.size() != b.size()) {
return false;
}
- return STREQLEN(a.data(), b.data(), a.size());
+ return STREQLEN(a.data(), b.data(), (size_t)a.size());
}
inline bool operator!=(StringRef a, StringRef b)
@@ -321,7 +333,7 @@ inline bool StringRefBase::startswith(StringRef prefix) const
if (size_ < prefix.size_) {
return false;
}
- for (uint i = 0; i < prefix.size_; i++) {
+ for (int64_t i = 0; i < prefix.size_; i++) {
if (data_[i] != prefix.data_[i]) {
return false;
}
@@ -337,8 +349,8 @@ inline bool StringRefBase::endswith(StringRef suffix) const
if (size_ < suffix.size_) {
return false;
}
- const uint offset = size_ - suffix.size_;
- for (uint i = 0; i < suffix.size_; i++) {
+ const int64_t offset = size_ - suffix.size_;
+ for (int64_t i = 0; i < suffix.size_; i++) {
if (data_[offset + i] != suffix.data_[i]) {
return false;
}
@@ -349,12 +361,12 @@ inline bool StringRefBase::endswith(StringRef suffix) const
/**
* Return a new #StringRef containing only a sub-string of the original string.
*/
-inline StringRef StringRefBase::substr(const uint start, const uint size) const
+inline StringRef StringRefBase::substr(const int64_t start, const int64_t size) const
{
+ BLI_assert(size >= 0);
+ BLI_assert(start >= 0);
BLI_assert(start + size <= size_);
return StringRef(data_ + start, size);
}
} // namespace blender
-
-#endif /* __BLI_STRING_REF_HH__ */
diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h
index 78e7113b6ef..3620a3ccc55 100644
--- a/source/blender/blenlib/BLI_string_utf8.h
+++ b/source/blender/blenlib/BLI_string_utf8.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_STRING_UTF8_H__
-#define __BLI_STRING_UTF8_H__
+#pragma once
/** \file
* \ingroup bli
@@ -115,5 +114,3 @@ int BLI_str_utf8_offset_from_column(const char *str, int column);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenlib/BLI_string_utils.h b/source/blender/blenlib/BLI_string_utils.h
index 857b22540e9..46fb096599f 100644
--- a/source/blender/blenlib/BLI_string_utils.h
+++ b/source/blender/blenlib/BLI_string_utils.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_STRING_UTILS_H__
-#define __BLI_STRING_UTILS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -97,5 +96,3 @@ bool BLI_uniquename(struct ListBase *list,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_STRING_UTILS_H__ */
diff --git a/source/blender/blenlib/BLI_sys_types.h b/source/blender/blenlib/BLI_sys_types.h
index ef15ce111b6..ff1f6af9573 100644
--- a/source/blender/blenlib/BLI_sys_types.h
+++ b/source/blender/blenlib/BLI_sys_types.h
@@ -31,8 +31,7 @@
* For these rogue platforms, we make the typedefs ourselves.
*/
-#ifndef __BLI_SYS_TYPES_H__
-#define __BLI_SYS_TYPES_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -89,5 +88,3 @@ typedef unsigned char uchar;
#ifdef __cplusplus
}
#endif
-
-#endif /* eof */
diff --git a/source/blender/blenlib/BLI_system.h b/source/blender/blenlib/BLI_system.h
index 50f8adc20f6..8dd0706e1e2 100644
--- a/source/blender/blenlib/BLI_system.h
+++ b/source/blender/blenlib/BLI_system.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_SYSTEM_H__
-#define __BLI_SYSTEM_H__
+#pragma once
#include <stdio.h>
@@ -64,5 +63,3 @@ void BLI_windows_handle_exception(void *exception);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_SYSTEM_H__ */
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 6f810144a48..a281aaa5b51 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_THREADS_H__
-#define __BLI_THREADS_H__
+#pragma once
/** \file
* \ingroup bli
@@ -107,7 +106,7 @@ typedef uint32_t SpinLock;
#elif defined(__APPLE__)
typedef ThreadMutex SpinLock;
#elif defined(_MSC_VER)
-typedef volatile int SpinLock;
+typedef volatile unsigned int SpinLock;
#else
typedef pthread_spinlock_t SpinLock;
#endif
@@ -205,5 +204,3 @@ void BLI_thread_put_thread_on_fast_node(void);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenlib/BLI_timecode.h b/source/blender/blenlib/BLI_timecode.h
index d3c6803130a..1dff50efa23 100644
--- a/source/blender/blenlib/BLI_timecode.h
+++ b/source/blender/blenlib/BLI_timecode.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_TIMECODE_H__
-#define __BLI_TIMECODE_H__
+#pragma once
/** \file
* \ingroup BLI
@@ -49,5 +48,3 @@ size_t BLI_timecode_string_from_time_seconds(char *str,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_TIMECODE_H__ */
diff --git a/source/blender/blenlib/BLI_timeit.hh b/source/blender/blenlib/BLI_timeit.hh
index 34c2d63cbd7..8e107585576 100644
--- a/source/blender/blenlib/BLI_timeit.hh
+++ b/source/blender/blenlib/BLI_timeit.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_TIMEIT_HH__
-#define __BLI_TIMEIT_HH__
+#pragma once
#include <chrono>
#include <iostream>
@@ -23,8 +22,7 @@
#include "BLI_sys_types.h"
-namespace blender {
-namespace Timeit {
+namespace blender::timeit {
using Clock = std::chrono::steady_clock;
using TimePoint = Clock::time_point;
@@ -54,9 +52,6 @@ class ScopedTimer {
}
};
-} // namespace Timeit
-} // namespace blender
+} // namespace blender::timeit
-#define SCOPED_TIMER(name) blender::Timeit::ScopedTimer scoped_timer(name)
-
-#endif /* __BLI_TIMEIT_HH__ */
+#define SCOPED_TIMER(name) blender::timeit::ScopedTimer scoped_timer(name)
diff --git a/source/blender/blenlib/BLI_timer.h b/source/blender/blenlib/BLI_timer.h
index 144fcd0a0d7..19275ff5b9a 100644
--- a/source/blender/blenlib/BLI_timer.h
+++ b/source/blender/blenlib/BLI_timer.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_TIMER_H__
-#define __BLI_TIMER_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -61,5 +60,3 @@ void BLI_timer_on_file_load(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_TIMER_H__ */
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 1f28f7e80c5..2699f2498ac 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -627,11 +627,11 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size);
/** \name String Macros
* \{ */
-/* Macro to convert a value to string in the preprocessor
- * STRINGIFY_ARG: gives the argument as a string
- * STRINGIFY_APPEND: appends any argument 'b' onto the string argument 'a',
- * used by STRINGIFY because some preprocessors warn about zero arguments
- * STRINGIFY: gives the argument's value as a string */
+/* Macro to convert a value to string in the pre-processor:
+ * - `STRINGIFY_ARG`: gives the argument as a string
+ * - `STRINGIFY_APPEND`: appends any argument 'b' onto the string argument 'a',
+ * used by `STRINGIFY` because some preprocessors warn about zero arguments
+ * - `STRINGIFY`: gives the argument's value as a string. */
#define STRINGIFY_ARG(x) "" #x
#define STRINGIFY_APPEND(a, b) "" a #b
#define STRINGIFY(x) STRINGIFY_APPEND("", x)
@@ -755,6 +755,43 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size);
/** \} */
/* -------------------------------------------------------------------- */
+/** \name C++ Macros
+ * \{ */
+
+#ifdef __cplusplus
+
+/* Useful to port C code using enums to C++ where enums are strongly typed.
+ * To use after the enum declaration. */
+# define ENUM_OPERATORS(_enum_type) \
+ inline constexpr _enum_type operator|(_enum_type a, _enum_type b) \
+ { \
+ return a = static_cast<_enum_type>(static_cast<int>(a) | b); \
+ } \
+ inline constexpr _enum_type operator&(_enum_type a, _enum_type b) \
+ { \
+ return a = static_cast<_enum_type>(static_cast<int>(a) & b); \
+ } \
+ inline constexpr _enum_type operator~(_enum_type a) \
+ { \
+ return a = static_cast<_enum_type>(~static_cast<int>(a)); \
+ } \
+ inline _enum_type &operator|=(_enum_type &a, _enum_type b) \
+ { \
+ return a = static_cast<_enum_type>(static_cast<int>(a) | b); \
+ } \
+ inline _enum_type &operator&=(_enum_type &a, _enum_type b) \
+ { \
+ return a = static_cast<_enum_type>(static_cast<int>(a) & b); \
+ }
+
+#else
+/* Output nothing. */
+# define ENUM_OPERATORS(_type)
+#endif
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Misc Macros
* \{ */
diff --git a/source/blender/blenlib/BLI_utildefines_iter.h b/source/blender/blenlib/BLI_utildefines_iter.h
index bbd83573e53..5fb6248e1e9 100644
--- a/source/blender/blenlib/BLI_utildefines_iter.h
+++ b/source/blender/blenlib/BLI_utildefines_iter.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_UTILDEFINES_ITER_H__
-#define __BLI_UTILDEFINES_ITER_H__
+#pragma once
/** \file
* \ingroup bli
@@ -42,5 +41,3 @@
for (int _src = (src), _src2 = _src * 2, _dst2 = (dst)*2, _error = _dst2 - _src, i = 0, _delta; \
((void)(_delta = divide_floor_i(_error, _dst2)), (void)(i -= _delta), (i < _src)); \
_error -= (_delta * _dst2) + _src2)
-
-#endif /* __BLI_UTILDEFINES_ITER_H__ */
diff --git a/source/blender/blenlib/BLI_utildefines_stack.h b/source/blender/blenlib/BLI_utildefines_stack.h
index 9f9bfb0405d..f50004ef79a 100644
--- a/source/blender/blenlib/BLI_utildefines_stack.h
+++ b/source/blender/blenlib/BLI_utildefines_stack.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_UTILDEFINES_STACK_H__
-#define __BLI_UTILDEFINES_STACK_H__
+#pragma once
/** \file
* \ingroup bli
@@ -99,5 +98,3 @@
} \
((void)0)
#endif
-
-#endif /* __BLI_UTILDEFINES_STACK_H__ */
diff --git a/source/blender/blenlib/BLI_utildefines_variadic.h b/source/blender/blenlib/BLI_utildefines_variadic.h
index f5a420a7faf..be0d0b93cc7 100644
--- a/source/blender/blenlib/BLI_utildefines_variadic.h
+++ b/source/blender/blenlib/BLI_utildefines_variadic.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_UTILDEFINES_VARIADIC_H__
-#define __BLI_UTILDEFINES_VARIADIC_H__
+#pragma once
/** \file
* \ingroup bli
@@ -47,5 +46,3 @@
_VA_NARGS_GLUE(_VA_NARGS_OVERLOAD_MACRO(name, VA_NARGS_COUNT(__VA_ARGS__)), (__VA_ARGS__))
/* clang-format on */
-
-#endif /* __BLI_UTILDEFINES_VARIADIC_H__ */
diff --git a/source/blender/blenlib/BLI_utility_mixins.hh b/source/blender/blenlib/BLI_utility_mixins.hh
index 61444e36725..69b1d85b3b6 100644
--- a/source/blender/blenlib/BLI_utility_mixins.hh
+++ b/source/blender/blenlib/BLI_utility_mixins.hh
@@ -18,8 +18,7 @@
* \ingroup bli
*/
-#ifndef __BLI_UTILITY_MIXINS_HH__
-#define __BLI_UTILITY_MIXINS_HH__
+#pragma once
namespace blender {
@@ -54,5 +53,3 @@ class NonMovable {
};
} // namespace blender
-
-#endif /* __BLI_UTILITY_MIXINS_HH__ */
diff --git a/source/blender/blenlib/BLI_uvproject.h b/source/blender/blenlib/BLI_uvproject.h
index 8a33ea6961c..6028d95bda0 100644
--- a/source/blender/blenlib/BLI_uvproject.h
+++ b/source/blender/blenlib/BLI_uvproject.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_UVPROJECT_H__
-#define __BLI_UVPROJECT_H__
+#pragma once
/** \file
* \ingroup bli
@@ -45,7 +44,7 @@ void BLI_uvproject_from_view(float target[2],
float winy);
/* apply ortho uv's */
-void BLI_uvproject_from_view_ortho(float target[2], float source[3], float rotmat[4][4]);
+void BLI_uvproject_from_view_ortho(float target[2], float source[3], const float rotmat[4][4]);
/* so we can adjust scale with keeping the struct private */
void BLI_uvproject_camera_info_scale(struct ProjCameraInfo *uci, float scale_x, float scale_y);
@@ -53,5 +52,3 @@ void BLI_uvproject_camera_info_scale(struct ProjCameraInfo *uci, float scale_x,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh
index a06be65685f..52e966267b5 100644
--- a/source/blender/blenlib/BLI_vector.hh
+++ b/source/blender/blenlib/BLI_vector.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_VECTOR_HH__
-#define __BLI_VECTOR_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -70,7 +69,7 @@ template<
* When T is large, the small buffer optimization is disabled by default to avoid large
* unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)),
/**
* The allocator used by this vector. Should rarely be changed, except when you don't want that
* MEM_* is used internally.
@@ -92,7 +91,7 @@ class Vector {
Allocator allocator_;
/** A placeholder buffer that will remain uninitialized until it is used. */
- AlignedBuffer<(uint)sizeof(T) * InlineBufferCapacity, (uint)alignof(T)> inline_buffer_;
+ TypedBuffer<T, InlineBufferCapacity> inline_buffer_;
/**
* Store the size of the vector explicitly in debug builds. Otherwise you'd always have to call
@@ -100,8 +99,8 @@ class Vector {
* annoying. Knowing the size of a vector is often quite essential when debugging some code.
*/
#ifndef NDEBUG
- uint debug_size_;
-# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = (uint)((ptr)->end_ - (ptr)->begin_)
+ int64_t debug_size_;
+# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = (int64_t)((ptr)->end_ - (ptr)->begin_)
#else
# define UPDATE_VECTOR_SIZE(ptr) ((void)0)
#endif
@@ -110,7 +109,7 @@ class Vector {
* Be a friend with other vector instantiations. This is necessary to implement some memory
* management logic.
*/
- template<typename OtherT, uint OtherInlineBufferCapacity, typename OtherAllocator>
+ template<typename OtherT, int64_t OtherInlineBufferCapacity, typename OtherAllocator>
friend class Vector;
public:
@@ -118,9 +117,9 @@ class Vector {
* Create an empty vector.
* This does not do any memory allocation.
*/
- Vector()
+ Vector(Allocator allocator = {}) : allocator_(allocator)
{
- begin_ = this->inline_buffer();
+ begin_ = inline_buffer_;
end_ = begin_;
capacity_end_ = begin_ + InlineBufferCapacity;
UPDATE_VECTOR_SIZE(this);
@@ -131,7 +130,7 @@ class Vector {
* The elements will be default constructed.
* If T is trivially constructible, the elements in the vector are not touched.
*/
- explicit Vector(uint size) : Vector()
+ explicit Vector(int64_t size) : Vector()
{
this->resize(size);
}
@@ -139,11 +138,21 @@ class Vector {
/**
* Create a vector filled with a specific value.
*/
- Vector(uint size, const T &value) : Vector()
+ Vector(int64_t size, const T &value) : Vector()
{
+ this->resize(size, value);
+ }
+
+ /**
+ * Create a vector from an array ref. The values in the vector are copy constructed.
+ */
+ template<typename U, typename std::enable_if_t<std::is_convertible_v<U, T>> * = nullptr>
+ Vector(Span<U> values, Allocator allocator = {}) : Vector(allocator)
+ {
+ const int64_t size = values.size();
this->reserve(size);
this->increase_size_by_unchecked(size);
- blender::uninitialized_fill_n(begin_, size, value);
+ uninitialized_convert_n<U, T>(values.data(), size, begin_);
}
/**
@@ -152,24 +161,25 @@ class Vector {
* This allows you to write code like:
* Vector<int> vec = {3, 4, 5};
*/
+ template<typename U, typename std::enable_if_t<std::is_convertible_v<U, T>> * = nullptr>
+ Vector(const std::initializer_list<U> &values) : Vector(Span<U>(values))
+ {
+ }
+
Vector(const std::initializer_list<T> &values) : Vector(Span<T>(values))
{
}
- /**
- * Create a vector from an array ref. The values in the vector are copy constructed.
- */
- Vector(Span<T> values) : Vector()
+ template<typename U,
+ size_t N,
+ typename std::enable_if_t<std::is_convertible_v<U, T>> * = nullptr>
+ Vector(const std::array<U, N> &values) : Vector(Span(values))
{
- const uint size = values.size();
- this->reserve(size);
- this->increase_size_by_unchecked(size);
- blender::uninitialized_copy_n(values.data(), size, begin_);
}
/**
- * Create a vector from any container. It must be possible to use the container in a range-for
- * loop.
+ * Create a vector from any container. It must be possible to use the container in a
+ * range-for loop.
*/
template<typename ContainerT> static Vector FromContainer(const ContainerT &container)
{
@@ -198,44 +208,42 @@ class Vector {
* Create a copy of another vector. The other vector will not be changed. If the other vector has
* less than InlineBufferCapacity elements, no allocation will be made.
*/
- Vector(const Vector &other) : allocator_(other.allocator_)
+ Vector(const Vector &other) : Vector(other.as_span(), other.allocator_)
{
- this->init_copy_from_other_vector(other);
}
/**
* Create a copy of a vector with a different InlineBufferCapacity. This needs to be handled
* separately, so that the other one is a valid copy constructor.
*/
- template<uint OtherInlineBufferCapacity>
+ template<int64_t OtherInlineBufferCapacity>
Vector(const Vector<T, OtherInlineBufferCapacity, Allocator> &other)
- : allocator_(other.allocator_)
+ : Vector(other.as_span(), other.allocator_)
{
- this->init_copy_from_other_vector(other);
}
/**
* Steal the elements from another vector. This does not do an allocation. The other vector will
* have zero elements afterwards.
*/
- template<uint OtherInlineBufferCapacity>
+ template<int64_t OtherInlineBufferCapacity>
Vector(Vector<T, OtherInlineBufferCapacity, Allocator> &&other) noexcept
: allocator_(other.allocator_)
{
- const uint size = other.size();
+ const int64_t size = other.size();
if (other.is_inline()) {
if (size <= InlineBufferCapacity) {
/* Copy between inline buffers. */
- begin_ = this->inline_buffer();
+ begin_ = inline_buffer_;
end_ = begin_ + size;
capacity_end_ = begin_ + InlineBufferCapacity;
uninitialized_relocate_n(other.begin_, size, begin_);
}
else {
/* Copy from inline buffer to newly allocated buffer. */
- const uint capacity = size;
- begin_ = (T *)allocator_.allocate(sizeof(T) * capacity, alignof(T), AT);
+ const int64_t capacity = size;
+ begin_ = (T *)allocator_.allocate(sizeof(T) * (size_t)capacity, alignof(T), AT);
end_ = begin_ + size;
capacity_end_ = begin_ + capacity;
uninitialized_relocate_n(other.begin_, size, begin_);
@@ -248,7 +256,7 @@ class Vector {
capacity_end_ = other.capacity_end_;
}
- other.begin_ = other.inline_buffer();
+ other.begin_ = other.inline_buffer_;
other.end_ = other.begin_;
other.capacity_end_ = other.begin_ + OtherInlineBufferCapacity;
UPDATE_VECTOR_SIZE(this);
@@ -293,14 +301,16 @@ class Vector {
* Get the value at the given index. This invokes undefined behavior when the index is out of
* bounds.
*/
- const T &operator[](uint index) const
+ const T &operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
return begin_[index];
}
- T &operator[](uint index)
+ T &operator[](int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
return begin_[index];
}
@@ -315,6 +325,18 @@ class Vector {
return MutableSpan<T>(begin_, this->size());
}
+ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<T, U>> * = nullptr>
+ operator Span<U>() const
+ {
+ return Span<U>(begin_, this->size());
+ }
+
+ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<T, U>> * = nullptr>
+ operator MutableSpan<U>()
+ {
+ return MutableSpan<U>(begin_, this->size());
+ }
+
Span<T> as_span() const
{
return *this;
@@ -330,7 +352,7 @@ class Vector {
* This won't necessarily make an allocation when min_capacity is small.
* The actual size of the vector does not change.
*/
- void reserve(const uint min_capacity)
+ void reserve(const int64_t min_capacity)
{
if (min_capacity > this->capacity()) {
this->realloc_to_at_least(min_capacity);
@@ -343,9 +365,10 @@ class Vector {
* destructed. If new_size is larger than the old size, the new elements at the end are default
* constructed. If T is trivially constructible, the memory is not touched by this function.
*/
- void resize(const uint new_size)
+ void resize(const int64_t new_size)
{
- const uint old_size = this->size();
+ BLI_assert(new_size >= 0);
+ const int64_t old_size = this->size();
if (new_size > old_size) {
this->reserve(new_size);
default_construct_n(begin_ + old_size, new_size - old_size);
@@ -363,9 +386,10 @@ class Vector {
* destructed. If new_size is larger than the old size, the new elements will be copy constructed
* from the given value.
*/
- void resize(const uint new_size, const T &value)
+ void resize(const int64_t new_size, const T &value)
{
- const uint old_size = this->size();
+ BLI_assert(new_size >= 0);
+ const int64_t old_size = this->size();
if (new_size > old_size) {
this->reserve(new_size);
uninitialized_fill_n(begin_ + old_size, new_size - old_size, value);
@@ -399,7 +423,7 @@ class Vector {
allocator_.deallocate(begin_);
}
- begin_ = this->inline_buffer();
+ begin_ = inline_buffer_;
end_ = begin_;
capacity_end_ = begin_ + InlineBufferCapacity;
UPDATE_VECTOR_SIZE(this);
@@ -426,9 +450,9 @@ class Vector {
* Append the value to the vector and return the index that can be used to access the newly
* added value.
*/
- uint append_and_get_index(const T &value)
+ int64_t append_and_get_index(const T &value)
{
- const uint index = this->size();
+ const int64_t index = this->size();
this->append(value);
return index;
}
@@ -469,8 +493,9 @@ class Vector {
* Insert the same element n times at the end of the vector.
* This might result in a reallocation internally.
*/
- void append_n_times(const T &value, const uint n)
+ void append_n_times(const T &value, const int64_t n)
{
+ BLI_assert(n >= 0);
this->reserve(this->size() + n);
blender::uninitialized_fill_n(end_, n, value);
this->increase_size_by_unchecked(n);
@@ -482,7 +507,7 @@ class Vector {
* useful when you want to call constructors in the vector yourself. This should only be done in
* very rare cases and has to be justified every time.
*/
- void increase_size_by_unchecked(const uint n)
+ void increase_size_by_unchecked(const int64_t n)
{
BLI_assert(end_ + n <= capacity_end_);
end_ += n;
@@ -498,7 +523,7 @@ class Vector {
{
this->extend(array.data(), array.size());
}
- void extend(const T *start, uint amount)
+ void extend(const T *start, int64_t amount)
{
this->reserve(this->size() + amount);
this->extend_unchecked(start, amount);
@@ -524,8 +549,9 @@ class Vector {
{
this->extend_unchecked(array.data(), array.size());
}
- void extend_unchecked(const T *start, uint amount)
+ void extend_unchecked(const T *start, int64_t amount)
{
+ BLI_assert(amount >= 0);
BLI_assert(begin_ + amount <= capacity_end_);
blender::uninitialized_copy_n(start, amount, end_);
end_ += amount;
@@ -534,7 +560,7 @@ class Vector {
/**
* Return a reference to the last element in the vector.
- * This will assert when the vector is empty.
+ * This invokes undefined behavior when the vector is empty.
*/
const T &last() const
{
@@ -548,28 +574,12 @@ class Vector {
}
/**
- * Replace every element with a new value.
- */
- void fill(const T &value)
- {
- initialized_fill_n(begin_, this->size(), value);
- }
-
- /**
- * Copy the value to all positions specified by the indices array.
- */
- void fill_indices(Span<uint> indices, const T &value)
- {
- MutableSpan<T>(*this).fill_indices(indices, value);
- }
-
- /**
* Return how many values are currently stored in the vector.
*/
- uint size() const
+ int64_t size() const
{
- BLI_assert(debug_size_ == (uint)(end_ - begin_));
- return (uint)(end_ - begin_);
+ BLI_assert(debug_size_ == (int64_t)(end_ - begin_));
+ return (int64_t)(end_ - begin_);
}
/**
@@ -614,8 +624,9 @@ class Vector {
* Delete any element in the vector. The empty space will be filled by the previously last
* element. This takes O(1) time.
*/
- void remove_and_reorder(const uint index)
+ void remove_and_reorder(const int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
T *element_to_remove = begin_ + index;
end_--;
@@ -632,8 +643,8 @@ class Vector {
*/
void remove_first_occurrence_and_reorder(const T &value)
{
- const uint index = this->first_index_of(value);
- this->remove_and_reorder((uint)index);
+ const int64_t index = this->first_index_of(value);
+ this->remove_and_reorder(index);
}
/**
@@ -643,11 +654,12 @@ class Vector {
*
* This is similar to std::vector::erase.
*/
- void remove(const uint index)
+ void remove(const int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
- const uint last_index = this->size() - 1;
- for (uint i = index; i < last_index; i++) {
+ const int64_t last_index = this->size() - 1;
+ for (int64_t i = index; i < last_index; i++) {
begin_[i] = std::move(begin_[i + 1]);
}
begin_[last_index].~T();
@@ -659,11 +671,11 @@ class Vector {
* Do a linear search to find the value in the vector.
* When found, return the first index, otherwise return -1.
*/
- int first_index_of_try(const T &value) const
+ int64_t first_index_of_try(const T &value) const
{
for (const T *current = begin_; current != end_; current++) {
if (*current == value) {
- return (int)(current - begin_);
+ return (int64_t)(current - begin_);
}
}
return -1;
@@ -673,11 +685,11 @@ class Vector {
* Do a linear search to find the value in the vector and return the found index. This invokes
* undefined behavior when the value is not in the vector.
*/
- uint first_index_of(const T &value) const
+ int64_t first_index_of(const T &value) const
{
- const int index = this->first_index_of_try(value);
+ const int64_t index = this->first_index_of_try(value);
BLI_assert(index >= 0);
- return (uint)index;
+ return index;
}
/**
@@ -690,6 +702,14 @@ class Vector {
}
/**
+ * Copies the given value to every element in the vector.
+ */
+ void fill(const T &value) const
+ {
+ initialized_fill_n(begin_, this->size(), value);
+ }
+
+ /**
* Get access to the underlying array.
*/
T *data()
@@ -727,9 +747,9 @@ class Vector {
* Get the current capacity of the vector, i.e. the maximum number of elements the vector can
* hold, before it has to reallocate.
*/
- uint capacity() const
+ int64_t capacity() const
{
- return (uint)(capacity_end_ - begin_);
+ return (int64_t)(capacity_end_ - begin_);
}
/**
@@ -737,7 +757,7 @@ class Vector {
* Obviously, this should only be used when you actually need the index in the loop.
*
* Example:
- * for (uint i : myvector.index_range()) {
+ * for (int64_t i : myvector.index_range()) {
* do_something(i, my_vector[i]);
* }
*/
@@ -763,14 +783,9 @@ class Vector {
}
private:
- T *inline_buffer() const
- {
- return (T *)inline_buffer_.ptr();
- }
-
bool is_inline() const
{
- return begin_ == this->inline_buffer();
+ return begin_ == inline_buffer_;
}
void ensure_space_for_one()
@@ -780,7 +795,7 @@ class Vector {
}
}
- BLI_NOINLINE void realloc_to_at_least(const uint min_capacity)
+ BLI_NOINLINE void realloc_to_at_least(const int64_t min_capacity)
{
if (this->capacity() >= min_capacity) {
return;
@@ -788,12 +803,12 @@ class Vector {
/* At least double the size of the previous allocation. Otherwise consecutive calls to grow can
* cause a reallocation every time even though min_capacity only increments. */
- const uint min_new_capacity = this->capacity() * 2;
+ const int64_t min_new_capacity = this->capacity() * 2;
- const uint new_capacity = std::max(min_capacity, min_new_capacity);
- const uint size = this->size();
+ const int64_t new_capacity = std::max(min_capacity, min_new_capacity);
+ const int64_t size = this->size();
- T *new_array = (T *)allocator_.allocate(new_capacity * (uint)sizeof(T), alignof(T), AT);
+ T *new_array = (T *)allocator_.allocate((size_t)new_capacity * sizeof(T), alignof(T), AT);
uninitialized_relocate_n(begin_, size, new_array);
if (!this->is_inline()) {
@@ -804,44 +819,15 @@ class Vector {
end_ = begin_ + size;
capacity_end_ = begin_ + new_capacity;
}
-
- /**
- * Initialize all properties, except for allocator_, which has to be initialized beforehand.
- */
- template<uint OtherInlineBufferCapacity>
- void init_copy_from_other_vector(const Vector<T, OtherInlineBufferCapacity, Allocator> &other)
- {
- allocator_ = other.allocator_;
-
- const uint size = other.size();
- uint capacity;
-
- if (size <= InlineBufferCapacity) {
- begin_ = this->inline_buffer();
- capacity = InlineBufferCapacity;
- }
- else {
- begin_ = (T *)allocator_.allocate(sizeof(T) * size, alignof(T), AT);
- capacity = size;
- }
-
- end_ = begin_ + size;
- capacity_end_ = begin_ + capacity;
-
- uninitialized_copy_n(other.data(), size, begin_);
- UPDATE_VECTOR_SIZE(this);
- }
};
#undef UPDATE_VECTOR_SIZE
/**
- * Use when the vector is used in the local scope of a function. It has a larger inline storage by
- * default to make allocations less likely.
+ * Same as a normal Vector, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
*/
-template<typename T, uint InlineBufferCapacity = 20>
-using ScopedVector = Vector<T, InlineBufferCapacity, GuardedAllocator>;
+template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
+using RawVector = Vector<T, InlineBufferCapacity, RawAllocator>;
} /* namespace blender */
-
-#endif /* __BLI_VECTOR_HH__ */
diff --git a/source/blender/blenlib/BLI_vector_adaptor.hh b/source/blender/blenlib/BLI_vector_adaptor.hh
new file mode 100644
index 00000000000..9c805f242e4
--- /dev/null
+++ b/source/blender/blenlib/BLI_vector_adaptor.hh
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * A `blender::VectorAdaptor` is a container with a fixed maximum size and does not own the
+ * underlying memory. When an adaptor is constructed, you have to provide it with an uninitialized
+ * array that will be filled when elements are added to the vector. The vector adaptor is not able
+ * to grow. Therefore, it is undefined behavior to add more elements than fit into the provided
+ * buffer.
+ */
+
+#include "BLI_span.hh"
+
+namespace blender {
+
+template<typename T> class VectorAdaptor {
+ private:
+ T *begin_;
+ T *end_;
+ T *capacity_end_;
+
+ public:
+ VectorAdaptor() : begin_(nullptr), end_(nullptr), capacity_end_(nullptr)
+ {
+ }
+
+ VectorAdaptor(T *data, int64_t capacity, int64_t size = 0)
+ : begin_(data), end_(data + size), capacity_end_(data + capacity)
+ {
+ }
+
+ VectorAdaptor(MutableSpan<T> span) : VectorAdaptor(span.data(), span.size(), 0)
+ {
+ }
+
+ void append(const T &value)
+ {
+ BLI_assert(end_ < capacity_end_);
+ new (end_) T(value);
+ end_++;
+ }
+
+ void append(T &&value)
+ {
+ BLI_assert(end_ < capacity_end_);
+ new (end_) T(std::move(value));
+ end_++;
+ }
+
+ void append_n_times(const T &value, int64_t n)
+ {
+ BLI_assert(end_ + n <= capacity_end_);
+ uninitialized_fill_n(end_, n, value);
+ end_ += n;
+ }
+
+ void extend(Span<T> values)
+ {
+ BLI_assert(end_ + values.size() <= capacity_end_);
+ uninitialized_copy_n(values.data(), values.size(), end_);
+ end_ += values.size();
+ }
+
+ int64_t capacity() const
+ {
+ return capacity_end_ - begin_;
+ }
+
+ int64_t size() const
+ {
+ return end_ - begin_;
+ }
+
+ bool is_empty() const
+ {
+ return begin_ == end_;
+ }
+
+ bool is_full() const
+ {
+ return end_ == capacity_end_;
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh
index a39f6a97f70..c3b15bcf454 100644
--- a/source/blender/blenlib/BLI_vector_set.hh
+++ b/source/blender/blenlib/BLI_vector_set.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_VECTOR_SET_HH__
-#define __BLI_VECTOR_SET_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -106,20 +105,20 @@ class VectorSet {
* Slots are either empty, occupied or removed. The number of occupied slots can be computed by
* subtracting the removed slots from the occupied-and-removed slots.
*/
- uint32_t removed_slots_;
- uint32_t occupied_and_removed_slots_;
+ int64_t removed_slots_;
+ int64_t occupied_and_removed_slots_;
/**
* The maximum number of slots that can be used (either occupied or removed) until the set has to
* grow. This is the total number of slots times the max load factor.
*/
- uint32_t usable_slots_;
+ int64_t usable_slots_;
/**
* The number of slots minus one. This is a bit mask that can be used to turn any integer into a
* valid slot index efficiently.
*/
- uint32_t slot_mask_;
+ uint64_t slot_mask_;
/** This is called to hash incoming keys. */
Hash hash_;
@@ -238,8 +237,9 @@ class VectorSet {
/**
* Get the key stored at the given position in the vector.
*/
- const Key &operator[](const uint32_t index) const
+ const Key &operator[](const int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index <= this->size());
return keys_[index];
}
@@ -288,10 +288,6 @@ class VectorSet {
{
return this->add_as(std::move(key));
}
-
- /**
- * Same as `add`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> bool add_as(ForwardKey &&key)
{
return this->add__impl(std::forward<ForwardKey>(key), hash_(key));
@@ -320,10 +316,6 @@ class VectorSet {
{
return this->contains_as(key);
}
-
- /**
- * Same as `contains`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> bool contains_as(const ForwardKey &key) const
{
return this->contains__impl(key, hash_(key));
@@ -339,10 +331,6 @@ class VectorSet {
{
return this->remove_as(key);
}
-
- /**
- * Same as `remove`, but accepts other key types that are supported by the hash function.
- */
template<typename ForwardKey> bool remove_as(const ForwardKey &key)
{
return this->remove__impl(key, hash_(key));
@@ -356,11 +344,6 @@ class VectorSet {
{
this->remove_contained_as(key);
}
-
- /**
- * Same as `remove_contained`, but accepts other key types that are supported by the hash
- * function.
- */
template<typename ForwardKey> void remove_contained_as(const ForwardKey &key)
{
this->remove_contained__impl(key, hash_(key));
@@ -379,15 +362,11 @@ class VectorSet {
* Return the location of the key in the vector. It is assumed, that the key is in the vector
* set. If this is not necessarily the case, use `index_of_try`.
*/
- uint32_t index_of(const Key &key) const
+ int64_t index_of(const Key &key) const
{
return this->index_of_as(key);
}
-
- /**
- * Same as `index_of`, but accepts other key types that are supported by the hash function.
- */
- template<typename ForwardKey> uint32_t index_of_as(const ForwardKey &key) const
+ template<typename ForwardKey> int64_t index_of_as(const ForwardKey &key) const
{
return this->index_of__impl(key, hash_(key));
}
@@ -396,15 +375,11 @@ class VectorSet {
* Return the location of the key in the vector. If the key is not in the set, -1 is returned.
* If you know for sure that the key is in the set, it is better to use `index_of` instead.
*/
- int32_t index_of_try(const Key &key) const
+ int64_t index_of_try(const Key &key) const
{
- return (int32_t)this->index_of_try_as(key);
+ return this->index_of_try_as(key);
}
-
- /**
- * Same as `index_of_try`, but accepts other key types that are supported by the hash function.
- */
- template<typename ForwardKey> int32_t index_of_try_as(const ForwardKey &key) const
+ template<typename ForwardKey> int64_t index_of_try_as(const ForwardKey &key) const
{
return this->index_of_try__impl(key, hash_(key));
}
@@ -439,7 +414,7 @@ class VectorSet {
/**
* Returns the number of keys stored in the vector set.
*/
- uint32_t size() const
+ int64_t size() const
{
return occupied_and_removed_slots_ - removed_slots_;
}
@@ -455,7 +430,7 @@ class VectorSet {
/**
* Returns the number of available slots. This is mostly for debugging purposes.
*/
- uint32_t capacity() const
+ int64_t capacity() const
{
return slots_.size();
}
@@ -463,7 +438,7 @@ class VectorSet {
/**
* Returns the amount of removed slots in the set. This is mostly for debugging purposes.
*/
- uint32_t removed_amount() const
+ int64_t removed_amount() const
{
return removed_slots_;
}
@@ -471,7 +446,7 @@ class VectorSet {
/**
* Returns the bytes required per element. This is mostly for debugging purposes.
*/
- uint32_t size_per_element() const
+ int64_t size_per_element() const
{
return sizeof(Slot) + sizeof(Key);
}
@@ -480,15 +455,15 @@ class VectorSet {
* Returns the approximate memory requirements of the set in bytes. This is more correct for
* larger sets.
*/
- uint32_t size_in_bytes() const
+ int64_t size_in_bytes() const
{
- return (uint32_t)(sizeof(Slot) * slots_.size() + sizeof(Key) * usable_slots_);
+ return (int64_t)(sizeof(Slot) * slots_.size() + sizeof(Key) * usable_slots_);
}
/**
* Potentially resize the vector set such that it can hold n elements without doing another grow.
*/
- void reserve(const uint32_t n)
+ void reserve(const int64_t n)
{
if (usable_slots_ < n) {
this->realloc_and_reinsert(n);
@@ -499,18 +474,19 @@ class VectorSet {
* Get the number of collisions that the probing strategy has to go through to find the key or
* determine that it is not in the set.
*/
- uint32_t count_collisions(const Key &key) const
+ int64_t count_collisions(const Key &key) const
{
return this->count_collisions__impl(key, hash_(key));
}
private:
- BLI_NOINLINE void realloc_and_reinsert(const uint32_t min_usable_slots)
+ BLI_NOINLINE void realloc_and_reinsert(const int64_t min_usable_slots)
{
- uint32_t total_slots, usable_slots;
+ int64_t total_slots, usable_slots;
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
- const uint32_t new_slot_mask = total_slots - 1;
+ BLI_assert(total_slots >= 1);
+ const uint64_t new_slot_mask = (uint64_t)total_slots - 1;
/* Optimize the case when the set was empty beforehand. We can avoid some copies here. */
if (this->size() == 0) {
@@ -549,10 +525,10 @@ class VectorSet {
void add_after_grow_and_destruct_old(Slot &old_slot,
SlotArray &new_slots,
- const uint32_t new_slot_mask)
+ const uint64_t new_slot_mask)
{
const Key &key = keys_[old_slot.index()];
- const uint32_t hash = old_slot.get_hash(key, Hash());
+ const uint64_t hash = old_slot.get_hash(key, Hash());
SLOT_PROBING_BEGIN (ProbingStrategy, hash, new_slot_mask, slot_index) {
Slot &slot = new_slots[slot_index];
@@ -565,7 +541,7 @@ class VectorSet {
}
template<typename ForwardKey>
- bool contains__impl(const ForwardKey &key, const uint32_t hash) const
+ bool contains__impl(const ForwardKey &key, const uint64_t hash) const
{
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
@@ -578,7 +554,7 @@ class VectorSet {
VECTOR_SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> void add_new__impl(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey> void add_new__impl(ForwardKey &&key, const uint64_t hash)
{
BLI_assert(!this->contains_as(key));
@@ -586,7 +562,7 @@ class VectorSet {
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
- uint32_t index = this->size();
+ int64_t index = this->size();
new (keys_ + index) Key(std::forward<ForwardKey>(key));
slot.occupy(index, hash);
occupied_and_removed_slots_++;
@@ -596,13 +572,13 @@ class VectorSet {
VECTOR_SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool add__impl(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey> bool add__impl(ForwardKey &&key, const uint64_t hash)
{
this->ensure_can_add();
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
- uint32_t index = this->size();
+ int64_t index = this->size();
new (keys_ + index) Key(std::forward<ForwardKey>(key));
occupied_and_removed_slots_++;
slot.occupy(index, hash);
@@ -616,7 +592,7 @@ class VectorSet {
}
template<typename ForwardKey>
- uint32_t index_of__impl(const ForwardKey &key, const uint32_t hash) const
+ int64_t index_of__impl(const ForwardKey &key, const uint64_t hash) const
{
BLI_assert(this->contains_as(key));
@@ -629,11 +605,11 @@ class VectorSet {
}
template<typename ForwardKey>
- int32_t index_of_try__impl(const ForwardKey &key, const uint32_t hash) const
+ int64_t index_of_try__impl(const ForwardKey &key, const uint64_t hash) const
{
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash, keys_)) {
- return (int32_t)slot.index();
+ return slot.index();
}
if (slot.is_empty()) {
return -1;
@@ -646,10 +622,10 @@ class VectorSet {
{
BLI_assert(this->size() > 0);
- const uint32_t index_to_pop = this->size() - 1;
+ const int64_t index_to_pop = this->size() - 1;
Key key = std::move(keys_[index_to_pop]);
keys_[index_to_pop].~Key();
- const uint32_t hash = hash_(key);
+ const uint64_t hash = hash_(key);
removed_slots_++;
@@ -662,7 +638,7 @@ class VectorSet {
VECTOR_SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool remove__impl(const ForwardKey &key, const uint32_t hash)
+ template<typename ForwardKey> bool remove__impl(const ForwardKey &key, const uint64_t hash)
{
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash, keys_)) {
@@ -677,7 +653,7 @@ class VectorSet {
}
template<typename ForwardKey>
- void remove_contained__impl(const ForwardKey &key, const uint32_t hash)
+ void remove_contained__impl(const ForwardKey &key, const uint64_t hash)
{
BLI_assert(this->contains_as(key));
@@ -692,9 +668,9 @@ class VectorSet {
void remove_key_internal(Slot &slot)
{
- uint32_t index_to_remove = slot.index();
- uint32_t size = this->size();
- uint32_t last_element_index = size - 1;
+ int64_t index_to_remove = slot.index();
+ int64_t size = this->size();
+ int64_t last_element_index = size - 1;
if (index_to_remove < last_element_index) {
keys_[index_to_remove] = std::move(keys_[last_element_index]);
@@ -707,9 +683,9 @@ class VectorSet {
return;
}
- void update_slot_index(const Key &key, const uint32_t old_index, const uint32_t new_index)
+ void update_slot_index(const Key &key, const int64_t old_index, const int64_t new_index)
{
- uint32_t hash = hash_(key);
+ uint64_t hash = hash_(key);
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.has_index(old_index)) {
slot.update_index(new_index);
@@ -720,9 +696,9 @@ class VectorSet {
}
template<typename ForwardKey>
- uint32_t count_collisions__impl(const ForwardKey &key, const uint32_t hash) const
+ int64_t count_collisions__impl(const ForwardKey &key, const uint64_t hash) const
{
- uint32_t collisions = 0;
+ int64_t collisions = 0;
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash, keys_)) {
@@ -744,9 +720,9 @@ class VectorSet {
}
}
- Key *allocate_keys_array(const uint32_t size)
+ Key *allocate_keys_array(const int64_t size)
{
- return (Key *)slots_.allocator().allocate((uint32_t)sizeof(Key) * size, alignof(Key), AT);
+ return (Key *)slots_.allocator().allocate(sizeof(Key) * (size_t)size, alignof(Key), AT);
}
void deallocate_keys_array(Key *keys)
@@ -755,6 +731,15 @@ class VectorSet {
}
};
-} // namespace blender
+/**
+ * Same as a normal VectorSet, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename Key,
+ typename ProbingStrategy = DefaultProbingStrategy,
+ typename Hash = DefaultHash<Key>,
+ typename IsEqual = DefaultEquality,
+ typename Slot = typename DefaultVectorSetSlot<Key>::type>
+using RawVectorSet = VectorSet<Key, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>;
-#endif /* __BLI_VECTOR_SET_HH__ */
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_vector_set_slots.hh b/source/blender/blenlib/BLI_vector_set_slots.hh
index e43b892b3f7..0e75c4690a4 100644
--- a/source/blender/blenlib/BLI_vector_set_slots.hh
+++ b/source/blender/blenlib/BLI_vector_set_slots.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLI_VECTOR_SET_SLOTS_HH__
-#define __BLI_VECTOR_SET_SLOTS_HH__
+#pragma once
/** \file
* \ingroup bli
@@ -53,7 +52,7 @@ template<typename Key> class SimpleVectorSetSlot {
/**
* After the default constructor has run, the slot has to be in the empty state.
*/
- int32_t state_ = s_is_empty;
+ int64_t state_ = s_is_empty;
public:
/**
@@ -75,10 +74,10 @@ template<typename Key> class SimpleVectorSetSlot {
/**
* Return the stored index. It is assumed that the slot is occupied.
*/
- uint32_t index() const
+ int64_t index() const
{
BLI_assert(this->is_occupied());
- return (uint32_t)state_;
+ return state_;
}
/**
@@ -88,7 +87,7 @@ template<typename Key> class SimpleVectorSetSlot {
template<typename ForwardKey, typename IsEqual>
bool contains(const ForwardKey &key,
const IsEqual &is_equal,
- uint32_t UNUSED(hash),
+ uint64_t UNUSED(hash),
const Key *keys) const
{
if (state_ >= 0) {
@@ -102,7 +101,7 @@ template<typename Key> class SimpleVectorSetSlot {
* we can avoid a comparison with the state, since we know the slot is occupied. For this
* specific slot implementation, this does not make a difference.
*/
- void relocate_occupied_here(SimpleVectorSetSlot &other, uint32_t UNUSED(hash))
+ void relocate_occupied_here(SimpleVectorSetSlot &other, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
@@ -113,20 +112,20 @@ template<typename Key> class SimpleVectorSetSlot {
* Change the state of this slot from empty/removed to occupied. The hash can be used by other
* slot implementations.
*/
- void occupy(uint32_t index, uint32_t UNUSED(hash))
+ void occupy(int64_t index, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
- state_ = (int32_t)index;
+ state_ = index;
}
/**
* The key has changed its position in the vector, so the index has to be updated. This method
* can assume that the slot is currently occupied.
*/
- void update_index(uint32_t index)
+ void update_index(int64_t index)
{
BLI_assert(this->is_occupied());
- state_ = (int32_t)index;
+ state_ = index;
}
/**
@@ -141,16 +140,16 @@ template<typename Key> class SimpleVectorSetSlot {
/**
* Return true if this slot is currently occupied and its corresponding key has the given index.
*/
- bool has_index(uint32_t index) const
+ bool has_index(int64_t index) const
{
- return (uint32_t)state_ == index;
+ return state_ == index;
}
/**
* Return the hash of the currently stored key. In this simple set slot implementation, we just
* compute the hash here. Other implementations might store the hash in the slot instead.
*/
- template<typename Hash> uint32_t get_hash(const Key &key, const Hash &hash) const
+ template<typename Hash> uint64_t get_hash(const Key &key, const Hash &hash) const
{
BLI_assert(this->is_occupied());
return hash(key);
@@ -167,5 +166,3 @@ template<typename Key> struct DefaultVectorSetSlot {
};
} // namespace blender
-
-#endif /* __BLI_VECTOR_SET_SLOTS_HH__ */
diff --git a/source/blender/blenlib/BLI_vfontdata.h b/source/blender/blenlib/BLI_vfontdata.h
index 047a72ec59a..0bb32ca24b7 100644
--- a/source/blender/blenlib/BLI_vfontdata.h
+++ b/source/blender/blenlib/BLI_vfontdata.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_VFONTDATA_H__
-#define __BLI_VFONTDATA_H__
+#pragma once
/** \file
* \ingroup bli
@@ -59,5 +58,3 @@ VChar *BLI_vfontchar_copy(const VChar *vchar_src, const int flag);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenlib/BLI_voronoi_2d.h b/source/blender/blenlib/BLI_voronoi_2d.h
index a48f32c283a..92c7d367b48 100644
--- a/source/blender/blenlib/BLI_voronoi_2d.h
+++ b/source/blender/blenlib/BLI_voronoi_2d.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_VORONOI_2D_H__
-#define __BLI_VORONOI_2D_H__
+#pragma once
struct ListBase;
@@ -81,5 +80,3 @@ void BLI_voronoi_triangulate(const VoronoiSite *sites,
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_VORONOI_2D_H__ */
diff --git a/source/blender/blenlib/BLI_voxel.h b/source/blender/blenlib/BLI_voxel.h
index 220ab9b3705..eb84f0a27ee 100644
--- a/source/blender/blenlib/BLI_voxel.h
+++ b/source/blender/blenlib/BLI_voxel.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_VOXEL_H__
-#define __BLI_VOXEL_H__
+#pragma once
/** \file
* \ingroup bli
@@ -35,13 +34,14 @@ extern "C" {
(int64_t)(z) * (int64_t)(res)[0] * (int64_t)(res)[1])
/* all input coordinates must be in bounding box 0.0 - 1.0 */
-float BLI_voxel_sample_nearest(float *data, const int res[3], const float co[3]);
-float BLI_voxel_sample_trilinear(float *data, const int res[3], const float co[3]);
-float BLI_voxel_sample_triquadratic(float *data, const int res[3], const float co[3]);
-float BLI_voxel_sample_tricubic(float *data, const int res[3], const float co[3], int bspline);
+float BLI_voxel_sample_nearest(const float *data, const int res[3], const float co[3]);
+float BLI_voxel_sample_trilinear(const float *data, const int res[3], const float co[3]);
+float BLI_voxel_sample_triquadratic(const float *data, const int res[3], const float co[3]);
+float BLI_voxel_sample_tricubic(const float *data,
+ const int res[3],
+ const float co[3],
+ int bspline);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_VOXEL_H__ */
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index 3d59ad21251..2de6098f6be 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLI_WINSTUFF_H__
-#define __BLI_WINSTUFF_H__
+#pragma once
/** \file
* \ingroup bli
@@ -111,5 +110,3 @@ int BLI_getInstallationDir(char *str);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLI_WINSTUFF_H__ */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index e599b00401a..a5af517ecca 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -37,6 +37,7 @@ set(INC_SYS
set(SRC
intern/BLI_args.c
intern/BLI_array.c
+ intern/BLI_assert.c
intern/BLI_dial_2d.c
intern/BLI_dynstr.c
intern/BLI_filelist.c
@@ -86,6 +87,7 @@ set(SRC
intern/listbase.c
intern/math_base.c
intern/math_base_inline.c
+ intern/math_base_safe_inline.c
intern/math_bits_inline.c
intern/math_color.c
intern/math_color_blend_inline.c
@@ -105,10 +107,11 @@ set(SRC
intern/polyfill_2d.c
intern/polyfill_2d_beautify.c
intern/quadric.c
- intern/rand.c
+ intern/rand.cc
intern/rct.c
intern/scanfill.c
intern/scanfill_utils.c
+ intern/session_uuid.c
intern/smallhash.c
intern/sort.c
intern/sort_utils.c
@@ -163,6 +166,7 @@ set(SRC
BLI_convexhull_2d.h
BLI_delaunay_2d.h
BLI_dial_2d.h
+ BLI_disjoint_set.hh
BLI_dlrbTree.h
BLI_dot_export.hh
BLI_dot_export_attribute_enums.hh
@@ -197,6 +201,7 @@ set(SRC
BLI_kdtree.h
BLI_kdtree_impl.h
BLI_lasso_2d.h
+ BLI_linear_allocator.hh
BLI_link_utils.h
BLI_linklist.h
BLI_linklist_lockfree.h
@@ -207,6 +212,7 @@ set(SRC
BLI_map_slots.hh
BLI_math.h
BLI_math_base.h
+ BLI_math_base_safe.h
BLI_math_bits.h
BLI_math_color.h
BLI_math_color_blend.h
@@ -231,8 +237,11 @@ set(SRC
BLI_probing_strategies.hh
BLI_quadric.h
BLI_rand.h
+ BLI_rand.hh
BLI_rect.h
+ BLI_resource_collector.hh
BLI_scanfill.h
+ BLI_session_uuid.h
BLI_set.hh
BLI_set_slots.hh
BLI_smallhash.h
@@ -261,6 +270,7 @@ set(SRC
BLI_utility_mixins.hh
BLI_uvproject.h
BLI_vector.hh
+ BLI_vector_adaptor.hh
BLI_vector_set.hh
BLI_vector_set_slots.hh
BLI_vfontdata.h
@@ -324,6 +334,7 @@ endif()
# no need to compile object files for inline headers.
set_source_files_properties(
intern/math_base_inline.c
+ intern/math_base_safe_inline.c
intern/math_bits_inline.c
intern/math_color_blend_inline.c
intern/math_color_inline.c
@@ -333,3 +344,29 @@ set_source_files_properties(
)
blender_add_lib(bf_blenlib "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+if(WITH_GTESTS)
+ set(TEST_SRC
+ tests/BLI_array_test.cc
+ tests/BLI_disjoint_set_test.cc
+ tests/BLI_edgehash_test.cc
+ tests/BLI_index_mask_test.cc
+ tests/BLI_index_range_test.cc
+ tests/BLI_linear_allocator_test.cc
+ tests/BLI_map_test.cc
+ tests/BLI_math_base_safe_test.cc
+ tests/BLI_memory_utils_test.cc
+ tests/BLI_multi_value_map_test.cc
+ tests/BLI_set_test.cc
+ tests/BLI_span_test.cc
+ tests/BLI_stack_cxx_test.cc
+ tests/BLI_string_ref_test.cc
+ tests/BLI_vector_set_test.cc
+ tests/BLI_vector_test.cc
+ )
+ set(TEST_LIB
+ bf_blenlib
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_bli_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
+endif()
diff --git a/source/blender/blenlib/PIL_time.h b/source/blender/blenlib/PIL_time.h
index 21ebc9d4b90..311869e844a 100644
--- a/source/blender/blenlib/PIL_time.h
+++ b/source/blender/blenlib/PIL_time.h
@@ -22,8 +22,7 @@
* \brief Platform independent time functions.
*/
-#ifndef __PIL_TIME_H__
-#define __PIL_TIME_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -51,5 +50,3 @@ void PIL_sleep_ms(int ms);
#ifdef __cplusplus
}
#endif
-
-#endif /* __PIL_TIME_H__ */
diff --git a/source/blender/blenlib/PIL_time_utildefines.h b/source/blender/blenlib/PIL_time_utildefines.h
index ffe753badf8..d404a8b2b8a 100644
--- a/source/blender/blenlib/PIL_time_utildefines.h
+++ b/source/blender/blenlib/PIL_time_utildefines.h
@@ -22,8 +22,7 @@
* \brief Utility defines for timing/benchmarks.
*/
-#ifndef __PIL_TIME_UTILDEFINES_H__
-#define __PIL_TIME_UTILDEFINES_H__
+#pragma once
#include "BLI_utildefines.h" /* for AT */
#include "PIL_time.h" /* for PIL_check_seconds_timer */
@@ -127,5 +126,3 @@
fflush(stdout); \
} \
(void)0
-
-#endif /* __PIL_TIME_UTILDEFINES_H__ */
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index 2b078b3bae5..91aabca7747 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -92,13 +92,9 @@ static bool keycmp(const void *a, const void *b)
if (ka->case_str == 1 || kb->case_str == 1) {
return (BLI_strcasecmp(ka->arg, kb->arg) != 0);
}
- else {
- return (!STREQ(ka->arg, kb->arg));
- }
- }
- else {
- return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass);
+ return (!STREQ(ka->arg, kb->arg));
}
+ return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass);
}
static bArgument *lookUp(struct bArgs *ba, const char *arg, int pass, int case_str)
diff --git a/source/blender/blenlib/intern/BLI_assert.c b/source/blender/blenlib/intern/BLI_assert.c
new file mode 100644
index 00000000000..dc22d035459
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_assert.c
@@ -0,0 +1,51 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bli
+ *
+ * Helper functions for BLI_assert.h header.
+ */
+
+#include "BLI_assert.h" /* Own include. */
+#include "BLI_system.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void _BLI_assert_print_pos(const char *file, int line, const char *function, const char *id)
+{
+ fprintf(stderr, "BLI_assert failed: %s:%d, %s(), at \'%s\'\n", file, line, function, id);
+}
+
+void _BLI_assert_print_backtrace(void)
+{
+#ifndef NDEBUG
+ BLI_system_backtrace(stderr);
+#endif
+}
+
+/**
+ * Wrap to remove 'noreturn' attribute since this suppresses missing return statements,
+ * allowing changes to debug builds to accidentally to break release builds.
+ *
+ * For example `BLI_assert(0);` at the end of a function that returns a value,
+ * will hide that it's missing a return.
+ */
+void _BLI_assert_abort(void)
+{
+ abort();
+}
diff --git a/source/blender/blenlib/intern/BLI_dial_2d.c b/source/blender/blenlib/intern/BLI_dial_2d.c
index c6d28e20f35..7363233d573 100644
--- a/source/blender/blenlib/intern/BLI_dial_2d.c
+++ b/source/blender/blenlib/intern/BLI_dial_2d.c
@@ -45,7 +45,7 @@ struct Dial {
bool initialized;
};
-Dial *BLI_dial_initialize(const float start_position[2], float threshold)
+Dial *BLI_dial_init(const float start_position[2], float threshold)
{
Dial *dial = MEM_callocN(sizeof(Dial), "dial");
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 09dbf18acd0..69602cd4209 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -538,10 +538,8 @@ BLI_INLINE bool ghash_insert_safe(GHash *gh,
}
return false;
}
- else {
- ghash_insert_ex(gh, key, val, bucket_index);
- return true;
- }
+ ghash_insert_ex(gh, key, val, bucket_index);
+ return true;
}
BLI_INLINE bool ghash_insert_safe_keyonly(GHash *gh,
@@ -564,10 +562,8 @@ BLI_INLINE bool ghash_insert_safe_keyonly(GHash *gh,
}
return false;
}
- else {
- ghash_insert_ex_keyonly(gh, key, bucket_index);
- return true;
- }
+ ghash_insert_ex_keyonly(gh, key, bucket_index);
+ return true;
}
/**
@@ -792,9 +788,7 @@ void *BLI_ghash_replace_key(GHash *gh, void *key)
e->e.key = key;
return key_prev;
}
- else {
- return NULL;
- }
+ return NULL;
}
/**
@@ -915,9 +909,7 @@ bool BLI_ghash_remove(GHash *gh,
BLI_mempool_free(gh->entrypool, e);
return true;
}
- else {
- return false;
- }
+ return false;
}
/* same as above but return the value,
@@ -940,9 +932,7 @@ void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp)
BLI_mempool_free(gh->entrypool, e);
return val;
}
- else {
- return NULL;
- }
+ return NULL;
}
/**
@@ -975,10 +965,9 @@ bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val)
BLI_mempool_free(gh->entrypool, e);
return true;
}
- else {
- *r_key = *r_val = NULL;
- return false;
- }
+
+ *r_key = *r_val = NULL;
+ return false;
}
/**
@@ -1246,10 +1235,9 @@ bool BLI_gset_pop(GSet *gs, GSetIterState *state, void **r_key)
BLI_mempool_free(((GHash *)gs)->entrypool, e);
return true;
}
- else {
- *r_key = NULL;
- return false;
- }
+
+ *r_key = NULL;
+ return false;
}
void BLI_gset_clear_ex(GSet *gs, GSetKeyFreeFP keyfreefp, const uint nentries_reserve)
@@ -1309,9 +1297,7 @@ void *BLI_gset_pop_key(GSet *gs, const void *key)
BLI_mempool_free(((GHash *)gs)->entrypool, e);
return key_ret;
}
- else {
- return NULL;
- }
+ return NULL;
}
/** \} */
diff --git a/source/blender/blenlib/intern/BLI_ghash_utils.c b/source/blender/blenlib/intern/BLI_ghash_utils.c
index 83bf0373ae7..d6a4b24682f 100644
--- a/source/blender/blenlib/intern/BLI_ghash_utils.c
+++ b/source/blender/blenlib/intern/BLI_ghash_utils.c
@@ -86,25 +86,6 @@ bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
return (memcmp(a, b, sizeof(uint[4])) != 0);
}
-uint BLI_ghashutil_uinthash_v2(const uint key[2])
-{
- uint hash;
- hash = key[0];
- hash *= 37;
- hash += key[1];
- return hash;
-}
-
-uint BLI_ghashutil_uinthash_v2_murmur(const uint key[2])
-{
- return BLI_hash_mm2((const unsigned char *)key, sizeof(int) * 2 /* sizeof(key) */, 0);
-}
-
-bool BLI_ghashutil_uinthash_v2_cmp(const void *a, const void *b)
-{
- return (memcmp(a, b, sizeof(uint[2])) != 0);
-}
-
uint BLI_ghashutil_uinthash(uint key)
{
key += ~(key << 16);
diff --git a/source/blender/blenlib/intern/BLI_index_range.cc b/source/blender/blenlib/intern/BLI_index_range.cc
index 9fa19143f91..43c6265a17d 100644
--- a/source/blender/blenlib/intern/BLI_index_range.cc
+++ b/source/blender/blenlib/intern/BLI_index_range.cc
@@ -24,28 +24,28 @@
namespace blender {
-static Vector<Array<uint, 0, RawAllocator>, 1, RawAllocator> arrays;
-static uint current_array_size = 0;
-static uint *current_array = nullptr;
+static RawVector<RawArray<int64_t, 0>> arrays;
+static int64_t current_array_size = 0;
+static int64_t *current_array = nullptr;
static std::mutex current_array_mutex;
-Span<uint> IndexRange::as_span() const
+Span<int64_t> IndexRange::as_span() const
{
- uint min_required_size = start_ + size_;
+ int64_t min_required_size = start_ + size_;
if (min_required_size <= current_array_size) {
- return Span<uint>(current_array + start_, size_);
+ return Span<int64_t>(current_array + start_, size_);
}
std::lock_guard<std::mutex> lock(current_array_mutex);
if (min_required_size <= current_array_size) {
- return Span<uint>(current_array + start_, size_);
+ return Span<int64_t>(current_array + start_, size_);
}
- uint new_size = std::max<uint>(1000, power_of_2_max_u(min_required_size));
- Array<uint, 0, RawAllocator> new_array(new_size);
- for (uint i = 0; i < new_size; i++) {
+ int64_t new_size = std::max<int64_t>(1000, power_of_2_max_u(min_required_size));
+ RawArray<int64_t, 0> new_array(new_size);
+ for (int64_t i = 0; i < new_size; i++) {
new_array[i] = i;
}
arrays.append(std::move(new_array));
@@ -54,7 +54,7 @@ Span<uint> IndexRange::as_span() const
std::atomic_thread_fence(std::memory_order_seq_cst);
current_array_size = new_size;
- return Span<uint>(current_array + start_, size_);
+ return Span<int64_t>(current_array + start_, size_);
}
} // namespace blender
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 0707e4c1d2a..f63a523ca60 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -169,6 +169,12 @@ typedef struct BVHNearestProjectedData {
} BVHNearestProjectedData;
+typedef struct BVHIntersectPlaneData {
+ const BVHTree *tree;
+ float plane[4];
+ struct BLI_Stack *intersect; /* Store indexes. */
+} BVHIntersectPlaneData;
+
/** \} */
/**
@@ -278,28 +284,19 @@ static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis)
if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
return a[mid];
}
- else {
- if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
- return a[hi];
- }
- else {
- return a[lo];
- }
+ if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
+ return a[hi];
}
+ return a[lo];
}
- else {
- if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
- if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
- return a[lo];
- }
- else {
- return a[hi];
- }
- }
- else {
- return a[mid];
+
+ if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
+ if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
+ return a[lo];
}
+ return a[hi];
}
+ return a[mid];
}
/**
@@ -416,18 +413,12 @@ static char get_largest_axis(const float *bv)
if (middle_point[0] > middle_point[2]) {
return 1; /* max x axis */
}
- else {
- return 5; /* max z axis */
- }
+ return 5; /* max z axis */
}
- else {
- if (middle_point[1] > middle_point[2]) {
- return 3; /* max y axis */
- }
- else {
- return 5; /* max z axis */
- }
+ if (middle_point[1] > middle_point[2]) {
+ return 3; /* max y axis */
}
+ return 5; /* max z axis */
}
/**
@@ -613,13 +604,11 @@ static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, con
if (min_leaf_index <= data->remain_leafs) {
return min_leaf_index;
}
- else if (data->leafs_per_child[depth]) {
+ if (data->leafs_per_child[depth]) {
return data->totleafs -
(data->branches_on_level[depth - 1] - child_index) * data->leafs_per_child[depth];
}
- else {
- return data->remain_leafs;
- }
+ return data->remain_leafs;
}
/**
@@ -1393,6 +1382,71 @@ BVHTreeOverlap *BLI_bvhtree_overlap(
/** \} */
/* -------------------------------------------------------------------- */
+/** \name BLI_bvhtree_intersect_plane
+ * \{ */
+
+static bool tree_intersect_plane_test(const float *bv, const float plane[4])
+{
+ /* TODO(germano): Support other kdop geometries. */
+ const float bb_min[3] = {bv[0], bv[2], bv[4]};
+ const float bb_max[3] = {bv[1], bv[3], bv[5]};
+ float bb_near[3], bb_far[3];
+ aabb_get_near_far_from_plane(plane, bb_min, bb_max, bb_near, bb_far);
+ if ((plane_point_side_v3(plane, bb_near) > 0.0f) !=
+ (plane_point_side_v3(plane, bb_far) > 0.0f)) {
+ return true;
+ }
+
+ return false;
+}
+
+static void bvhtree_intersect_plane_dfs_recursive(BVHIntersectPlaneData *__restrict data,
+ const BVHNode *node)
+{
+ if (tree_intersect_plane_test(node->bv, data->plane)) {
+ /* check if node is a leaf */
+ if (!node->totnode) {
+ int *intersect = BLI_stack_push_r(data->intersect);
+ *intersect = node->index;
+ }
+ else {
+ for (int j = 0; j < data->tree->tree_type; j++) {
+ if (node->children[j]) {
+ bvhtree_intersect_plane_dfs_recursive(data, node->children[j]);
+ }
+ }
+ }
+ }
+}
+
+int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_tot)
+{
+ int *intersect = NULL;
+ size_t total = 0;
+
+ if (tree->totleaf) {
+ BVHIntersectPlaneData data;
+ data.tree = tree;
+ copy_v4_v4(data.plane, plane);
+ data.intersect = BLI_stack_new(sizeof(int), __func__);
+
+ BVHNode *root = tree->nodes[tree->totleaf];
+ bvhtree_intersect_plane_dfs_recursive(&data, root);
+
+ total = BLI_stack_count(data.intersect);
+ if (total) {
+ intersect = MEM_mallocN(sizeof(int) * total, __func__);
+ BLI_stack_pop_n(data.intersect, intersect, (uint)total);
+ }
+ BLI_stack_free(data.intersect);
+ }
+ *r_intersect_tot = (uint)total;
+ return intersect;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name BLI_bvhtree_find_nearest
* \{ */
@@ -1597,10 +1651,8 @@ static bool dfs_find_duplicate_fast_dfs(BVHNearestData *data, BVHNode *node)
data->callback(data->userdata, node->index, data->co, &data->nearest);
return (data->nearest.dist_sq < dist_sq);
}
- else {
- data->nearest.index = node->index;
- return true;
- }
+ data->nearest.index = node->index;
+ return true;
}
}
else {
@@ -1734,9 +1786,7 @@ static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *nod
(t1x > data->hit.dist || t1y > data->hit.dist || t1z > data->hit.dist)) {
return FLT_MAX;
}
- else {
- return max_fff(t1x, t1y, t1z);
- }
+ return max_fff(t1x, t1y, t1z);
}
static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
@@ -2283,26 +2333,25 @@ static bool bvhtree_walk_dfs_recursive(BVHTree_WalkData *walk_data, const BVHNod
return walk_data->walk_leaf_cb(
(const BVHTreeAxisRange *)node->bv, node->index, walk_data->userdata);
}
- else {
- /* First pick the closest node to recurse into */
- if (walk_data->walk_order_cb(
- (const BVHTreeAxisRange *)node->bv, node->main_axis, walk_data->userdata)) {
- for (int i = 0; i != node->totnode; i++) {
- if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
- walk_data->userdata)) {
- if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
- return false;
- }
+
+ /* First pick the closest node to recurse into */
+ if (walk_data->walk_order_cb(
+ (const BVHTreeAxisRange *)node->bv, node->main_axis, walk_data->userdata)) {
+ for (int i = 0; i != node->totnode; i++) {
+ if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
+ walk_data->userdata)) {
+ if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
+ return false;
}
}
}
- else {
- for (int i = node->totnode - 1; i >= 0; i--) {
- if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
- walk_data->userdata)) {
- if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
- return false;
- }
+ }
+ else {
+ for (int i = node->totnode - 1; i >= 0; i--) {
+ if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
+ walk_data->userdata)) {
+ if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
+ return false;
}
}
}
diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c
index 5020e06d0b3..4cac526088b 100644
--- a/source/blender/blenlib/intern/BLI_linklist.c
+++ b/source/blender/blenlib/intern/BLI_linklist.c
@@ -74,6 +74,16 @@ LinkNode *BLI_linklist_find(LinkNode *list, int index)
return NULL;
}
+LinkNode *BLI_linklist_find_last(LinkNode *list)
+{
+ if (list) {
+ while (list->next) {
+ list = list->next;
+ }
+ }
+ return list;
+}
+
void BLI_linklist_reverse(LinkNode **listp)
{
LinkNode *rhead = NULL, *cur = *listp;
@@ -137,7 +147,7 @@ void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index)
lnk_pdst = lnk;
break;
}
- else if (i == curr_index - 1) {
+ if (i == curr_index - 1) {
lnk_psrc = lnk;
}
}
diff --git a/source/blender/blenlib/intern/BLI_memiter.c b/source/blender/blenlib/intern/BLI_memiter.c
index 1b9509e36d8..428dd1e2ad8 100644
--- a/source/blender/blenlib/intern/BLI_memiter.c
+++ b/source/blender/blenlib/intern/BLI_memiter.c
@@ -269,9 +269,7 @@ void *BLI_memiter_elem_first(BLI_memiter *mi)
BLI_memiter_elem *elem = (BLI_memiter_elem *)chunk->data;
return elem->data;
}
- else {
- return NULL;
- }
+ return NULL;
}
void *BLI_memiter_elem_first_size(BLI_memiter *mi, uint *r_size)
@@ -282,9 +280,7 @@ void *BLI_memiter_elem_first_size(BLI_memiter *mi, uint *r_size)
*r_size = (uint)elem->size;
return elem->data;
}
- else {
- return NULL;
- }
+ return NULL;
}
/** \} */
@@ -334,9 +330,7 @@ void *BLI_memiter_iter_step_size(BLI_memiter_handle *iter, uint *r_size)
iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)];
return (void *)data;
}
- else {
- return NULL;
- }
+ return NULL;
}
void *BLI_memiter_iter_step(BLI_memiter_handle *iter)
@@ -352,9 +346,7 @@ void *BLI_memiter_iter_step(BLI_memiter_handle *iter)
iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)];
return (void *)data;
}
- else {
- return NULL;
- }
+ return NULL;
}
/** \} */
diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c
index 6810601d527..b0c3379ac97 100644
--- a/source/blender/blenlib/intern/DLRB_tree.c
+++ b/source/blender/blenlib/intern/DLRB_tree.c
@@ -299,9 +299,7 @@ static DLRBT_Node *get_grandparent(DLRBT_Node *node)
if (node && node->parent) {
return node->parent->parent;
}
- else {
- return NULL;
- }
+ return NULL;
}
/* get the sibling node (e.g. if node is left child of parent, return right child of parent) */
@@ -311,9 +309,7 @@ static DLRBT_Node *get_sibling(DLRBT_Node *node)
if (node == node->parent->left) {
return node->parent->right;
}
- else {
- return node->parent->left;
- }
+ return node->parent->left;
}
/* sibling not found */
diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c
index 85fbe7ece0f..387f9837159 100644
--- a/source/blender/blenlib/intern/array_store.c
+++ b/source/blender/blenlib/intern/array_store.c
@@ -355,9 +355,7 @@ static bool bchunk_data_compare(const BChunk *chunk,
if (offset + (size_t)chunk->data_len <= data_base_len) {
return (memcmp(&data_base[offset], chunk->data, chunk->data_len) == 0);
}
- else {
- return false;
- }
+ return false;
}
/** \} */
@@ -893,20 +891,18 @@ static hash_key key_from_chunk_ref(const BArrayInfo *info,
# endif
return key;
}
- else {
- /* corner case - we're too small, calculate the key each time. */
+ /* corner case - we're too small, calculate the key each time. */
- hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
- hash_accum_single(hash_store, hash_store_len, info->accum_steps);
- hash_key key = hash_store[0];
+ hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
+ hash_accum_single(hash_store, hash_store_len, info->accum_steps);
+ hash_key key = hash_store[0];
# ifdef USE_HASH_TABLE_KEY_CACHE
- if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) {
- key = HASH_TABLE_KEY_FALLBACK;
- }
-# endif
- return key;
+ if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) {
+ key = HASH_TABLE_KEY_FALLBACK;
}
+# endif
+ return key;
}
static const BChunkRef *table_lookup(const BArrayInfo *info,
@@ -1083,9 +1079,7 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info,
if (cref == cref_match_first) {
break;
}
- else {
- cref = cref->next;
- }
+ cref = cref->next;
}
/* happens when bytes are removed from the end of the array */
if (chunk_size_step == data_len_original) {
diff --git a/source/blender/blenlib/intern/array_utils.c b/source/blender/blenlib/intern/array_utils.c
index 5dec10a5756..e9ef5e2a927 100644
--- a/source/blender/blenlib/intern/array_utils.c
+++ b/source/blender/blenlib/intern/array_utils.c
@@ -208,7 +208,7 @@ bool _bli_array_iter_span(const void *arr,
if (arr_len == 0) {
return false;
}
- else if (use_wrap && (span_step[0] != arr_len) && (span_step[0] > span_step[1])) {
+ if (use_wrap && (span_step[0] != arr_len) && (span_step[0] > span_step[1])) {
return false;
}
diff --git a/source/blender/blenlib/intern/bitmap_draw_2d.c b/source/blender/blenlib/intern/bitmap_draw_2d.c
index 17debb38326..33250105c79 100644
--- a/source/blender/blenlib/intern/bitmap_draw_2d.c
+++ b/source/blender/blenlib/intern/bitmap_draw_2d.c
@@ -316,27 +316,25 @@ static int draw_poly_v2i_n__span_y_sort(const void *a_p, const void *b_p, void *
if (co_a[1] < co_b[1]) {
return -1;
}
- else if (co_a[1] > co_b[1]) {
+ if (co_a[1] > co_b[1]) {
return 1;
}
- else if (co_a[0] < co_b[0]) {
+ if (co_a[0] < co_b[0]) {
return -1;
}
- else if (co_a[0] > co_b[0]) {
+ if (co_a[0] > co_b[0]) {
return 1;
}
- else {
- /* co_a & co_b are identical, use the line closest to the x-min */
- const int *co = co_a;
- co_a = verts[a[1]];
- co_b = verts[b[1]];
- int ord = (((co_b[0] - co[0]) * (co_a[1] - co[1])) - ((co_a[0] - co[0]) * (co_b[1] - co[1])));
- if (ord > 0) {
- return -1;
- }
- if (ord < 0) {
- return 1;
- }
+ /* co_a & co_b are identical, use the line closest to the x-min */
+ const int *co = co_a;
+ co_a = verts[a[1]];
+ co_b = verts[b[1]];
+ int ord = (((co_b[0] - co[0]) * (co_a[1] - co[1])) - ((co_a[0] - co[0]) * (co_b[1] - co[1])));
+ if (ord > 0) {
+ return -1;
+ }
+ if (ord < 0) {
+ return 1;
}
return 0;
}
diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index 83866f766df..5bcb0c0322a 100644
--- a/source/blender/blenlib/intern/boxpack_2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -216,7 +216,7 @@ static int box_areasort(const void *p1, const void *p2)
if (a1 < a2) {
return 1;
}
- else if (a1 > a2) {
+ if (a1 > a2) {
return -1;
}
return 0;
@@ -246,10 +246,10 @@ static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p)
if (UNLIKELY(v1->free == 0 && v2->free == 0)) {
return 0;
}
- else if (UNLIKELY(v1->free == 0)) {
+ if (UNLIKELY(v1->free == 0)) {
return 1;
}
- else if (UNLIKELY(v2->free == 0)) {
+ if (UNLIKELY(v2->free == 0)) {
return -1;
}
#endif
@@ -266,7 +266,7 @@ static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p)
if (a1 > a2) {
return 1;
}
- else if (a1 < a2) {
+ if (a1 < a2) {
return -1;
}
return 0;
diff --git a/source/blender/blenlib/intern/convexhull_2d.c b/source/blender/blenlib/intern/convexhull_2d.c
index b37dc73db29..6e4a8623077 100644
--- a/source/blender/blenlib/intern/convexhull_2d.c
+++ b/source/blender/blenlib/intern/convexhull_2d.c
@@ -115,9 +115,7 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points
if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
break; /* points[i] is a new hull vertex */
}
- else {
- top--; /* pop top point off stack */
- }
+ top--; /* pop top point off stack */
}
r_points[++top] = i; /* push points[i] onto stack */
@@ -141,9 +139,7 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points
if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
break; /* points[i] is a new hull vertex */
}
- else {
- top--; /* pop top point off stack */
- }
+ top--; /* pop top point off stack */
}
if (points[i][0] == points[r_points[0]][0] && points[i][1] == points[r_points[0]][1]) {
@@ -172,20 +168,17 @@ static int pointref_cmp_yx(const void *a_, const void *b_)
if (a->pt[1] > b->pt[1]) {
return 1;
}
- else if (a->pt[1] < b->pt[1]) {
+ if (a->pt[1] < b->pt[1]) {
return -1;
}
if (a->pt[0] > b->pt[0]) {
return 1;
}
- else if (a->pt[0] < b->pt[0]) {
+ if (a->pt[0] < b->pt[0]) {
return -1;
}
-
- else {
- return 0;
- }
+ return 0;
}
/**
diff --git a/source/blender/blenlib/intern/delaunay_2d.c b/source/blender/blenlib/intern/delaunay_2d.c
index 08ccff695c1..7199e461c6c 100644
--- a/source/blender/blenlib/intern/delaunay_2d.c
+++ b/source/blender/blenlib/intern/delaunay_2d.c
@@ -600,19 +600,19 @@ static int site_lexicographic_cmp(const void *a, const void *b)
if (co1[0] < co2[0]) {
return -1;
}
- else if (co1[0] > co2[0]) {
+ if (co1[0] > co2[0]) {
return 1;
}
- else if (co1[1] < co2[1]) {
+ if (co1[1] < co2[1]) {
return -1;
}
- else if (co1[1] > co2[1]) {
+ if (co1[1] > co2[1]) {
return 1;
}
- else if (s1->orig_index < s2->orig_index) {
+ if (s1->orig_index < s2->orig_index) {
return -1;
}
- else if (s1->orig_index > s2->orig_index) {
+ if (s1->orig_index > s2->orig_index) {
return 1;
}
return 0;
@@ -952,7 +952,7 @@ static void initial_triangulation(CDT_state *cdt)
}
#endif
- /* Now dedup according to user-defined epsilon.
+ /* Now de-duplicate according to user-defined epsilon.
* We will merge a vertex into an earlier-indexed vertex
* that is within epsilon (Euclidean distance).
* Merges may cascade. So we may end up merging two things
@@ -974,7 +974,7 @@ static void initial_triangulation(CDT_state *cdt)
if (jco[0] > xend) {
break; /* No more j's to process. */
}
- else if (jco[1] > yend) {
+ if (jco[1] > yend) {
/* Get past any string of v's with the same x and too-big y. */
xcur = jco[0];
while (++j < n) {
@@ -1414,7 +1414,7 @@ static bool get_next_crossing_from_vert(CDT_state *cdt,
ok = true;
break;
}
- else if (t->face != cdt->outer_face) {
+ if (t->face != cdt->outer_face) {
orient2 = orient2d(vcur->co, vb->co, v2->co);
#ifdef DEBUG_CDT
if (dbg_level > 1) {
@@ -1683,14 +1683,12 @@ static void add_edge_constraint(
(cd_prev->lambda != 0.0 && cd_prev->in->vert != v && cd_prev->in->next->vert != v)) {
break;
}
- else {
- cd_prev->lambda = -1.0; /* Mark cd_prev as 'deleted'. */
+ cd_prev->lambda = -1.0; /* Mark cd_prev as 'deleted'. */
#ifdef DEBUG_CDT
- if (dbg_level > 0) {
- fprintf(stderr, "deleted crossing %d\n", j);
- }
-#endif
+ if (dbg_level > 0) {
+ fprintf(stderr, "deleted crossing %d\n", j);
}
+#endif
}
if (j < i - 1) {
/* Some crossings were deleted. Fix the in and out edges across gap. */
@@ -2002,19 +2000,19 @@ static int evl_cmp(const void *a, const void *b)
if (area->e_id < sb->e_id) {
return -1;
}
- else if (area->e_id > sb->e_id) {
+ if (area->e_id > sb->e_id) {
return 1;
}
- else if (area->lambda < sb->lambda) {
+ if (area->lambda < sb->lambda) {
return -1;
}
- else if (area->lambda > sb->lambda) {
+ if (area->lambda > sb->lambda) {
return 1;
}
- else if (area->v_id < sb->v_id) {
+ if (area->v_id < sb->v_id) {
return -1;
}
- else if (area->v_id > sb->v_id) {
+ if (area->v_id > sb->v_id) {
return 1;
}
return 0;
@@ -2386,9 +2384,7 @@ static const CDT_input *modify_input_for_near_edge_ends(const CDT_input *input,
if (new_input != NULL) {
return (const CDT_input *)new_input;
}
- else {
- return input;
- }
+ return input;
}
static void free_modified_input(CDT_input *input)
@@ -2745,7 +2741,7 @@ static int edge_to_sort_cmp(const void *a, const void *b)
if (e1->len_squared > e2->len_squared) {
return -1;
}
- else if (e1->len_squared < e2->len_squared) {
+ if (e1->len_squared < e2->len_squared) {
return 1;
}
return 0;
@@ -4320,7 +4316,7 @@ static void exactinit(void)
*/
static int fast_expansion_sum_zeroelim(
- int elen, double *e, int flen, double *f, double *h) /* h cannot be e or f. */
+ int elen, const double *e, int flen, const double *f, double *h) /* h cannot be e or f. */
{
double Q;
INEXACT double Qnew;
@@ -4405,7 +4401,7 @@ static int fast_expansion_sum_zeroelim(
*/
static int scale_expansion_zeroelim(int elen,
- double *e,
+ const double *e,
double b,
double *h) /* e and h cannot be the same. */
{
@@ -4451,7 +4447,7 @@ static int scale_expansion_zeroelim(int elen,
* See either version of my paper for details.
*/
-static double estimate(int elen, double *e)
+static double estimate(int elen, const double *e)
{
double Q;
int eindex;
@@ -4570,17 +4566,13 @@ static double orient2d(const double *pa, const double *pb, const double *pc)
if (detright <= 0.0) {
return det;
}
- else {
- detsum = detleft + detright;
- }
+ detsum = detleft + detright;
}
else if (detleft < 0.0) {
if (detright >= 0.0) {
return det;
}
- else {
- detsum = -detleft - detright;
- }
+ detsum = -detleft - detright;
}
else {
return det;
diff --git a/source/blender/blenlib/intern/dot_export.cc b/source/blender/blenlib/intern/dot_export.cc
index 0f60ea6fd1b..9ffb1895d04 100644
--- a/source/blender/blenlib/intern/dot_export.cc
+++ b/source/blender/blenlib/intern/dot_export.cc
@@ -28,7 +28,7 @@ Node &Graph::new_node(StringRef label)
Node *node = new Node(*this);
nodes_.append(std::unique_ptr<Node>(node));
top_level_nodes_.add_new(node);
- node->set_attribute("label", label);
+ node->attributes.set("label", label);
return *node;
}
@@ -37,7 +37,7 @@ Cluster &Graph::new_cluster(StringRef label)
Cluster *cluster = new Cluster(*this);
clusters_.append(std::unique_ptr<Cluster>(cluster));
top_level_clusters_.add_new(cluster);
- cluster->set_attribute("label", label);
+ cluster->attributes.set("label", label);
return *cluster;
}
@@ -60,7 +60,7 @@ void Cluster::set_parent_cluster(Cluster *new_parent)
if (parent_ == new_parent) {
return;
}
- else if (parent_ == nullptr) {
+ if (parent_ == nullptr) {
graph_.top_level_clusters_.remove(this);
new_parent->children_.add_new(this);
}
@@ -80,7 +80,7 @@ void Node::set_parent_cluster(Cluster *cluster)
if (cluster_ == cluster) {
return;
}
- else if (cluster_ == nullptr) {
+ if (cluster_ == nullptr) {
graph_.top_level_nodes_.remove(this);
cluster->nodes_.add_new(this);
}
@@ -110,13 +110,25 @@ void Cluster::set_random_cluster_bgcolors()
float hue = rand() / (float)RAND_MAX;
float staturation = 0.3f;
float value = 0.8f;
- this->set_attribute("bgcolor", color_attr_from_hsv(hue, staturation, value));
+ this->attributes.set("bgcolor", color_attr_from_hsv(hue, staturation, value));
for (Cluster *cluster : children_) {
cluster->set_random_cluster_bgcolors();
}
}
+bool Cluster::contains(Node &node) const
+{
+ Cluster *current = node.parent_cluster();
+ while (current != nullptr) {
+ if (current == this) {
+ return true;
+ }
+ current = current->parent_;
+ }
+ return false;
+}
+
/* Dot Generation
**********************************************/
@@ -155,7 +167,7 @@ std::string UndirectedGraph::to_dot_string() const
void Graph::export__declare_nodes_and_clusters(std::stringstream &ss) const
{
ss << "graph ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
ss << "\n\n";
for (Node *node : top_level_nodes_) {
@@ -169,10 +181,10 @@ void Graph::export__declare_nodes_and_clusters(std::stringstream &ss) const
void Cluster::export__declare_nodes_and_clusters(std::stringstream &ss) const
{
- ss << "subgraph cluster_" << (uintptr_t)this << " {\n";
+ ss << "subgraph " << this->name() << " {\n";
ss << "graph ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
ss << "\n\n";
for (Node *node : nodes_) {
@@ -192,7 +204,7 @@ void DirectedEdge::export__as_edge_statement(std::stringstream &ss) const
ss << " -> ";
b_.to_dot_string(ss);
ss << " ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
}
void UndirectedEdge::export__as_edge_statement(std::stringstream &ss) const
@@ -201,10 +213,10 @@ void UndirectedEdge::export__as_edge_statement(std::stringstream &ss) const
ss << " -- ";
b_.to_dot_string(ss);
ss << " ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
}
-void AttributeList::export__as_bracket_list(std::stringstream &ss) const
+void Attributes::export__as_bracket_list(std::stringstream &ss) const
{
ss << "[";
attributes_.foreach_item([&](StringRef key, StringRef value) {
@@ -228,7 +240,7 @@ void Node::export__as_declaration(std::stringstream &ss) const
{
this->export__as_id(ss);
ss << " ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
ss << "\n";
}
@@ -263,8 +275,8 @@ NodeWithSocketsRef::NodeWithSocketsRef(Node &node,
ss << "</b></td></tr>";
/* Sockets */
- uint socket_max_amount = std::max(input_names.size(), output_names.size());
- for (uint i = 0; i < socket_max_amount; i++) {
+ int socket_max_amount = std::max(input_names.size(), output_names.size());
+ for (int i = 0; i < socket_max_amount; i++) {
ss << "<tr>";
if (i < input_names.size()) {
StringRef name = input_names[i];
@@ -296,7 +308,7 @@ NodeWithSocketsRef::NodeWithSocketsRef(Node &node,
ss << "</table>>";
- node_->set_attribute("label", ss.str());
+ node_->attributes.set("label", ss.str());
node_->set_shape(Attr_shape::Rectangle);
}
diff --git a/source/blender/blenlib/intern/easing.c b/source/blender/blenlib/intern/easing.c
index 9532f78bd44..07aafc1b57b 100644
--- a/source/blender/blenlib/intern/easing.c
+++ b/source/blender/blenlib/intern/easing.c
@@ -72,18 +72,16 @@ float BLI_easing_bounce_ease_out(float time, float begin, float change, float du
if (time < (1 / 2.75f)) {
return change * (7.5625f * time * time) + begin;
}
- else if (time < (2 / 2.75f)) {
+ if (time < (2 / 2.75f)) {
time -= (1.5f / 2.75f);
return change * ((7.5625f * time) * time + 0.75f) + begin;
}
- else if (time < (2.5f / 2.75f)) {
+ if (time < (2.5f / 2.75f)) {
time -= (2.25f / 2.75f);
return change * ((7.5625f * time) * time + 0.9375f) + begin;
}
- else {
- time -= (2.625f / 2.75f);
- return change * ((7.5625f * time) * time + 0.984375f) + begin;
- }
+ time -= (2.625f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.984375f) + begin;
}
float BLI_easing_bounce_ease_in(float time, float begin, float change, float duration)
@@ -96,10 +94,8 @@ float BLI_easing_bounce_ease_in_out(float time, float begin, float change, float
if (time < duration / 2) {
return BLI_easing_bounce_ease_in(time * 2, 0, change, duration) * 0.5f + begin;
}
- else {
- return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f +
- change * 0.5f + begin;
- }
+ return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f +
+ change * 0.5f + begin;
}
float BLI_easing_circ_ease_in(float time, float begin, float change, float duration)
@@ -271,13 +267,12 @@ float BLI_easing_elastic_ease_in_out(
sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
begin;
}
- else {
- time = -time;
- f *= 0.5f;
- return (f * (amplitude * powf(2, 10 * time) *
- sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
- change + begin;
- }
+
+ time = -time;
+ f *= 0.5f;
+ return (f * (amplitude * powf(2, 10 * time) *
+ sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
+ change + begin;
}
static const float pow_min = 0.0009765625f; /* = 2^(-10) */
@@ -306,10 +301,8 @@ float BLI_easing_expo_ease_in_out(float time, float begin, float change, float d
if (time <= duration_half) {
return BLI_easing_expo_ease_in(time, begin, change_half, duration_half);
}
- else {
- return BLI_easing_expo_ease_out(
- time - duration_half, begin + change_half, change_half, duration_half);
- }
+ return BLI_easing_expo_ease_out(
+ time - duration_half, begin + change_half, change_half, duration_half);
}
float BLI_easing_linear_ease(float time, float begin, float change, float duration)
diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c
index 56529581dd3..05ee02ad869 100644
--- a/source/blender/blenlib/intern/edgehash.c
+++ b/source/blender/blenlib/intern/edgehash.c
@@ -185,7 +185,7 @@ BLI_INLINE EdgeHashEntry *edgehash_insert(EdgeHash *eh, Edge edge, void *value)
if (index == SLOT_EMPTY) {
return edgehash_insert_at_slot(eh, slot, edge, value);
}
- else if (index == SLOT_DUMMY) {
+ if (index == SLOT_DUMMY) {
eh->dummy_count--;
return edgehash_insert_at_slot(eh, slot, edge, value);
}
@@ -200,7 +200,7 @@ BLI_INLINE EdgeHashEntry *edgehash_lookup_entry(EdgeHash *eh, uint v0, uint v1)
if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
return &eh->entries[index];
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
return NULL;
}
}
@@ -294,7 +294,7 @@ bool BLI_edgehash_reinsert(EdgeHash *eh, uint v0, uint v1, void *value)
eh->entries[index].value = value;
return false;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
if (edgehash_ensure_can_insert(eh)) {
edgehash_insert(eh, edge, value);
}
@@ -360,7 +360,7 @@ bool BLI_edgehash_ensure_p(EdgeHash *eh, uint v0, uint v1, void ***r_value)
*r_value = &eh->entries[index].value;
return true;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
if (edgehash_ensure_can_insert(eh)) {
*r_value = &edgehash_insert(eh, edge, NULL)->value;
}
@@ -413,7 +413,7 @@ void *BLI_edgehash_popkey(EdgeHash *eh, uint v0, uint v1)
}
return value;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
return NULL;
}
}
@@ -583,7 +583,7 @@ bool BLI_edgeset_add(EdgeSet *es, uint v0, uint v1)
if (ES_INDEX_HAS_EDGE(es, index, edge)) {
return false;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
edgeset_insert_at_slot(es, slot, edge);
return true;
}
@@ -615,7 +615,7 @@ bool BLI_edgeset_haskey(EdgeSet *es, uint v0, uint v1)
if (ES_INDEX_HAS_EDGE(es, index, edge)) {
return true;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
return false;
}
}
diff --git a/source/blender/blenlib/intern/expr_pylike_eval.c b/source/blender/blenlib/intern/expr_pylike_eval.c
index d1d84dab3f7..f8618c54ea4 100644
--- a/source/blender/blenlib/intern/expr_pylike_eval.c
+++ b/source/blender/blenlib/intern/expr_pylike_eval.c
@@ -72,6 +72,8 @@ typedef enum eOpCode {
OPCODE_FUNC1,
/* 2 argument function call: (a b -> func2(a,b)) */
OPCODE_FUNC2,
+ /* 3 argument function call: (a b c -> func3(a,b,c)) */
+ OPCODE_FUNC3,
/* Parameter access: (-> params[ival]) */
OPCODE_PARAMETER,
/* Minimum of multiple inputs: (a b c... -> min); ival = arg count */
@@ -92,6 +94,7 @@ typedef enum eOpCode {
typedef double (*UnaryOpFunc)(double);
typedef double (*BinaryOpFunc)(double, double);
+typedef double (*TernaryOpFunc)(double, double, double);
typedef struct ExprOp {
eOpCode opcode;
@@ -104,6 +107,7 @@ typedef struct ExprOp {
void *ptr;
UnaryOpFunc func1;
BinaryOpFunc func2;
+ TernaryOpFunc func3;
} arg;
} ExprOp;
@@ -216,6 +220,11 @@ eExprPyLike_EvalStatus BLI_expr_pylike_eval(ExprPyLike_Parsed *expr,
stack[sp - 2] = ops[pc].arg.func2(stack[sp - 2], stack[sp - 1]);
sp--;
break;
+ case OPCODE_FUNC3:
+ FAIL_IF(sp < 3);
+ stack[sp - 3] = ops[pc].arg.func3(stack[sp - 3], stack[sp - 2], stack[sp - 1]);
+ sp -= 2;
+ break;
case OPCODE_MIN:
FAIL_IF(sp < ops[pc].arg.ival);
for (int j = 1; j < ops[pc].arg.ival; j++, sp--) {
@@ -326,6 +335,35 @@ static double op_degrees(double arg)
return arg * 180.0 / M_PI;
}
+static double op_log2(double a, double b)
+{
+ return log(a) / log(b);
+}
+
+static double op_lerp(double a, double b, double x)
+{
+ return a * (1.0 - x) + b * x;
+}
+
+static double op_clamp(double arg)
+{
+ CLAMP(arg, 0.0, 1.0);
+ return arg;
+}
+
+static double op_clamp3(double arg, double minv, double maxv)
+{
+ CLAMP(arg, minv, maxv);
+ return arg;
+}
+
+static double op_smoothstep(double a, double b, double x)
+{
+ double t = (x - a) / (b - a);
+ CLAMP(t, 0.0, 1.0);
+ return t * t * (3.0 - 2.0 * t);
+}
+
static double op_not(double a)
{
return a ? 0.0 : 1.0;
@@ -390,6 +428,7 @@ static BuiltinOpDef builtin_ops[] = {
{"floor", OPCODE_FUNC1, floor},
{"ceil", OPCODE_FUNC1, ceil},
{"trunc", OPCODE_FUNC1, trunc},
+ {"round", OPCODE_FUNC1, round},
{"int", OPCODE_FUNC1, trunc},
{"sin", OPCODE_FUNC1, sin},
{"cos", OPCODE_FUNC1, cos},
@@ -400,9 +439,14 @@ static BuiltinOpDef builtin_ops[] = {
{"atan2", OPCODE_FUNC2, atan2},
{"exp", OPCODE_FUNC1, exp},
{"log", OPCODE_FUNC1, log},
+ {"log", OPCODE_FUNC2, op_log2},
{"sqrt", OPCODE_FUNC1, sqrt},
{"pow", OPCODE_FUNC2, pow},
{"fmod", OPCODE_FUNC2, fmod},
+ {"lerp", OPCODE_FUNC3, op_lerp},
+ {"clamp", OPCODE_FUNC1, op_clamp},
+ {"clamp", OPCODE_FUNC3, op_clamp3},
+ {"smoothstep", OPCODE_FUNC3, op_smoothstep},
{NULL, OPCODE_CONST, NULL},
};
@@ -514,6 +558,22 @@ static void parse_set_jump(ExprParseState *state, int jump)
state->ops[jump - 1].jmp_offset = state->ops_count - jump;
}
+/* Returns the required argument count of the given function call code. */
+static int opcode_arg_count(eOpCode code)
+{
+ switch (code) {
+ case OPCODE_FUNC1:
+ return 1;
+ case OPCODE_FUNC2:
+ return 2;
+ case OPCODE_FUNC3:
+ return 3;
+ default:
+ BLI_assert(!"unexpected opcode");
+ return -1;
+ }
+}
+
/* Add a function call operation, applying constant folding when possible. */
static bool parse_add_func(ExprParseState *state, eOpCode code, int args, void *funcptr)
{
@@ -560,6 +620,27 @@ static bool parse_add_func(ExprParseState *state, eOpCode code, int args, void *
}
break;
+ case OPCODE_FUNC3:
+ CHECK_ERROR(args == 3);
+
+ if (jmp_gap >= 3 && prev_ops[-3].opcode == OPCODE_CONST &&
+ prev_ops[-2].opcode == OPCODE_CONST && prev_ops[-1].opcode == OPCODE_CONST) {
+ TernaryOpFunc func = funcptr;
+
+ /* volatile because some compilers overly aggressive optimize this call out.
+ * see D6012 for details. */
+ volatile double result = func(
+ prev_ops[-3].arg.dval, prev_ops[-2].arg.dval, prev_ops[-1].arg.dval);
+
+ if (fetestexcept(FE_DIVBYZERO | FE_INVALID) == 0) {
+ prev_ops[-3].arg.dval = result;
+ state->ops_count -= 2;
+ state->stack_ptr -= 2;
+ return true;
+ }
+ }
+ break;
+
default:
BLI_assert(false);
return false;
@@ -755,6 +836,17 @@ static bool parse_unary(ExprParseState *state)
if (STREQ(state->tokenbuf, builtin_ops[i].name)) {
int args = parse_function_args(state);
+ /* Search for other arg count versions if necessary. */
+ if (args != opcode_arg_count(builtin_ops[i].op)) {
+ for (int j = i + 1; builtin_ops[j].name; j++) {
+ if (opcode_arg_count(builtin_ops[j].op) == args &&
+ STREQ(builtin_ops[j].name, builtin_ops[i].name)) {
+ i = j;
+ break;
+ }
+ }
+ }
+
return parse_add_func(state, builtin_ops[i].op, args, builtin_ops[i].funcptr);
}
}
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index b9133edcae3..6c7383bc297 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -177,8 +177,9 @@ size_t BLI_gzip_mem_to_file_at_pos(
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, compression_level);
- if (ret != Z_OK)
+ if (ret != Z_OK) {
return 0;
+ }
strm.avail_in = len;
strm.next_in = (Bytef *)buf;
@@ -224,8 +225,9 @@ size_t BLI_ungzip_file_to_mem_at_pos(void *buf, size_t len, FILE *file, size_t g
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
- if (ret != Z_OK)
+ if (ret != Z_OK) {
return 0;
+ }
do {
strm.avail_in = fread(in, 1, chunk, file);
@@ -558,7 +560,7 @@ int BLI_move(const char *file, const char *to)
/* windows doesn't support moving to a directory
* it has to be 'mv filename filename' and not
- * 'mv filename destdir' */
+ * 'mv filename destination_directory' */
BLI_strncpy(str, to, sizeof(str));
/* points 'to' to a directory ? */
@@ -978,7 +980,7 @@ static int delete_soft(const char *file, const char **error_message)
"Blender may not support moving files or directories to trash on your system.";
return -1;
}
- else if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus)) {
+ if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus)) {
*error_message = process_failed;
return -1;
}
@@ -1034,12 +1036,10 @@ int BLI_delete(const char *file, bool dir, bool recursive)
if (recursive) {
return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post);
}
- else if (dir) {
+ if (dir) {
return rmdir(file);
}
- else {
- return remove(file);
- }
+ return remove(file);
}
/**
@@ -1182,8 +1182,7 @@ static int copy_single_file(const char *from, const char *to)
return RecursiveOp_Callback_OK;
}
- else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode) ||
- S_ISSOCK(st.st_mode)) {
+ if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
/* copy special type of file */
if (mknod(to, st.st_mode, st.st_rdev)) {
perror("mknod");
@@ -1196,7 +1195,7 @@ static int copy_single_file(const char *from, const char *to)
return RecursiveOp_Callback_OK;
}
- else if (!S_ISREG(st.st_mode)) {
+ if (!S_ISREG(st.st_mode)) {
fprintf(stderr, "Copying of this kind of files isn't supported yet\n");
return RecursiveOp_Callback_Error;
}
@@ -1335,7 +1334,7 @@ bool BLI_dir_create_recursive(const char *dirname)
if (BLI_is_dir(dirname)) {
return true;
}
- else if (BLI_exists(dirname)) {
+ if (BLI_exists(dirname)) {
return false;
}
diff --git a/source/blender/blenlib/intern/lasso_2d.c b/source/blender/blenlib/intern/lasso_2d.c
index a01adf4fa6a..f2cc8d42de7 100644
--- a/source/blender/blenlib/intern/lasso_2d.c
+++ b/source/blender/blenlib/intern/lasso_2d.c
@@ -60,10 +60,9 @@ bool BLI_lasso_is_point_inside(const int mcoords[][2],
if (sx == error_value || mcoords_len == 0) {
return false;
}
- else {
- int pt[2] = {sx, sy};
- return isect_point_poly_v2_int(pt, mcoords, mcoords_len, true);
- }
+
+ int pt[2] = {sx, sy};
+ return isect_point_poly_v2_int(pt, mcoords, mcoords_len, true);
}
/* edge version for lasso select. we assume boundbox check was done */
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 892eca768b3..5e88f8f3e44 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -162,9 +162,8 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink)
BLI_remlink(listbase, vlink);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
diff --git a/source/blender/blenlib/intern/math_base_safe_inline.c b/source/blender/blenlib/intern/math_base_safe_inline.c
new file mode 100644
index 00000000000..5600382e395
--- /dev/null
+++ b/source/blender/blenlib/intern/math_base_safe_inline.c
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#ifndef __MATH_BASE_SAFE_INLINE_C__
+#define __MATH_BASE_SAFE_INLINE_C__
+
+#include "BLI_math_base_safe.h"
+#include "BLI_utildefines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+MINLINE float safe_divide(float a, float b)
+{
+ return (b != 0.0f) ? a / b : 0.0f;
+}
+
+MINLINE float safe_modf(float a, float b)
+{
+ return (b != 0.0f) ? fmodf(a, b) : 0.0f;
+}
+
+MINLINE float safe_logf(float a, float base)
+{
+ if (UNLIKELY(a <= 0.0f || base <= 0.0f)) {
+ return 0.0f;
+ }
+ return safe_divide(logf(a), logf(base));
+}
+
+MINLINE float safe_sqrtf(float a)
+{
+ return sqrtf(MAX2(a, 0.0f));
+}
+
+MINLINE float safe_inverse_sqrtf(float a)
+{
+ return (a > 0.0f) ? 1.0f / sqrtf(a) : 0.0f;
+}
+
+MINLINE float safe_asinf(float a)
+{
+ CLAMP(a, -1.0f, 1.0f);
+ return asinf(a);
+}
+
+MINLINE float safe_acosf(float a)
+{
+ CLAMP(a, -1.0f, 1.0f);
+ return acosf(a);
+}
+
+MINLINE float safe_powf(float base, float exponent)
+{
+ if (UNLIKELY(base < 0.0f && exponent != (int)exponent)) {
+ return 0.0f;
+ }
+ return powf(base, exponent);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MATH_BASE_SAFE_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 625849c01df..09bb7ea5711 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -439,9 +439,8 @@ float srgb_to_linearrgb(float c)
if (c < 0.04045f) {
return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
}
- else {
- return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
- }
+
+ return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
}
float linearrgb_to_srgb(float c)
@@ -449,9 +448,8 @@ float linearrgb_to_srgb(float c)
if (c < 0.0031308f) {
return (c < 0.0f) ? 0.0f : c * 12.92f;
}
- else {
- return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
- }
+
+ return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
}
void minmax_rgb(short c[3])
@@ -503,8 +501,12 @@ int constrain_rgb(float *r, float *g, float *b)
/* ********************** lift/gamma/gain / ASC-CDL conversion ********************************* */
-void lift_gamma_gain_to_asc_cdl(
- float *lift, float *gamma, float *gain, float *offset, float *slope, float *power)
+void lift_gamma_gain_to_asc_cdl(const float *lift,
+ const float *gamma,
+ const float *gain,
+ float *offset,
+ float *slope,
+ float *power)
{
int c;
for (c = 0; c < 3; c++) {
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index d3dc4729617..ce83b522178 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -231,9 +231,8 @@ float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float
if (c_len > FLT_EPSILON) {
return dot_v3v3(a, b) / c_len;
}
- else {
- return 0.0f;
- }
+
+ return 0.0f;
}
/********************************* Planes **********************************/
@@ -589,9 +588,8 @@ float dist_signed_squared_to_corner_v3v3v3(const float p[3],
if (flip) {
return min_ff(dist_a, dist_b);
}
- else {
- return max_ff(dist_a, dist_b);
- }
+
+ return max_ff(dist_a, dist_b);
}
/**
@@ -630,7 +628,7 @@ float dist_squared_ray_to_seg_v3(const float ray_origin[3],
float *r_depth)
{
float lambda, depth;
- if (isect_ray_seg_v3(ray_origin, ray_direction, v0, v1, &lambda)) {
+ if (isect_ray_line_v3(ray_origin, ray_direction, v0, v1, &lambda)) {
if (lambda <= 0.0f) {
copy_v3_v3(r_point, v0);
}
@@ -1146,9 +1144,8 @@ int isect_line_line_v2_point(
return ISECT_LINE_LINE_CROSS;
}
- else {
- return ISECT_LINE_LINE_COLINEAR;
- }
+
+ return ISECT_LINE_LINE_COLINEAR;
}
/* intersect Line-Line, floats */
@@ -1304,55 +1301,54 @@ int isect_seg_seg_v2_point_ex(const float v0[2],
/* out of segment intersection */
return -1;
}
- else {
- if ((cross_v2v2(s10, s30) == 0.0f) && (cross_v2v2(s32, s30) == 0.0f)) {
- /* equal lines */
- float s20[2];
- float u_a, u_b;
-
- if (equals_v2v2(v0, v1)) {
- if (len_squared_v2v2(v2, v3) > square_f(eps)) {
- /* use non-point segment as basis */
- SWAP(const float *, v0, v2);
- SWAP(const float *, v1, v3);
-
- sub_v2_v2v2(s10, v1, v0);
- sub_v2_v2v2(s30, v3, v0);
- }
- else { /* both of segments are points */
- if (equals_v2v2(v0, v2)) { /* points are equal */
- copy_v2_v2(r_vi, v0);
- return 1;
- }
-
- /* two different points */
- return -1;
- }
- }
- sub_v2_v2v2(s20, v2, v0);
+ if ((cross_v2v2(s10, s30) == 0.0f) && (cross_v2v2(s32, s30) == 0.0f)) {
+ /* equal lines */
+ float s20[2];
+ float u_a, u_b;
- u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10);
- u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10);
+ if (equals_v2v2(v0, v1)) {
+ if (len_squared_v2v2(v2, v3) > square_f(eps)) {
+ /* use non-point segment as basis */
+ SWAP(const float *, v0, v2);
+ SWAP(const float *, v1, v3);
- if (u_a > u_b) {
- SWAP(float, u_a, u_b);
+ sub_v2_v2v2(s10, v1, v0);
+ sub_v2_v2v2(s30, v3, v0);
}
+ else { /* both of segments are points */
+ if (equals_v2v2(v0, v2)) { /* points are equal */
+ copy_v2_v2(r_vi, v0);
+ return 1;
+ }
- if (u_a > endpoint_max || u_b < endpoint_min) {
- /* non-overlapping segments */
+ /* two different points */
return -1;
}
- else if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) {
- /* one common point: can return result */
- madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a));
- return 1;
- }
}
- /* lines are collinear */
- return -1;
+ sub_v2_v2v2(s20, v2, v0);
+
+ u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10);
+ u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10);
+
+ if (u_a > u_b) {
+ SWAP(float, u_a, u_b);
+ }
+
+ if (u_a > endpoint_max || u_b < endpoint_min) {
+ /* non-overlapping segments */
+ return -1;
+ }
+ if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) {
+ /* one common point: can return result */
+ madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a));
+ return 1;
+ }
}
+
+ /* lines are collinear */
+ return -1;
}
int isect_seg_seg_v2_point(
@@ -1472,13 +1468,13 @@ int isect_line_sphere_v3(const float l1[3],
/* no intersections */
return 0;
}
- else if (i == 0.0f) {
+ if (i == 0.0f) {
/* one intersection */
mu = -b / (2.0f * a);
madd_v3_v3v3fl(r_p1, l1, ldir, mu);
return 1;
}
- else if (i > 0.0f) {
+ if (i > 0.0f) {
const float i_sqrt = sqrtf(i); /* avoid calc twice */
/* first intersection */
@@ -1490,10 +1486,9 @@ int isect_line_sphere_v3(const float l1[3],
madd_v3_v3v3fl(r_p2, l1, ldir, mu);
return 2;
}
- else {
- /* math domain error - nan */
- return -1;
- }
+
+ /* math domain error - nan */
+ return -1;
}
/* keep in sync with isect_line_sphere_v3 */
@@ -1520,13 +1515,13 @@ int isect_line_sphere_v2(const float l1[2],
/* no intersections */
return 0;
}
- else if (i == 0.0f) {
+ if (i == 0.0f) {
/* one intersection */
mu = -b / (2.0f * a);
madd_v2_v2v2fl(r_p1, l1, ldir, mu);
return 1;
}
- else if (i > 0.0f) {
+ if (i > 0.0f) {
const float i_sqrt = sqrtf(i); /* avoid calc twice */
/* first intersection */
@@ -1538,10 +1533,9 @@ int isect_line_sphere_v2(const float l1[2],
madd_v2_v2v2fl(r_p2, l1, ldir, mu);
return 2;
}
- else {
- /* math domain error - nan */
- return -1;
- }
+
+ /* math domain error - nan */
+ return -1;
}
/* point in polygon (keep float and int versions in sync) */
@@ -1957,34 +1951,32 @@ bool isect_ray_tri_watertight_v3(const float ray_origin[3],
if (UNLIKELY(det == 0.0f || !isfinite(det))) {
return false;
}
- else {
- /* Calculate scaled z-coordinates of vertices and use them to calculate
- * the hit distance.
- */
- const int sign_det = (float_as_int(det) & (int)0x80000000);
- const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
- const float sign_t = xor_fl(t, sign_det);
- if ((sign_t < 0.0f)
- /* Differ from Cycles, don't read r_lambda's original value
- * otherwise we won't match any of the other intersect functions here...
- * which would be confusing. */
+
+ /* Calculate scaled z-coordinates of vertices and use them to calculate
+ * the hit distance.
+ */
+ const int sign_det = (float_as_int(det) & (int)0x80000000);
+ const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
+ const float sign_t = xor_fl(t, sign_det);
+ if ((sign_t < 0.0f)
+ /* Differ from Cycles, don't read r_lambda's original value
+ * otherwise we won't match any of the other intersect functions here...
+ * which would be confusing. */
#if 0
|| (sign_T > *r_lambda * xor_signmask(det, sign_mask))
#endif
- ) {
- return false;
- }
- else {
- /* 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;
- }
+ ) {
+ return false;
}
+
+ /* 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;
}
bool isect_ray_tri_watertight_v3_simple(const float ray_origin[3],
@@ -2129,11 +2121,11 @@ bool isect_ray_seg_v2(const float ray_origin[2],
return false;
}
-bool isect_ray_seg_v3(const float ray_origin[3],
- const float ray_direction[3],
- const float v0[3],
- const float v1[3],
- float *r_lambda)
+bool isect_ray_line_v3(const float ray_origin[3],
+ const float ray_direction[3],
+ const float v0[3],
+ const float v1[3],
+ float *r_lambda)
{
float a[3], t[3], n[3];
sub_v3_v3v3(a, v1, v0);
@@ -2215,10 +2207,9 @@ bool isect_line_plane_v3(float r_isect_co[3],
madd_v3_v3v3fl(r_isect_co, l1, u, lambda);
return true;
}
- else {
- /* The segment is parallel to plane */
- return false;
- }
+
+ /* The segment is parallel to plane */
+ return false;
}
/**
@@ -2257,9 +2248,8 @@ bool isect_plane_plane_plane_v3(const float plane_a[4],
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -2303,9 +2293,8 @@ bool isect_plane_plane_v3(const float plane_a[4],
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -2436,65 +2425,54 @@ static bool isect_tri_tri_v2_impl_vert(const float t_a0[2],
if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else {
- if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
- if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
- return 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
+
+ if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
+ return 1;
}
+
+ return 0;
}
+
+ return 0;
}
- else if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) {
+ if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) {
if (line_point_side_v2(t_b2, t_b1, t_a2) <= 0.0f) {
if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
- }
- else {
+
return 0;
}
- }
- else {
+
return 0;
}
+
+ return 0;
}
- else if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) {
if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) {
+ if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) {
if (line_point_side_v2(t_b2, t_a2, t_b1) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
- }
- else {
+
return 0;
}
- }
- else {
+
return 0;
}
+
+ return 0;
}
static bool isect_tri_tri_v2_impl_edge(const float t_a0[2],
@@ -2511,47 +2489,38 @@ static bool isect_tri_tri_v2_impl_edge(const float t_a0[2],
if (line_point_side_v2(t_a0, t_a1, t_b2) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else {
- if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
- if (line_point_side_v2(t_a2, t_a0, t_b0) >= 0.0f) {
- return 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
+
+ if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
+ if (line_point_side_v2(t_a2, t_a0, t_b0) >= 0.0f) {
+ return 1;
}
+
+ return 0;
}
+
+ return 0;
}
- else {
- if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
- if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
- if (line_point_side_v2(t_a0, t_a2, t_b2) >= 0.0f) {
- return 1;
- }
- else {
- if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) {
- return 1;
- }
- else {
- return 0;
- }
- }
+
+ if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_a0, t_a2, t_b2) >= 0.0f) {
+ return 1;
}
- else {
- return 0;
+
+ if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) {
+ return 1;
}
- }
- else {
+
return 0;
}
+
+ return 0;
}
+
+ return 0;
}
static int isect_tri_tri_impl_ccw_v2(const float t_a0[2],
@@ -2566,32 +2535,26 @@ static int isect_tri_tri_impl_ccw_v2(const float t_a0[2],
if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
return 1;
}
- else {
- return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
- }
+
+ return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
}
- else {
- if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
- return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
- }
- else {
- return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
- }
+
+ if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
+ return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
}
+
+ return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
}
- else {
- if (line_point_side_v2(t_b1, t_b2, t_a0) >= 0.0f) {
- if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
- return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
- }
- else {
- return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
- }
- }
- else {
- return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
+
+ if (line_point_side_v2(t_b1, t_b2, t_a0) >= 0.0f) {
+ if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
+ return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
}
+
+ return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
}
+
+ return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
}
bool isect_tri_tri_v2(const float t_a0[2],
@@ -2605,18 +2568,15 @@ bool isect_tri_tri_v2(const float t_a0[2],
if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) {
return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b2, t_b1);
}
- else {
- return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b1, t_b2);
- }
+
+ return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b1, t_b2);
}
- else {
- if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) {
- return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b2, t_b1);
- }
- else {
- return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
- }
+
+ if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) {
+ return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b2, t_b1);
}
+
+ return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
}
/** \} */
@@ -2682,8 +2642,7 @@ int isect_aabb_planes_v3(const float (*planes)[4],
if (plane_point_side_v3(planes[i], bb_far) < 0.0f) {
return ISECT_AABB_PLANE_BEHIND_ANY;
}
- else if ((ret != ISECT_AABB_PLANE_CROSS_ANY) &&
- (plane_point_side_v3(planes[i], bb_near) < 0.0f)) {
+ if ((ret != ISECT_AABB_PLANE_CROSS_ANY) && (plane_point_side_v3(planes[i], bb_near) < 0.0f)) {
ret = ISECT_AABB_PLANE_CROSS_ANY;
}
}
@@ -2967,7 +2926,7 @@ int isect_line_line_epsilon_v3(const float v1[3],
return 0;
}
/* test if the two lines are coplanar */
- else if (UNLIKELY(fabsf(d) <= epsilon)) {
+ if (UNLIKELY(fabsf(d) <= epsilon)) {
cross_v3_v3v3(cb, c, b);
mul_v3_fl(a, dot_v3v3(cb, ab) / div);
@@ -2977,34 +2936,33 @@ int isect_line_line_epsilon_v3(const float v1[3],
return 1; /* one intersection only */
}
/* if not */
- else {
- float n[3], t[3];
- float v3t[3], v4t[3];
- sub_v3_v3v3(t, v1, v3);
- /* offset between both plane where the lines lies */
- cross_v3_v3v3(n, a, b);
- project_v3_v3v3(t, t, n);
+ float n[3], t[3];
+ float v3t[3], v4t[3];
+ sub_v3_v3v3(t, v1, v3);
- /* for the first line, offset the second line until it is coplanar */
- add_v3_v3v3(v3t, v3, t);
- add_v3_v3v3(v4t, v4, t);
+ /* offset between both plane where the lines lies */
+ cross_v3_v3v3(n, a, b);
+ project_v3_v3v3(t, t, n);
- sub_v3_v3v3(c, v3t, v1);
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v4t, v3t);
+ /* for the first line, offset the second line until it is coplanar */
+ add_v3_v3v3(v3t, v3, t);
+ add_v3_v3v3(v4t, v4, t);
- cross_v3_v3v3(ab, a, b);
- cross_v3_v3v3(cb, c, b);
+ sub_v3_v3v3(c, v3t, v1);
+ sub_v3_v3v3(a, v2, v1);
+ sub_v3_v3v3(b, v4t, v3t);
- mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
- add_v3_v3v3(r_i1, v1, a);
+ cross_v3_v3v3(ab, a, b);
+ cross_v3_v3v3(cb, c, b);
- /* for the second line, just substract the offset from the first intersection point */
- sub_v3_v3v3(r_i2, r_i1, t);
+ mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
+ add_v3_v3v3(r_i1, v1, a);
- return 2; /* two nearest points */
- }
+ /* for the second line, just subtract the offset from the first intersection point */
+ sub_v3_v3v3(r_i2, r_i1, t);
+
+ return 2; /* two nearest points */
}
int isect_line_line_v3(const float v1[3],
@@ -3047,31 +3005,29 @@ bool isect_line_line_strict_v3(const float v1[3],
return false;
}
/* test if the two lines are coplanar */
- else if (UNLIKELY(fabsf(d) < epsilon)) {
+ if (UNLIKELY(fabsf(d) < epsilon)) {
return false;
}
- else {
- float f1, f2;
- cross_v3_v3v3(cb, c, b);
- cross_v3_v3v3(ca, c, a);
- f1 = dot_v3v3(cb, ab) / div;
- f2 = dot_v3v3(ca, ab) / div;
+ float f1, f2;
+ cross_v3_v3v3(cb, c, b);
+ cross_v3_v3v3(ca, c, a);
- if (f1 >= 0 && f1 <= 1 && f2 >= 0 && f2 <= 1) {
- mul_v3_fl(a, f1);
- add_v3_v3v3(vi, v1, a);
+ f1 = dot_v3v3(cb, ab) / div;
+ f2 = dot_v3v3(ca, ab) / div;
- if (r_lambda) {
- *r_lambda = f1;
- }
+ if (f1 >= 0 && f1 <= 1 && f2 >= 0 && f2 <= 1) {
+ mul_v3_fl(a, f1);
+ add_v3_v3v3(vi, v1, a);
- return true; /* intersection found */
- }
- else {
- return false;
+ if (r_lambda) {
+ *r_lambda = f1;
}
+
+ return true; /* intersection found */
}
+
+ return false;
}
/**
@@ -3237,15 +3193,14 @@ bool isect_ray_aabb_v3_simple(const float orig[3],
if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) {
return false;
}
- else {
- if (tmin) {
- *tmin = hit_dist[0];
- }
- if (tmax) {
- *tmax = hit_dist[1];
- }
- return true;
+
+ if (tmin) {
+ *tmin = hit_dist[0];
+ }
+ if (tmax) {
+ *tmax = hit_dist[1];
}
+ return true;
}
float closest_to_ray_v3(float r_close[3],
@@ -3522,9 +3477,8 @@ bool isect_point_tri_v3(
return true;
}
- else {
- return false;
- }
+
+ return false;
}
bool clip_segment_v3_plane(
@@ -3547,7 +3501,7 @@ bool clip_segment_v3_plane(
if (t >= div) {
return false;
}
- else if (t > 0.0f) {
+ if (t > 0.0f) {
const float p1_copy[3] = {UNPACK3(p1)};
copy_v3_v3(r_p2, p2);
madd_v3_v3v3fl(r_p1, p1_copy, dp, t / div);
@@ -3559,7 +3513,7 @@ bool clip_segment_v3_plane(
if (t >= 0.0f) {
return false;
}
- else if (t > div) {
+ if (t > div) {
const float p1_copy[3] = {UNPACK3(p1)};
copy_v3_v3(r_p1, p1);
madd_v3_v3v3fl(r_p2, p1_copy, dp, t / div);
@@ -3598,7 +3552,7 @@ bool clip_segment_v3_plane_n(const float p1[3],
if (t >= div) {
return false;
}
- else if (t > 0.0f) {
+ if (t > 0.0f) {
t /= div;
if (t > p1_fac) {
p1_fac = t;
@@ -3613,7 +3567,7 @@ bool clip_segment_v3_plane_n(const float p1[3],
if (t >= 0.0f) {
return false;
}
- else if (t > div) {
+ if (t > div) {
t /= div;
if (t < p2_fac) {
p2_fac = t;
@@ -3797,8 +3751,8 @@ int barycentric_inside_triangle_v2(const float w[3])
if (IN_RANGE(w[0], 0.0f, 1.0f) && IN_RANGE(w[1], 0.0f, 1.0f) && IN_RANGE(w[2], 0.0f, 1.0f)) {
return 1;
}
- else if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && IN_RANGE_INCL(w[1], 0.0f, 1.0f) &&
- IN_RANGE_INCL(w[2], 0.0f, 1.0f)) {
+ if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && IN_RANGE_INCL(w[1], 0.0f, 1.0f) &&
+ IN_RANGE_INCL(w[2], 0.0f, 1.0f)) {
return 2;
}
@@ -4095,68 +4049,67 @@ int interp_sparse_array(float *array, const int list_size, const float skipval)
if (found_valid == 0) {
return -1;
}
- else if (found_invalid == 0) {
+ if (found_invalid == 0) {
return 0;
}
- else {
- /* found invalid depths, interpolate */
- float valid_last = skipval;
- int valid_ofs = 0;
- float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
- float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
+ /* found invalid depths, interpolate */
+ float valid_last = skipval;
+ int valid_ofs = 0;
- int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup");
- int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown");
+ float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
+ float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
- for (i = 0; i < list_size; i++) {
- if (array[i] == skipval) {
- array_up[i] = valid_last;
- ofs_tot_up[i] = ++valid_ofs;
- }
- else {
- valid_last = array[i];
- valid_ofs = 0;
- }
+ int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup");
+ int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown");
+
+ for (i = 0; i < list_size; i++) {
+ if (array[i] == skipval) {
+ array_up[i] = valid_last;
+ ofs_tot_up[i] = ++valid_ofs;
+ }
+ else {
+ valid_last = array[i];
+ valid_ofs = 0;
}
+ }
- valid_last = skipval;
- valid_ofs = 0;
+ valid_last = skipval;
+ valid_ofs = 0;
- for (i = list_size - 1; i >= 0; i--) {
- if (array[i] == skipval) {
- array_down[i] = valid_last;
- ofs_tot_down[i] = ++valid_ofs;
- }
- else {
- valid_last = array[i];
- valid_ofs = 0;
- }
+ for (i = list_size - 1; i >= 0; i--) {
+ if (array[i] == skipval) {
+ array_down[i] = valid_last;
+ ofs_tot_down[i] = ++valid_ofs;
+ }
+ else {
+ valid_last = array[i];
+ valid_ofs = 0;
}
+ }
- /* now blend */
- for (i = 0; i < list_size; i++) {
- if (array[i] == skipval) {
- if (array_up[i] != skipval && array_down[i] != skipval) {
- array[i] = ((array_up[i] * (float)ofs_tot_down[i]) +
- (array_down[i] * (float)ofs_tot_up[i])) /
- (float)(ofs_tot_down[i] + ofs_tot_up[i]);
- }
- else if (array_up[i] != skipval) {
- array[i] = array_up[i];
- }
- else if (array_down[i] != skipval) {
- array[i] = array_down[i];
- }
+ /* now blend */
+ for (i = 0; i < list_size; i++) {
+ if (array[i] == skipval) {
+ if (array_up[i] != skipval && array_down[i] != skipval) {
+ array[i] = ((array_up[i] * (float)ofs_tot_down[i]) +
+ (array_down[i] * (float)ofs_tot_up[i])) /
+ (float)(ofs_tot_down[i] + ofs_tot_up[i]);
+ }
+ else if (array_up[i] != skipval) {
+ array[i] = array_up[i];
+ }
+ else if (array_down[i] != skipval) {
+ array[i] = array_down[i];
}
}
+ }
- MEM_freeN(array_up);
- MEM_freeN(array_down);
+ MEM_freeN(array_up);
+ MEM_freeN(array_down);
- MEM_freeN(ofs_tot_up);
- MEM_freeN(ofs_tot_down);
- }
+ MEM_freeN(ofs_tot_up);
+ MEM_freeN(ofs_tot_down);
return 1;
}
@@ -4176,8 +4129,8 @@ int interp_sparse_array(float *array, const int list_size, const float skipval)
#define DIR_V2_SET(d_len, va, vb) \
{ \
- sub_v2_v2v2((d_len)->dir, va, vb); \
- (d_len)->len = len_v2((d_len)->dir); \
+ sub_v2db_v2fl_v2fl((d_len)->dir, va, vb); \
+ (d_len)->len = len_v2_db((d_len)->dir); \
} \
(void)0
@@ -4185,8 +4138,8 @@ struct Float3_Len {
float dir[3], len;
};
-struct Float2_Len {
- float dir[2], len;
+struct Double2_Len {
+ double dir[2], len;
};
/* Mean value weights - smooth interpolation weights for polygons with
@@ -4209,21 +4162,30 @@ static float mean_value_half_tan_v3(const struct Float3_Len *d_curr,
return 0.0f;
}
-static float mean_value_half_tan_v2(const struct Float2_Len *d_curr,
- const struct Float2_Len *d_next)
+/**
+ * Mean value weights - same as #mean_value_half_tan_v3 but for 2D vectors.
+ *
+ * \note When interpolating a 2D polygon, a point can be considered "outside"
+ * the polygon's bounds. Thus, when the point is very distant and the vectors
+ * have relatively close values, the precision problems are evident since they
+ * do not indicate a point "inside" the polygon.
+ * To resolve this, doubles are used.
+ */
+static double mean_value_half_tan_v2_db(const struct Double2_Len *d_curr,
+ const struct Double2_Len *d_next)
{
- /* different from the 3d version but still correct */
- const float area = cross_v2v2(d_curr->dir, d_next->dir);
+ /* Different from the 3d version but still correct. */
+ const double area = cross_v2v2_db(d_curr->dir, d_next->dir);
/* Compare against zero since 'FLT_EPSILON' can be too large, see: T73348. */
- if (LIKELY(area != 0.0f)) {
- const float dot = dot_v2v2(d_curr->dir, d_next->dir);
- const float len = d_curr->len * d_next->len;
- const float result = (len - dot) / area;
+ if (LIKELY(area != 0.0)) {
+ const double dot = dot_v2v2_db(d_curr->dir, d_next->dir);
+ const double len = d_curr->len * d_next->len;
+ const double result = (len - dot) / area;
if (isfinite(result)) {
return result;
}
}
- return 0.0f;
+ return 0.0;
}
void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3])
@@ -4265,12 +4227,12 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
* to borders of face.
* In that case, do simple linear interpolation between the two edge vertices */
- /* 'd_next.len' is infact 'd_curr.len', just avoid copy to begin with */
+ /* 'd_next.len' is in fact 'd_curr.len', just avoid copy to begin with */
if (UNLIKELY(d_next.len < eps)) {
ix_flag = IS_POINT_IX;
break;
}
- else if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) {
+ if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) {
ix_flag = IS_SEGMENT_IX;
break;
}
@@ -4328,11 +4290,11 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
const float eps_sq = eps * eps;
const float *v_curr, *v_next;
- float ht_prev, ht; /* half tangents */
+ double ht_prev, ht; /* half tangents */
float totweight = 0.0f;
int i_curr, i_next;
char ix_flag = 0;
- struct Float2_Len d_curr, d_next;
+ struct Double2_Len d_curr, d_next;
/* loop over 'i_next' */
i_curr = n - 1;
@@ -4343,27 +4305,27 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
DIR_V2_SET(&d_curr, v_curr - 2 /* v[n - 2] */, co);
DIR_V2_SET(&d_next, v_curr /* v[n - 1] */, co);
- ht_prev = mean_value_half_tan_v2(&d_curr, &d_next);
+ ht_prev = mean_value_half_tan_v2_db(&d_curr, &d_next);
while (i_next < n) {
/* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
* to borders of face. In that case,
* do simple linear interpolation between the two edge vertices */
- /* 'd_next.len' is infact 'd_curr.len', just avoid copy to begin with */
+ /* 'd_next.len' is in fact 'd_curr.len', just avoid copy to begin with */
if (UNLIKELY(d_next.len < eps)) {
ix_flag = IS_POINT_IX;
break;
}
- else if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) {
+ if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) {
ix_flag = IS_SEGMENT_IX;
break;
}
d_curr = d_next;
DIR_V2_SET(&d_next, v_next, co);
- ht = mean_value_half_tan_v2(&d_curr, &d_next);
- w[i_curr] = (ht_prev + ht) / d_curr.len;
+ ht = mean_value_half_tan_v2_db(&d_curr, &d_next);
+ w[i_curr] = (float)((ht_prev + ht) / d_curr.len);
totweight += w[i_curr];
/* step */
@@ -4638,17 +4600,15 @@ float resolve_quad_u_v2(const float st[2],
if (IS_ZERO(fDen) == 0) {
return (float)(a / fDen);
}
- else {
- return 0.0f;
- }
- }
- else {
- const double desc_sq = b * b - a * fC;
- const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
- const double s = signed_area > 0 ? (-1.0) : 1.0;
- return (float)(((a - b) + s * desc) / denom);
+ return 0.0f;
}
+
+ const double desc_sq = b * b - a * fC;
+ const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
+ const double s = signed_area > 0 ? (-1.0) : 1.0;
+
+ return (float)(((a - b) + s * desc) / denom);
}
#undef IS_ZERO
@@ -4880,6 +4840,37 @@ void projmat_dimensions(const float projmat[4][4],
}
}
+void projmat_dimensions_db(const float projmat_fl[4][4],
+ double *r_left,
+ double *r_right,
+ double *r_bottom,
+ double *r_top,
+ double *r_near,
+ double *r_far)
+{
+ double projmat[4][4];
+ copy_m4d_m4(projmat, projmat_fl);
+
+ bool is_persp = projmat[3][3] == 0.0f;
+
+ if (is_persp) {
+ *r_left = (projmat[2][0] - 1.0) / projmat[0][0];
+ *r_right = (projmat[2][0] + 1.0) / projmat[0][0];
+ *r_bottom = (projmat[2][1] - 1.0) / projmat[1][1];
+ *r_top = (projmat[2][1] + 1.0) / projmat[1][1];
+ *r_near = projmat[3][2] / (projmat[2][2] - 1.0);
+ *r_far = projmat[3][2] / (projmat[2][2] + 1.0);
+ }
+ else {
+ *r_left = (-projmat[3][0] - 1.0) / projmat[0][0];
+ *r_right = (-projmat[3][0] + 1.0) / projmat[0][0];
+ *r_bottom = (-projmat[3][1] - 1.0) / projmat[1][1];
+ *r_top = (-projmat[3][1] + 1.0) / projmat[1][1];
+ *r_near = (projmat[3][2] + 1.0) / projmat[2][2];
+ *r_far = (projmat[3][2] - 1.0) / projmat[2][2];
+ }
+}
+
/**
* Creates a projection matrix for a small region of the viewport.
*
@@ -6099,17 +6090,16 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
/* no angle difference (use fallback, length wont make any difference) */
return (1.0f / 3.0f) * 0.75f;
}
- else if (tan_dot < -1.0f + eps) {
+ if (tan_dot < -1.0f + eps) {
/* parallele tangents (half-circle) */
return (1.0f / 2.0f);
}
- else {
- /* non-aligned tangents, calculate handle length */
- const float angle = acosf(tan_dot) / 2.0f;
- /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */
- const float angle_sin = sinf(angle);
- const float angle_cos = cosf(angle);
- return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
- }
+ /* non-aligned tangents, calculate handle length */
+ const float angle = acosf(tan_dot) / 2.0f;
+
+ /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */
+ const float angle_sin = sinf(angle);
+ const float angle_cos = cosf(angle);
+ return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
}
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 92cfd09f191..fadd7d83444 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -248,7 +248,7 @@ void swap_m4m4(float m1[4][4], float m2[4][4])
}
}
-void shuffle_m4(float R[4][4], int index[4])
+void shuffle_m4(float R[4][4], const int index[4])
{
zero_m4(R);
for (int k = 0; k < 4; k++) {
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index a2f7cc24dd3..a6368981050 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -644,9 +644,8 @@ float angle_signed_normalized_qt(const float q[4])
if (q[0] >= 0.0f) {
return 2.0f * saacos(q[0]);
}
- else {
- return -2.0f * saacos(-q[0]);
- }
+
+ return -2.0f * saacos(-q[0]);
}
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
@@ -654,11 +653,10 @@ float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
if (dot_qtqt(q1, q2) >= 0.0f) {
return angle_normalized_qtqt(q1, q2);
}
- else {
- float q2_copy[4];
- negate_v4_v4(q2_copy, q2);
- return -angle_normalized_qtqt(q1, q2_copy);
- }
+
+ float q2_copy[4];
+ negate_v4_v4(q2_copy, q2);
+ return -angle_normalized_qtqt(q1, q2_copy);
}
float angle_signed_qt(const float q[4])
@@ -675,11 +673,10 @@ float angle_signed_qtqt(const float q1[4], const float q2[4])
if (dot_qtqt(q1, q2) >= 0.0f) {
return angle_qtqt(q1, q2);
}
- else {
- float q2_copy[4];
- negate_v4_v4(q2_copy, q2);
- return -angle_qtqt(q1, q2_copy);
- }
+
+ float q2_copy[4];
+ negate_v4_v4(q2_copy, q2);
+ return -angle_qtqt(q1, q2_copy);
}
/** \} */
@@ -1594,12 +1591,11 @@ static const RotOrderInfo *get_rotation_order_info(const short order)
if (order < 1) {
return &rotOrders[0];
}
- else if (order < 6) {
+ if (order < 6) {
return &rotOrders[order - 1];
}
- else {
- return &rotOrders[5];
- }
+
+ return &rotOrders[5];
}
/* Construct quaternion from Euler angles (in radians). */
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 6ec7c960d6b..909d508e262 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -307,7 +307,7 @@ void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint nbr)
/**
* Specialized function for calculating normals.
- * fastpath for:
+ * Fast-path for:
*
* \code{.c}
* add_v3_v3v3(r, a, b);
@@ -506,11 +506,10 @@ float angle_normalized_v3v3(const float v1[3], const float v2[3])
if (dot_v3v3(v1, v2) >= 0.0f) {
return 2.0f * saasin(len_v3v3(v1, v2) / 2.0f);
}
- else {
- float v2_n[3];
- negate_v3_v3(v2_n, v2);
- return (float)M_PI - 2.0f * saasin(len_v3v3(v1, v2_n) / 2.0f);
- }
+
+ float v2_n[3];
+ negate_v3_v3(v2_n, v2);
+ return (float)M_PI - 2.0f * saasin(len_v3v3(v1, v2_n) / 2.0f);
}
float angle_normalized_v2v2(const float v1[2], const float v2[2])
@@ -523,11 +522,10 @@ float angle_normalized_v2v2(const float v1[2], const float v2[2])
if (dot_v2v2(v1, v2) >= 0.0f) {
return 2.0f * saasin(len_v2v2(v1, v2) / 2.0f);
}
- else {
- float v2_n[2];
- negate_v2_v2(v2_n, v2);
- return (float)M_PI - 2.0f * saasin(len_v2v2(v1, v2_n) / 2.0f);
- }
+
+ float v2_n[2];
+ negate_v2_v2(v2_n, v2);
+ return (float)M_PI - 2.0f * saasin(len_v2v2(v1, v2_n) / 2.0f);
}
/**
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index ca405907bdd..1b47832589e 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -509,6 +509,12 @@ MINLINE void sub_v3_v3v3_db(double r[3], const double a[3], const double b[3])
r[2] = a[2] - b[2];
}
+MINLINE void sub_v2db_v2fl_v2fl(double r[2], const float a[2], const float b[2])
+{
+ r[0] = (double)a[0] - (double)b[0];
+ r[1] = (double)a[1] - (double)b[1];
+}
+
MINLINE void sub_v3db_v3fl_v3fl(double r[3], const float a[3], const float b[3])
{
r[0] = (double)a[0] - (double)b[0];
@@ -917,6 +923,11 @@ MINLINE float cross_v2v2(const float a[2], const float b[2])
return a[0] * b[1] - a[1] * b[0];
}
+MINLINE double cross_v2v2_db(const double a[2], const double b[2])
+{
+ return a[0] * b[1] - a[1] * b[0];
+}
+
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
{
BLI_assert(r != a && r != b);
@@ -997,6 +1008,11 @@ MINLINE float len_v2(const float v[2])
return sqrtf(v[0] * v[0] + v[1] * v[1]);
}
+MINLINE double len_v2_db(const double v[2])
+{
+ return sqrt(v[0] * v[0] + v[1] * v[1]);
+}
+
MINLINE float len_v2v2(const float v1[2], const float v2[2])
{
float x, y;
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index 42b5ba28f5a..1ae1c91a3bd 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -27,7 +27,7 @@
#include "BLI_noise.h"
/* local */
-static float noise3_perlin(float vec[3]);
+static float noise3_perlin(const float vec[3]);
// static float turbulence_perlin(const float point[3], float lofreq, float hifreq);
// static float turbulencep(float noisesize, float x, float y, float z, int nr);
@@ -779,7 +779,7 @@ static const float g_perlin_data_v3[512 + 2][3] = {
} \
(void)0
-static float noise3_perlin(float vec[3])
+static float noise3_perlin(const float vec[3])
{
const char *p = g_perlin_data_ub;
const float(*g)[3] = g_perlin_data_v3;
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 2f51b66725b..67d41ffb779 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -242,7 +242,7 @@ void BLI_path_normalize(const char *relabase, char *path)
/* Note: previous version of following call used an offset of 3 instead of 4,
* which meant that the "/../home/me" example actually became "home/me".
- * Using offset of 3 gives behavior consistent with the abovementioned
+ * Using offset of 3 gives behavior consistent with the aforementioned
* Python routine. */
memmove(path, path + 3, strlen(path + 3) + 1);
}
@@ -427,9 +427,8 @@ static int BLI_path_unc_prefix_len(const char *path)
/* we assume long UNC path like \\?\server\share\folder etc... */
return 4;
}
- else {
- return 2;
- }
+
+ return 2;
}
return 0;
@@ -683,7 +682,7 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char
has_extension = true;
break;
}
- else if (ELEM(string[a], '/', '\\')) {
+ if (ELEM(string[a], '/', '\\')) {
break;
}
}
@@ -713,9 +712,8 @@ bool BLI_path_parent_dir(char *path)
strcpy(path, tmp); /* We assume pardir is always shorter... */
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -764,11 +762,10 @@ static bool stringframe_chars(const char *path, int *char_start, int *char_end)
*char_end = ch_end;
return true;
}
- else {
- *char_start = -1;
- *char_end = -1;
- return false;
- }
+
+ *char_start = -1;
+ *char_end = -1;
+ return false;
}
/**
@@ -1731,9 +1728,8 @@ void BLI_join_dirfile(char *__restrict dst,
dst[dirlen - 1] = '\0';
return; /* dir fills the path */
}
- else {
- memcpy(dst, dir, dirlen + 1);
- }
+
+ memcpy(dst, dir, dirlen + 1);
if (dirlen + 1 >= maxlen) {
return; /* fills the path */
@@ -1891,32 +1887,31 @@ bool BLI_path_name_at_index(const char *__restrict path,
}
return false;
}
- else {
- /* negative number, reverse where -1 is the last element */
- int index_step = -1;
- int prev = strlen(path);
- int i = prev - 1;
- while (true) {
- const char c = i >= 0 ? path[i] : '\0';
- if (ELEM(c, SEP, ALTSEP, '\0')) {
- if (prev - 1 != i) {
- i += 1;
- if (index_step == index) {
- *r_offset = i;
- *r_len = prev - i;
- return true;
- }
- index_step -= 1;
- }
- if (c == '\0') {
- break;
+
+ /* negative number, reverse where -1 is the last element */
+ int index_step = -1;
+ int prev = strlen(path);
+ int i = prev - 1;
+ while (true) {
+ const char c = i >= 0 ? path[i] : '\0';
+ if (ELEM(c, SEP, ALTSEP, '\0')) {
+ if (prev - 1 != i) {
+ i += 1;
+ if (index_step == index) {
+ *r_offset = i;
+ *r_len = prev - i;
+ return true;
}
- prev = i;
+ index_step -= 1;
}
- i -= 1;
+ if (c == '\0') {
+ break;
+ }
+ prev = i;
}
- return false;
+ i -= 1;
}
+ return false;
}
/**
@@ -1930,7 +1925,7 @@ const char *BLI_path_slash_find(const char *string)
if (!ffslash) {
return fbslash;
}
- else if (!fbslash) {
+ if (!fbslash) {
return ffslash;
}
@@ -1948,7 +1943,7 @@ const char *BLI_path_slash_rfind(const char *string)
if (!lfslash) {
return lbslash;
}
- else if (!lbslash) {
+ if (!lbslash) {
return lfslash;
}
diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c
index 90a4a4f4c2d..d1e2bd58909 100644
--- a/source/blender/blenlib/intern/polyfill_2d.c
+++ b/source/blender/blenlib/intern/polyfill_2d.c
@@ -177,12 +177,11 @@ BLI_INLINE eSign signum_enum(float a)
if (UNLIKELY(a == 0.0f)) {
return 0;
}
- else if (a > 0.0f) {
+ if (a > 0.0f) {
return 1;
}
- else {
- return -1;
- }
+
+ return -1;
}
/**
@@ -250,7 +249,7 @@ static uint kdtree2d_balance_recursive(
if (totnode <= 0) {
return KDNODE_UNSET;
}
- else if (totnode == 1) {
+ if (totnode == 1) {
return 0 + ofs;
}
@@ -330,9 +329,8 @@ static void kdtree2d_node_remove(struct KDTree2D *tree, uint index)
if (node_index == KDNODE_UNSET) {
return;
}
- else {
- tree->nodes_map[index] = KDNODE_UNSET;
- }
+
+ tree->nodes_map[index] = KDNODE_UNSET;
node = &tree->nodes[node_index];
tree->totnode -= 1;
diff --git a/source/blender/blenlib/intern/polyfill_2d_beautify.c b/source/blender/blenlib/intern/polyfill_2d_beautify.c
index 41364c5a3a9..7bfca149ffb 100644
--- a/source/blender/blenlib/intern/polyfill_2d_beautify.c
+++ b/source/blender/blenlib/intern/polyfill_2d_beautify.c
@@ -64,14 +64,14 @@ static int oedge_cmp(const void *a1, const void *a2)
if (x1->verts[0] > x2->verts[0]) {
return 1;
}
- else if (x1->verts[0] < x2->verts[0]) {
+ if (x1->verts[0] < x2->verts[0]) {
return -1;
}
if (x1->verts[1] > x2->verts[1]) {
return 1;
}
- else if (x1->verts[1] < x2->verts[1]) {
+ if (x1->verts[1] < x2->verts[1]) {
return -1;
}
@@ -79,7 +79,7 @@ static int oedge_cmp(const void *a1, const void *a2)
if (x1->e_half > x2->e_half) {
return 1;
}
- else if (x1->e_half < x2->e_half) {
+ if (x1->e_half < x2->e_half) {
return -1;
}
/* Should never get here, no two edges should be the same. */
@@ -141,7 +141,7 @@ float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2],
if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) {
break;
}
- else if ((fabsf(area_2x_123) <= eps_zero_area) || (fabsf(area_2x_134) <= eps_zero_area)) {
+ if ((fabsf(area_2x_123) <= eps_zero_area) || (fabsf(area_2x_134) <= eps_zero_area)) {
break;
}
@@ -150,11 +150,10 @@ float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2],
if (lock_degenerate) {
break;
}
- else {
- return -FLT_MAX; /* always rotate */
- }
+
+ return -FLT_MAX; /* always rotate */
}
- else if ((fabsf(area_2x_234) <= eps_zero_area) || (fabsf(area_2x_241) <= eps_zero_area)) {
+ if ((fabsf(area_2x_234) <= eps_zero_area) || (fabsf(area_2x_241) <= eps_zero_area)) {
return -FLT_MAX; /* always rotate */
}
diff --git a/source/blender/blenlib/intern/quadric.c b/source/blender/blenlib/intern/quadric.c
index 3ad1844cfe1..ac522171951 100644
--- a/source/blender/blenlib/intern/quadric.c
+++ b/source/blender/blenlib/intern/quadric.c
@@ -107,9 +107,8 @@ static bool quadric_to_tensor_m3_inverse(const Quadric *q, double m[3][3], doubl
return true;
}
- else {
- return false;
- }
+
+ return false;
}
void BLI_quadric_to_vector_v3(const Quadric *q, double v[3])
@@ -161,7 +160,6 @@ bool BLI_quadric_optimize(const Quadric *q, double v[3], const double epsilon)
negate_v3_db(v);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.cc
index ab7a972e010..9bafc422db5 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.cc
@@ -30,6 +30,7 @@
#include "BLI_math.h"
#include "BLI_rand.h"
+#include "BLI_rand.hh"
#include "BLI_threads.h"
/* defines BLI_INLINE */
@@ -38,29 +39,22 @@
#include "BLI_strict_flags.h"
#include "BLI_sys_types.h"
-#define MULTIPLIER 0x5DEECE66Dll
-#define MASK 0x0000FFFFFFFFFFFFll
-#define MASK_BYTES 2
-
-#define ADDEND 0xB
-#define LOWSEED 0x330E
-
-extern unsigned char BLI_noise_hash_uchar_512[512]; /* noise.c */
+extern "C" unsigned char BLI_noise_hash_uchar_512[512]; /* noise.c */
#define hash BLI_noise_hash_uchar_512
/**
* Random Number Generator.
*/
struct RNG {
- uint64_t X;
+ blender::RandomNumberGenerator rng;
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("RNG")
};
RNG *BLI_rng_new(unsigned int seed)
{
- RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
-
- BLI_rng_seed(rng, seed);
-
+ RNG *rng = new RNG();
+ rng->rng.seed(seed);
return rng;
}
@@ -69,26 +63,24 @@ RNG *BLI_rng_new(unsigned int seed)
*/
RNG *BLI_rng_new_srandom(unsigned int seed)
{
- RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
-
- BLI_rng_srandom(rng, seed);
-
+ RNG *rng = new RNG();
+ rng->rng.seed_random(seed);
return rng;
}
RNG *BLI_rng_copy(RNG *rng)
{
- return MEM_dupallocN(rng);
+ return new RNG(*rng);
}
void BLI_rng_free(RNG *rng)
{
- MEM_freeN(rng);
+ delete rng;
}
void BLI_rng_seed(RNG *rng, unsigned int seed)
{
- rng->X = (((uint64_t)seed) << 16) | LOWSEED;
+ rng->rng.seed(seed);
}
/**
@@ -96,67 +88,22 @@ void BLI_rng_seed(RNG *rng, unsigned int seed)
*/
void BLI_rng_srandom(RNG *rng, unsigned int seed)
{
- BLI_rng_seed(rng, seed + hash[seed & 255]);
- seed = BLI_rng_get_uint(rng);
- BLI_rng_seed(rng, seed + hash[seed & 255]);
- seed = BLI_rng_get_uint(rng);
- BLI_rng_seed(rng, seed + hash[seed & 255]);
-}
-
-BLI_INLINE void rng_step(RNG *rng)
-{
- rng->X = (MULTIPLIER * rng->X + ADDEND) & MASK;
+ rng->rng.seed_random(seed);
}
void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len)
{
- size_t last_len = 0;
- size_t trim_len = bytes_len;
-
-#define RAND_STRIDE (sizeof(rng->X) - MASK_BYTES)
-
- if (trim_len > RAND_STRIDE) {
- last_len = trim_len % RAND_STRIDE;
- trim_len = trim_len - last_len;
- }
- else {
- trim_len = 0;
- last_len = bytes_len;
- }
-
- const char *data_src = (void *)&(rng->X);
- size_t i = 0;
- while (i != trim_len) {
- BLI_assert(i < trim_len);
-#ifdef __BIG_ENDIAN__
- for (size_t j = (RAND_STRIDE + MASK_BYTES) - 1; j != MASK_BYTES - 1; j--)
-#else
- for (size_t j = 0; j != RAND_STRIDE; j++)
-#endif
- {
- bytes[i++] = data_src[j];
- }
- rng_step(rng);
- }
- if (last_len) {
- for (size_t j = 0; j != last_len; j++) {
- bytes[i++] = data_src[j];
- }
- }
-
-#undef RAND_STRIDE
+ rng->rng.get_bytes(blender::MutableSpan(bytes, (int64_t)bytes_len));
}
int BLI_rng_get_int(RNG *rng)
{
- rng_step(rng);
- return (int)(rng->X >> 17);
+ return rng->rng.get_int32();
}
unsigned int BLI_rng_get_uint(RNG *rng)
{
- rng_step(rng);
- return (unsigned int)(rng->X >> 17);
+ return rng->rng.get_uint32();
}
/**
@@ -164,7 +111,7 @@ unsigned int BLI_rng_get_uint(RNG *rng)
*/
double BLI_rng_get_double(RNG *rng)
{
- return (double)BLI_rng_get_int(rng) / 0x80000000;
+ return rng->rng.get_double();
}
/**
@@ -172,29 +119,17 @@ double BLI_rng_get_double(RNG *rng)
*/
float BLI_rng_get_float(RNG *rng)
{
- return (float)BLI_rng_get_int(rng) / 0x80000000;
+ return rng->rng.get_float();
}
void BLI_rng_get_float_unit_v2(RNG *rng, float v[2])
{
- float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
- v[0] = cosf(a);
- v[1] = sinf(a);
+ copy_v2_v2(v, rng->rng.get_unit_float2());
}
void BLI_rng_get_float_unit_v3(RNG *rng, float v[3])
{
- float r;
- v[2] = (2.0f * BLI_rng_get_float(rng)) - 1.0f;
- if ((r = 1.0f - (v[2] * v[2])) > 0.0f) {
- float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
- r = sqrtf(r);
- v[0] = r * cosf(a);
- v[1] = r * sinf(a);
- }
- else {
- v[2] = 1.0f;
- }
+ copy_v3_v3(v, rng->rng.get_unit_float3());
}
/**
@@ -203,27 +138,12 @@ void BLI_rng_get_float_unit_v3(RNG *rng, float v[3])
void BLI_rng_get_tri_sample_float_v2(
RNG *rng, const float v1[2], const float v2[2], const float v3[2], float r_pt[2])
{
- float u = BLI_rng_get_float(rng);
- float v = BLI_rng_get_float(rng);
-
- float side_u[2], side_v[2];
-
- if ((u + v) > 1.0f) {
- u = 1.0f - u;
- v = 1.0f - v;
- }
-
- sub_v2_v2v2(side_u, v2, v1);
- sub_v2_v2v2(side_v, v3, v1);
-
- copy_v2_v2(r_pt, v1);
- madd_v2_v2fl(r_pt, side_u, u);
- madd_v2_v2fl(r_pt, side_v, v);
+ copy_v2_v2(r_pt, rng->rng.get_triangle_sample(v1, v2, v3));
}
void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_tot)
{
- const size_t elem_size = (size_t)elem_size_i;
+ const uint elem_size = elem_size_i;
unsigned int i = elem_tot;
void *temp;
@@ -254,9 +174,7 @@ void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsig
*/
void BLI_rng_skip(RNG *rng, int n)
{
- while (n--) {
- rng_step(rng);
- }
+ rng->rng.skip((uint)n);
}
/***/
@@ -326,7 +244,8 @@ struct RNG_THREAD_ARRAY {
RNG_THREAD_ARRAY *BLI_rng_threaded_new(void)
{
unsigned int i;
- RNG_THREAD_ARRAY *rngarr = MEM_mallocN(sizeof(RNG_THREAD_ARRAY), "random_array");
+ RNG_THREAD_ARRAY *rngarr = (RNG_THREAD_ARRAY *)MEM_mallocN(sizeof(RNG_THREAD_ARRAY),
+ "random_array");
for (i = 0; i < BLENDER_MAX_THREADS; i++) {
BLI_rng_srandom(&rngarr->rng_tab[i], (unsigned int)clock());
@@ -382,7 +301,7 @@ void BLI_halton_1d(unsigned int prime, double offset, int n, double *r)
}
}
-void BLI_halton_2d(unsigned int prime[2], double offset[2], int n, double *r)
+void BLI_halton_2d(const unsigned int prime[2], double offset[2], int n, double *r)
{
const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
@@ -395,7 +314,7 @@ void BLI_halton_2d(unsigned int prime[2], double offset[2], int n, double *r)
}
}
-void BLI_halton_3d(unsigned int prime[3], double offset[3], int n, double *r)
+void BLI_halton_3d(const unsigned int prime[3], double offset[3], int n, double *r)
{
const double invprimes[3] = {
1.0 / (double)prime[0], 1.0 / (double)prime[1], 1.0 / (double)prime[2]};
@@ -409,7 +328,7 @@ void BLI_halton_3d(unsigned int prime[3], double offset[3], int n, double *r)
}
}
-void BLI_halton_2d_sequence(unsigned int prime[2], double offset[2], int n, double *r)
+void BLI_halton_2d_sequence(const unsigned int prime[2], double offset[2], int n, double *r)
{
const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
@@ -426,7 +345,7 @@ BLI_INLINE double radical_inverse(unsigned int n)
{
double u = 0;
- /* This reverse the bitwise representation
+ /* This reverse the bit-wise representation
* around the decimal point. */
for (double p = 0.5; n; p *= 0.5, n >>= 1) {
if (n & 1) {
@@ -449,3 +368,99 @@ void BLI_hammersley_2d_sequence(unsigned int n, double *r)
r[s * 2 + 1] = radical_inverse(s);
}
}
+
+namespace blender {
+
+/**
+ * Set a randomized hash of the value as seed.
+ */
+void RandomNumberGenerator::seed_random(uint32_t seed)
+{
+ this->seed(seed + hash[seed & 255]);
+ seed = this->get_uint32();
+ this->seed(seed + hash[seed & 255]);
+ seed = this->get_uint32();
+ this->seed(seed + hash[seed & 255]);
+}
+
+float2 RandomNumberGenerator::get_unit_float2()
+{
+ float a = (float)(M_PI * 2.0) * this->get_float();
+ return {cosf(a), sinf(a)};
+}
+
+float3 RandomNumberGenerator::get_unit_float3()
+{
+ float z = (2.0f * this->get_float()) - 1.0f;
+ float r = 1.0f - z * z;
+ if (r > 0.0f) {
+ float a = (float)(M_PI * 2.0) * this->get_float();
+ r = sqrtf(r);
+ float x = r * cosf(a);
+ float y = r * sinf(a);
+ return {x, y, z};
+ }
+ return {0.0f, 0.0f, 1.0f};
+}
+
+/**
+ * Generate a random point inside the given triangle.
+ */
+float2 RandomNumberGenerator::get_triangle_sample(float2 v1, float2 v2, float2 v3)
+{
+ float u = this->get_float();
+ float v = this->get_float();
+
+ if (u + v > 1.0f) {
+ u = 1.0f - u;
+ v = 1.0f - v;
+ }
+
+ float2 side_u = v2 - v1;
+ float2 side_v = v3 - v1;
+
+ float2 sample = v1;
+ sample += side_u * u;
+ sample += side_v * v;
+ return sample;
+}
+
+void RandomNumberGenerator::get_bytes(MutableSpan<char> r_bytes)
+{
+ constexpr int64_t mask_bytes = 2;
+ constexpr int64_t rand_stride = (int64_t)sizeof(x_) - mask_bytes;
+
+ int64_t last_len = 0;
+ int64_t trim_len = r_bytes.size();
+
+ if (trim_len > rand_stride) {
+ last_len = trim_len % rand_stride;
+ trim_len = trim_len - last_len;
+ }
+ else {
+ trim_len = 0;
+ last_len = r_bytes.size();
+ }
+
+ const char *data_src = (const char *)&x_;
+ int64_t i = 0;
+ while (i != trim_len) {
+ BLI_assert(i < trim_len);
+#ifdef __BIG_ENDIAN__
+ for (int64_t j = (rand_stride + mask_bytes) - 1; j != mask_bytes - 1; j--)
+#else
+ for (int64_t j = 0; j != rand_stride; j++)
+#endif
+ {
+ r_bytes[i++] = data_src[j];
+ }
+ this->step();
+ }
+ if (last_len) {
+ for (int64_t j = 0; j != last_len; j++) {
+ r_bytes[i++] = data_src[j];
+ }
+ }
+}
+
+} // namespace blender
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index ad8443683f8..f952b62cb61 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -238,15 +238,14 @@ static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], c
if (div == 0.0) {
return 1; /* co-linear */
}
- else {
- const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
- (v1[0] - v3[0]) * (v4[1] - v3[1])) /
- div;
- const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
- (v1[0] - v3[0]) * (v2[1] - v1[1])) /
- div;
- return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
- }
+
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
+ (v1[0] - v3[0]) * (v4[1] - v3[1])) /
+ div;
+ const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
+ (v1[0] - v3[0]) * (v2[1] - v1[1])) /
+ div;
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
}
static int isect_segments_fl(const float v1[2],
const float v2[2],
@@ -258,15 +257,14 @@ static int isect_segments_fl(const float v1[2],
if (div == 0.0) {
return 1; /* co-linear */
}
- else {
- const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
- (v1[0] - v3[0]) * (v4[1] - v3[1])) /
- div;
- const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
- (v1[0] - v3[0]) * (v2[1] - v1[1])) /
- div;
- return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
- }
+
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
+ (v1[0] - v3[0]) * (v4[1] - v3[1])) /
+ div;
+ const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
+ (v1[0] - v3[0]) * (v2[1] - v1[1])) /
+ div;
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
}
bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
@@ -289,31 +287,30 @@ bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
if (BLI_rcti_isect_pt_v(rect, s1) || BLI_rcti_isect_pt_v(rect, s2)) {
return true;
}
- else {
- /* both points are outside but may intersect the rect */
- int tvec1[2];
- int tvec2[2];
- /* diagonal: [/] */
- tvec1[0] = rect->xmin;
- tvec1[1] = rect->ymin;
- tvec2[0] = rect->xmin;
- tvec2[1] = rect->ymax;
- if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return true;
- }
- /* diagonal: [\] */
- tvec1[0] = rect->xmin;
- tvec1[1] = rect->ymax;
- tvec2[0] = rect->xmax;
- tvec2[1] = rect->ymin;
- if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return true;
- }
+ /* both points are outside but may intersect the rect */
+ int tvec1[2];
+ int tvec2[2];
+ /* diagonal: [/] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymin;
+ tvec2[0] = rect->xmin;
+ tvec2[1] = rect->ymax;
+ if (isect_segments_i(s1, s2, tvec1, tvec2)) {
+ return true;
+ }
- /* no intersection */
- return false;
+ /* diagonal: [\] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymax;
+ tvec2[0] = rect->xmax;
+ tvec2[1] = rect->ymin;
+ if (isect_segments_i(s1, s2, tvec1, tvec2)) {
+ return true;
}
+
+ /* no intersection */
+ return false;
}
bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
@@ -336,31 +333,30 @@ bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[
if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) {
return true;
}
- else {
- /* both points are outside but may intersect the rect */
- float tvec1[2];
- float tvec2[2];
- /* diagonal: [/] */
- tvec1[0] = rect->xmin;
- tvec1[1] = rect->ymin;
- tvec2[0] = rect->xmin;
- tvec2[1] = rect->ymax;
- if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return true;
- }
- /* diagonal: [\] */
- tvec1[0] = rect->xmin;
- tvec1[1] = rect->ymax;
- tvec2[0] = rect->xmax;
- tvec2[1] = rect->ymin;
- if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return true;
- }
+ /* both points are outside but may intersect the rect */
+ float tvec1[2];
+ float tvec2[2];
+ /* diagonal: [/] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymin;
+ tvec2[0] = rect->xmin;
+ tvec2[1] = rect->ymax;
+ if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
+ return true;
+ }
- /* no intersection */
- return false;
+ /* diagonal: [\] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymax;
+ tvec2[0] = rect->xmax;
+ tvec2[1] = rect->ymin;
+ if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
+ return true;
}
+
+ /* no intersection */
+ return false;
}
bool BLI_rcti_isect_circle(const rcti *rect, const float xy[2], const float radius)
@@ -635,6 +631,14 @@ void BLI_rcti_resize(rcti *rect, int x, int y)
rect->ymax = rect->ymin + y;
}
+void BLI_rcti_pad(rcti *rect, int pad_x, int pad_y)
+{
+ rect->xmin -= pad_x;
+ rect->ymin -= pad_y;
+ rect->xmax += pad_x;
+ rect->ymax += pad_y;
+}
+
void BLI_rctf_resize(rctf *rect, float x, float y)
{
rect->xmin = BLI_rctf_cent_x(rect) - (x * 0.5f);
@@ -882,15 +886,14 @@ bool BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
}
return true;
}
- else {
- if (dest) {
- dest->xmin = 0;
- dest->xmax = 0;
- dest->ymin = 0;
- dest->ymax = 0;
- }
- return false;
+
+ if (dest) {
+ dest->xmin = 0;
+ dest->xmax = 0;
+ dest->ymin = 0;
+ dest->ymax = 0;
}
+ return false;
}
bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
@@ -912,15 +915,14 @@ bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
}
return true;
}
- else {
- if (dest) {
- dest->xmin = 0;
- dest->xmax = 0;
- dest->ymin = 0;
- dest->ymax = 0;
- }
- return false;
+
+ if (dest) {
+ dest->xmin = 0;
+ dest->xmax = 0;
+ dest->ymin = 0;
+ dest->ymax = 0;
}
+ return false;
}
bool BLI_rctf_isect_rect_x(const rctf *src1, const rctf *src2, float range_x[2])
@@ -935,13 +937,12 @@ bool BLI_rctf_isect_rect_x(const rctf *src1, const rctf *src2, float range_x[2])
}
return true;
}
- else {
- if (range_x) {
- range_x[0] = 0;
- range_x[1] = 0;
- }
- return false;
+
+ if (range_x) {
+ range_x[0] = 0;
+ range_x[1] = 0;
}
+ return false;
}
bool BLI_rctf_isect_rect_y(const rctf *src1, const rctf *src2, float range_y[2])
@@ -956,13 +957,12 @@ bool BLI_rctf_isect_rect_y(const rctf *src1, const rctf *src2, float range_y[2])
}
return true;
}
- else {
- if (range_y) {
- range_y[0] = 0;
- range_y[1] = 0;
- }
- return false;
+
+ if (range_y) {
+ range_y[0] = 0;
+ range_y[1] = 0;
}
+ return false;
}
bool BLI_rcti_isect_rect_x(const rcti *src1, const rcti *src2, int range_x[2])
@@ -977,13 +977,12 @@ bool BLI_rcti_isect_rect_x(const rcti *src1, const rcti *src2, int range_x[2])
}
return true;
}
- else {
- if (range_x) {
- range_x[0] = 0;
- range_x[1] = 0;
- }
- return false;
+
+ if (range_x) {
+ range_x[0] = 0;
+ range_x[1] = 0;
}
+ return false;
}
bool BLI_rcti_isect_rect_y(const rcti *src1, const rcti *src2, int range_y[2])
@@ -998,13 +997,12 @@ bool BLI_rcti_isect_rect_y(const rcti *src1, const rcti *src2, int range_y[2])
}
return true;
}
- else {
- if (range_y) {
- range_y[0] = 0;
- range_y[1] = 0;
- }
- return false;
+
+ if (range_y) {
+ range_y[0] = 0;
+ range_y[1] = 0;
}
+ return false;
}
void BLI_rcti_rctf_copy(rcti *dst, const rctf *src)
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 4723a3532ac..8b536354af2 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -91,13 +91,13 @@ static int vergscdata(const void *a1, const void *a2)
if (x1->vert->xy[1] < x2->vert->xy[1]) {
return 1;
}
- else if (x1->vert->xy[1] > x2->vert->xy[1]) {
+ if (x1->vert->xy[1] > x2->vert->xy[1]) {
return -1;
}
- else if (x1->vert->xy[0] > x2->vert->xy[0]) {
+ if (x1->vert->xy[0] > x2->vert->xy[0]) {
return 1;
}
- else if (x1->vert->xy[0] < x2->vert->xy[0]) {
+ if (x1->vert->xy[0] < x2->vert->xy[0]) {
return -1;
}
@@ -111,13 +111,13 @@ static int vergpoly(const void *a1, const void *a2)
if (x1->min_xy[0] > x2->min_xy[0]) {
return 1;
}
- else if (x1->min_xy[0] < x2->min_xy[0]) {
+ if (x1->min_xy[0] < x2->min_xy[0]) {
return -1;
}
- else if (x1->min_xy[1] > x2->min_xy[1]) {
+ if (x1->min_xy[1] > x2->min_xy[1]) {
return 1;
}
- else if (x1->min_xy[1] < x2->min_xy[1]) {
+ if (x1->min_xy[1] < x2->min_xy[1]) {
return -1;
}
@@ -259,7 +259,7 @@ static bool testedgeside(const float v1[2], const float v2[2], const float v3[2]
if (inp < 0.0f) {
return false;
}
- else if (inp == 0.0f) {
+ if (inp == 0.0f) {
if (v1[0] == v3[0] && v1[1] == v3[1]) {
return false;
}
@@ -417,25 +417,24 @@ static void testvertexnearedge(ScanFillContext *sf_ctx)
eve->edge_tot = 0;
break;
}
- else if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) {
+ if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) {
ed1->v2 = eed->v2;
eed->v2->edge_tot++;
eve->edge_tot = 0;
break;
}
- else {
- if (boundinsideEV(eed, eve)) {
- const float dist = dist_squared_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy);
- if (dist < SF_EPSILON_SQ) {
- /* new edge */
- ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
-
- /* printf("fill: vertex near edge %x\n", eve); */
- ed1->poly_nr = eed->poly_nr;
- eed->v1 = eve;
- eve->edge_tot = 3;
- break;
- }
+
+ if (boundinsideEV(eed, eve)) {
+ const float dist = dist_squared_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy);
+ if (dist < SF_EPSILON_SQ) {
+ /* new edge */
+ ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
+
+ /* printf("fill: vertex near edge %x\n", eve); */
+ ed1->poly_nr = eed->poly_nr;
+ eed->v1 = eve;
+ eve->edge_tot = 3;
+ break;
}
}
}
@@ -875,41 +874,40 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
if (UNLIKELY(eve == NULL)) {
return 0;
}
+
+ float n[3];
+
+ if (nor_proj) {
+ copy_v3_v3(n, nor_proj);
+ }
else {
- float n[3];
+ /* define projection: with 'best' normal */
+ /* Newell's Method */
+ /* Similar code used elsewhere, but this checks for double ups
+ * which historically this function supports so better not change */
- if (nor_proj) {
- copy_v3_v3(n, nor_proj);
- }
- else {
- /* define projection: with 'best' normal */
- /* Newell's Method */
- /* Similar code used elsewhere, but this checks for double ups
- * which historically this function supports so better not change */
-
- /* warning: this only gives stable direction with single polygons,
- * ideally we'd calculate connectivity and each polys normal, see T41047 */
- const float *v_prev;
-
- zero_v3(n);
- eve = sf_ctx->fillvertbase.last;
- v_prev = eve->co;
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) {
- add_newell_cross_v3_v3v3(n, v_prev, eve->co);
- v_prev = eve->co;
- }
- }
- }
+ /* warning: this only gives stable direction with single polygons,
+ * ideally we'd calculate connectivity and each polys normal, see T41047 */
+ const float *v_prev;
- if (UNLIKELY(normalize_v3(n) == 0.0f)) {
- return 0;
+ zero_v3(n);
+ eve = sf_ctx->fillvertbase.last;
+ v_prev = eve->co;
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) {
+ add_newell_cross_v3_v3v3(n, v_prev, eve->co);
+ v_prev = eve->co;
+ }
}
+ }
- axis_dominant_v3_to_m3_negate(mat_2d, n);
+ if (UNLIKELY(normalize_v3(n) == 0.0f)) {
+ return 0;
}
+ axis_dominant_v3_to_m3_negate(mat_2d, n);
+
/* STEP 1: COUNT POLYS */
if (sf_ctx->poly_nr != SF_POLY_UNSET) {
poly = (unsigned short)(sf_ctx->poly_nr + 1);
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index 31b2bf85142..660d3dca807 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -139,9 +139,8 @@ static int edge_isect_ls_sort_cb(void *thunk, const void *def_a_ptr, const void
if (a > b) {
return -1;
}
- else {
- return (a < b);
- }
+
+ return (a < b);
}
static ScanFillEdge *edge_step(PolyInfo *poly_info,
diff --git a/source/blender/blenlib/intern/session_uuid.c b/source/blender/blenlib/intern/session_uuid.c
new file mode 100644
index 00000000000..8ed96f02149
--- /dev/null
+++ b/source/blender/blenlib/intern/session_uuid.c
@@ -0,0 +1,78 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#include "BLI_session_uuid.h"
+
+#include "BLI_utildefines.h"
+
+#include "atomic_ops.h"
+
+/* Special value which indicates the UUID has not been assigned yet. */
+#define BLI_SESSION_UUID_NONE 0
+
+static const SessionUUID global_session_uuid_none = {BLI_SESSION_UUID_NONE};
+
+/* Denotes last used UUID.
+ * It might eventually overflow, and easiest is to add more bits to it. */
+static SessionUUID global_session_uuid = {BLI_SESSION_UUID_NONE};
+
+SessionUUID BLI_session_uuid_generate(void)
+{
+ SessionUUID result;
+ result.uuid_ = atomic_add_and_fetch_uint64(&global_session_uuid.uuid_, 1);
+ if (!BLI_session_uuid_is_generated(&result)) {
+ /* Happens when the UUID overflows.
+ *
+ * Just request the UUID once again, hoping that there are not a lot of high-priority threads
+ * which will overflow the counter once again between the previous call and this one.
+ *
+ * NOTE: It is possible to have collisions after such overflow. */
+ result.uuid_ = atomic_add_and_fetch_uint64(&global_session_uuid.uuid_, 1);
+ }
+ return result;
+}
+
+bool BLI_session_uuid_is_generated(const SessionUUID *uuid)
+{
+ return !BLI_session_uuid_is_equal(uuid, &global_session_uuid_none);
+}
+
+bool BLI_session_uuid_is_equal(const SessionUUID *lhs, const SessionUUID *rhs)
+{
+ return lhs->uuid_ == rhs->uuid_;
+}
+
+uint64_t BLI_session_uuid_hash_uint64(const SessionUUID *uuid)
+{
+ return uuid->uuid_;
+}
+
+uint BLI_session_uuid_ghash_hash(const void *uuid_v)
+{
+ const SessionUUID *uuid = (const SessionUUID *)uuid_v;
+ return uuid->uuid_ & 0xffffffff;
+}
+
+bool BLI_session_uuid_ghash_compare(const void *lhs_v, const void *rhs_v)
+{
+ const SessionUUID *lhs = (const SessionUUID *)lhs_v;
+ const SessionUUID *rhs = (const SessionUUID *)rhs_v;
+ return BLI_session_uuid_is_equal(lhs, rhs);
+}
diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c
index 6d1ce3c84cd..ab2b0fd2928 100644
--- a/source/blender/blenlib/intern/smallhash.c
+++ b/source/blender/blenlib/intern/smallhash.c
@@ -253,10 +253,9 @@ bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item)
e->val = item;
return false;
}
- else {
- BLI_smallhash_insert(sh, key, item);
- return true;
- }
+
+ BLI_smallhash_insert(sh, key, item);
+ return true;
}
#ifdef USE_REMOVE
diff --git a/source/blender/blenlib/intern/sort_utils.c b/source/blender/blenlib/intern/sort_utils.c
index 09babd3d424..e02d77de0c7 100644
--- a/source/blender/blenlib/intern/sort_utils.c
+++ b/source/blender/blenlib/intern/sort_utils.c
@@ -44,12 +44,11 @@ int BLI_sortutil_cmp_float(const void *a_, const void *b_)
if (a->sort_value > b->sort_value) {
return 1;
}
- else if (a->sort_value < b->sort_value) {
+ if (a->sort_value < b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_float_reverse(const void *a_, const void *b_)
@@ -59,12 +58,11 @@ int BLI_sortutil_cmp_float_reverse(const void *a_, const void *b_)
if (a->sort_value < b->sort_value) {
return 1;
}
- else if (a->sort_value > b->sort_value) {
+ if (a->sort_value > b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_int(const void *a_, const void *b_)
@@ -74,12 +72,11 @@ int BLI_sortutil_cmp_int(const void *a_, const void *b_)
if (a->sort_value > b->sort_value) {
return 1;
}
- else if (a->sort_value < b->sort_value) {
+ if (a->sort_value < b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_int_reverse(const void *a_, const void *b_)
@@ -89,12 +86,11 @@ int BLI_sortutil_cmp_int_reverse(const void *a_, const void *b_)
if (a->sort_value < b->sort_value) {
return 1;
}
- else if (a->sort_value > b->sort_value) {
+ if (a->sort_value > b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_ptr(const void *a_, const void *b_)
@@ -104,12 +100,11 @@ int BLI_sortutil_cmp_ptr(const void *a_, const void *b_)
if (a->sort_value > b->sort_value) {
return 1;
}
- else if (a->sort_value < b->sort_value) {
+ if (a->sort_value < b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_ptr_reverse(const void *a_, const void *b_)
@@ -119,10 +114,9 @@ int BLI_sortutil_cmp_ptr_reverse(const void *a_, const void *b_)
if (a->sort_value < b->sort_value) {
return 1;
}
- else if (a->sort_value > b->sort_value) {
+ if (a->sort_value > b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index f2217b1cd1a..fbd9e562b6a 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -53,9 +53,9 @@
# include "BLI_string_utf8.h"
# include "BLI_winstuff.h"
# include "utfconv.h"
+# include <ShObjIdl.h>
# include <direct.h>
# include <io.h>
-# include <shobjidl_core.h>
# include <stdbool.h>
#else
# include <pwd.h>
@@ -96,9 +96,7 @@ char *BLI_current_working_dir(char *dir, const size_t maxncpy)
memcpy(dir, pwd, srclen + 1);
return dir;
}
- else {
- return NULL;
- }
+ return NULL;
}
return getcwd(dir, maxncpy);
#endif
@@ -275,25 +273,26 @@ eFileAttributes BLI_file_attributes(const char *path)
ret |= FILE_ATTR_REPARSE_POINT;
}
-# endif
+# else
-# ifdef __linux__
UNUSED_VARS(path);
/* TODO:
* If Immutable set FILE_ATTR_READONLY
* If Archived set FILE_ATTR_ARCHIVE
*/
-
# endif
-
return ret;
}
#endif
/* Return alias/shortcut file target. Apple version is defined in storage_apple.mm */
#ifndef __APPLE__
-bool BLI_file_alias_target(char target[FILE_MAXDIR], const char *filepath)
+bool BLI_file_alias_target(
+ /* This parameter can only be const on non-windows platforms.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ char target[FILE_MAXDIR],
+ const char *filepath)
{
# ifdef WIN32
if (!BLI_path_extension_check(filepath, ".lnk")) {
@@ -330,9 +329,7 @@ bool BLI_file_alias_target(char target[FILE_MAXDIR], const char *filepath)
}
return (success && target[0]);
-# endif
-
-# ifdef __linux__
+# else
UNUSED_VARS(target, filepath);
/* File-based redirection not supported. */
return false;
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index abdae06acd5..8b4720ca1e1 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -394,9 +394,7 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
if (LIKELY(*(endMatch - 1) != '\\')) {
break;
}
- else {
- endMatch++;
- }
+ endMatch++;
}
if (endMatch) {
@@ -470,11 +468,9 @@ char *BLI_str_replaceN(const char *__restrict str,
return str_new;
}
- else {
- /* Just create a new copy of the entire string - we avoid going through the assembly buffer
- * for what should be a bit more efficiency. */
- return BLI_strdup(str);
- }
+ /* Just create a new copy of the entire string - we avoid going through the assembly buffer
+ * for what should be a bit more efficiency. */
+ return BLI_strdup(str);
}
/**
@@ -574,10 +570,10 @@ int BLI_strcasecmp(const char *s1, const char *s2)
if (c1 < c2) {
return -1;
}
- else if (c1 > c2) {
+ if (c1 > c2) {
return 1;
}
- else if (c1 == 0) {
+ if (c1 == 0) {
break;
}
}
@@ -597,10 +593,10 @@ int BLI_strncasecmp(const char *s1, const char *s2, size_t len)
if (c1 < c2) {
return -1;
}
- else if (c1 > c2) {
+ if (c1 > c2) {
return 1;
}
- else if (c1 == 0) {
+ if (c1 == 0) {
break;
}
}
@@ -627,15 +623,13 @@ static int left_number_strcmp(const char *s1, const char *s2, int *tiebreaker)
if (isdigit(*(p1 + numdigit)) && isdigit(*(p2 + numdigit))) {
continue;
}
- else if (isdigit(*(p1 + numdigit))) {
+ if (isdigit(*(p1 + numdigit))) {
return 1; /* s2 is bigger */
}
- else if (isdigit(*(p2 + numdigit))) {
+ if (isdigit(*(p2 + numdigit))) {
return -1; /* s1 is bigger */
}
- else {
- break;
- }
+ break;
}
/* same number of digits, compare size of number */
@@ -759,14 +753,14 @@ int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad)
if (str1_len == str2_len) {
return strncmp(str1, str2, str2_len);
}
- else if (str1_len > str2_len) {
+ if (str1_len > str2_len) {
int ret = strncmp(str1, str2, str2_len);
if (ret == 0) {
ret = 1;
}
return ret;
}
- else {
+ {
int ret = strncmp(str1, str2, str1_len);
if (ret == 0) {
ret = -1;
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index e9fdce83710..0a723a623f0 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -215,11 +215,9 @@ int BLI_utf8_invalid_strip(char *str, size_t length)
tot++;
break;
}
- else {
- /* strip, keep looking */
- memmove(str, str + 1, length + 1); /* +1 for NULL char! */
- tot++;
- }
+ /* strip, keep looking */
+ memmove(str, str + 1, length + 1); /* +1 for NULL char! */
+ tot++;
}
return tot;
diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c
index fb9530b5cb5..dbeb75570fb 100644
--- a/source/blender/blenlib/intern/string_utils.c
+++ b/source/blender/blenlib/intern/string_utils.c
@@ -72,7 +72,7 @@ size_t BLI_split_name_num(char *left, int *nr, const char *name, const char deli
}
return a;
}
- else if (isdigit(name[a]) == 0) {
+ if (isdigit(name[a]) == 0) {
/* non-numeric suffix - give up */
break;
}
diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c
index 53db49aa59c..20edbb97561 100644
--- a/source/blender/blenlib/intern/system.c
+++ b/source/blender/blenlib/intern/system.c
@@ -111,7 +111,11 @@ void BLI_system_backtrace(FILE *fp)
/* NOTE: The code for CPU brand string is adopted from Cycles. */
#if !defined(_WIN32) || defined(FREE_WINDOWS)
-static void __cpuid(int data[4], int selector)
+static void __cpuid(
+ /* Cannot be const, because it is modified below.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ int data[4],
+ int selector)
{
# if defined(__x86_64__)
asm("cpuid" : "=a"(data[0]), "=b"(data[1]), "=c"(data[2]), "=d"(data[3]) : "a"(selector));
diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc
index 67d8960434e..27e0fb0ed07 100644
--- a/source/blender/blenlib/intern/task_range.cc
+++ b/source/blender/blenlib/intern/task_range.cc
@@ -62,7 +62,7 @@ struct RangeTask {
}
/* Splitting constructor for parallel reduce. */
- RangeTask(RangeTask &other, tbb::split)
+ RangeTask(RangeTask &other, tbb::split /* unused */)
: func(other.func), userdata(other.userdata), settings(other.settings)
{
init_chunk(settings->userdata_chunk);
diff --git a/source/blender/blenlib/intern/threads.cc b/source/blender/blenlib/intern/threads.cc
index 7acd9b071e1..002b78bec39 100644
--- a/source/blender/blenlib/intern/threads.cc
+++ b/source/blender/blenlib/intern/threads.cc
@@ -176,9 +176,9 @@ void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int t
unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
if (level == 0) {
#ifdef USE_APPLE_OMP_FIX
- /* workaround for Apple gcc 4.2.1 omp vs background thread bug,
- * we copy gomp thread local storage pointer to setting it again
- * inside the thread that we start */
+ /* Workaround for Apple gcc 4.2.1 OMP vs background thread bug,
+ * we copy GOMP thread local storage pointer to setting it again
+ * inside the thread that we start. */
thread_tls_data = pthread_getspecific(gomp_tls_key);
#endif
}
@@ -218,8 +218,8 @@ static void *tslot_thread_start(void *tslot_p)
ThreadSlot *tslot = (ThreadSlot *)tslot_p;
#ifdef USE_APPLE_OMP_FIX
- /* workaround for Apple gcc 4.2.1 omp vs background thread bug,
- * set gomp thread local storage pointer which was copied beforehand */
+ /* Workaround for Apple gcc 4.2.1 OMP vs background thread bug,
+ * set GOMP thread local storage pointer which was copied beforehand */
pthread_setspecific(gomp_tls_key, thread_tls_data);
#endif
@@ -309,7 +309,7 @@ int BLI_system_thread_count(void)
if (num_threads_override != 0) {
return num_threads_override;
}
- else if (LIKELY(t != -1)) {
+ if (LIKELY(t != -1)) {
return t;
}
@@ -433,7 +433,7 @@ void BLI_mutex_free(ThreadMutex *mutex)
/* Spin Locks */
-#if WITH_TBB
+#ifdef WITH_TBB
static tbb::spin_mutex *tbb_spin_mutex_cast(SpinLock *spin)
{
static_assert(sizeof(SpinLock) >= sizeof(tbb::spin_mutex),
@@ -500,7 +500,7 @@ void BLI_spin_end(SpinLock *spin)
#elif defined(__APPLE__)
BLI_mutex_end(spin);
#elif defined(_MSC_VER)
- BLI_mutex_unlock(spin);
+ /* Nothing to do, spin is a simple integer type. */
#else
pthread_spin_destroy(spin);
#endif
@@ -751,7 +751,7 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) {
break;
}
- else if (PIL_check_seconds_timer() - t >= ms * 0.001) {
+ if (PIL_check_seconds_timer() - t >= ms * 0.001) {
break;
}
}
diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c
index 510b9651961..9586da941a4 100644
--- a/source/blender/blenlib/intern/timecode.c
+++ b/source/blender/blenlib/intern/timecode.c
@@ -36,7 +36,7 @@
#include "BLI_strict_flags.h"
/**
- * Generate timecode/frame number string and store in \a str
+ * Generate time-code/frame number string and store in \a str
*
* \param str: destination string
* \param maxncpy: maximum number of characters to copy ``sizeof(str)``
@@ -44,7 +44,7 @@
* used to specify how detailed we need to be
* \param time_seconds: time total time in seconds
* \param fps: frames per second, typically from the #FPS macro
- * \param timecode_style: enum from eTimecodeStyles
+ * \param timecode_style: enum from #eTimecodeStyles
* \return length of \a str
*/
diff --git a/source/blender/blenlib/intern/timeit.cc b/source/blender/blenlib/intern/timeit.cc
index 7938784da67..9e07e44ca12 100644
--- a/source/blender/blenlib/intern/timeit.cc
+++ b/source/blender/blenlib/intern/timeit.cc
@@ -16,8 +16,7 @@
#include "BLI_timeit.hh"
-namespace blender {
-namespace Timeit {
+namespace blender::timeit {
void print_duration(Nanoseconds duration)
{
@@ -32,5 +31,4 @@ void print_duration(Nanoseconds duration)
}
}
-} // namespace Timeit
-} // namespace blender
+} // namespace blender::timeit
diff --git a/source/blender/blenlib/intern/uvproject.c b/source/blender/blenlib/intern/uvproject.c
index a34c551767a..00fef29587c 100644
--- a/source/blender/blenlib/intern/uvproject.c
+++ b/source/blender/blenlib/intern/uvproject.c
@@ -183,7 +183,7 @@ ProjCameraInfo *BLI_uvproject_camera_info(Object *ob, float (*rotmat)[4], float
return NULL;
}
-void BLI_uvproject_from_view_ortho(float target[2], float source[3], float rotmat[4][4])
+void BLI_uvproject_from_view_ortho(float target[2], float source[3], const float rotmat[4][4])
{
float pv[3];
diff --git a/source/blender/blenlib/intern/voronoi_2d.c b/source/blender/blenlib/intern/voronoi_2d.c
index 59270c58341..bc11a2c7a1c 100644
--- a/source/blender/blenlib/intern/voronoi_2d.c
+++ b/source/blender/blenlib/intern/voronoi_2d.c
@@ -213,7 +213,7 @@ static void voronoiParabola_setRight(VoronoiParabola *parabola, VoronoiParabola
right->parent = parabola;
}
-static float voronoi_getY(VoronoiProcess *process, float p[2], float x)
+static float voronoi_getY(VoronoiProcess *process, const float p[2], float x)
{
float ly = process->current_y;
diff --git a/source/blender/blenlib/intern/voxel.c b/source/blender/blenlib/intern/voxel.c
index c7c794957c2..2c8eb9f5a13 100644
--- a/source/blender/blenlib/intern/voxel.c
+++ b/source/blender/blenlib/intern/voxel.c
@@ -26,7 +26,7 @@
#include "BLI_strict_flags.h"
-BLI_INLINE float D(float *data, const int res[3], int x, int y, int z)
+BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
{
CLAMP(x, 0, res[0] - 1);
CLAMP(y, 0, res[1] - 1);
@@ -36,7 +36,7 @@ BLI_INLINE float D(float *data, const int res[3], int x, int y, int z)
/* *** nearest neighbor *** */
/* input coordinates must be in bounding box 0.0 - 1.0 */
-float BLI_voxel_sample_nearest(float *data, const int res[3], const float co[3])
+float BLI_voxel_sample_nearest(const float *data, const int res[3], const float co[3])
{
int xi, yi, zi;
@@ -65,7 +65,7 @@ BLI_INLINE int64_t _clamp(int a, int b, int c)
return (a < b) ? b : ((a > c) ? c : a);
}
-float BLI_voxel_sample_trilinear(float *data, const int res[3], const float co[3])
+float BLI_voxel_sample_trilinear(const float *data, const int res[3], const float co[3])
{
if (data) {
@@ -106,7 +106,7 @@ float BLI_voxel_sample_trilinear(float *data, const int res[3], const float co[3
return 0.f;
}
-float BLI_voxel_sample_triquadratic(float *data, const int res[3], const float co[3])
+float BLI_voxel_sample_triquadratic(const float *data, const int res[3], const float co[3])
{
if (data) {
@@ -161,7 +161,10 @@ float BLI_voxel_sample_triquadratic(float *data, const int res[3], const float c
return 0.f;
}
-float BLI_voxel_sample_tricubic(float *data, const int res[3], const float co[3], int bspline)
+float BLI_voxel_sample_tricubic(const float *data,
+ const int res[3],
+ const float co[3],
+ int bspline)
{
if (data) {
diff --git a/source/blender/blenlib/tests/BLI_array_test.cc b/source/blender/blenlib/tests/BLI_array_test.cc
new file mode 100644
index 00000000000..7348a6f93f3
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_array_test.cc
@@ -0,0 +1,176 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_array.hh"
+#include "BLI_strict_flags.h"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(array, DefaultConstructor)
+{
+ Array<int> array;
+ EXPECT_EQ(array.size(), 0);
+ EXPECT_TRUE(array.is_empty());
+}
+
+TEST(array, SizeConstructor)
+{
+ Array<int> array(5);
+ EXPECT_EQ(array.size(), 5);
+ EXPECT_FALSE(array.is_empty());
+}
+
+TEST(array, FillConstructor)
+{
+ Array<int> array(5, 8);
+ EXPECT_EQ(array.size(), 5);
+ EXPECT_EQ(array[0], 8);
+ EXPECT_EQ(array[1], 8);
+ EXPECT_EQ(array[2], 8);
+ EXPECT_EQ(array[3], 8);
+ EXPECT_EQ(array[4], 8);
+}
+
+TEST(array, InitializerListConstructor)
+{
+ Array<int> array = {4, 5, 6, 7};
+ EXPECT_EQ(array.size(), 4);
+ EXPECT_EQ(array[0], 4);
+ EXPECT_EQ(array[1], 5);
+ EXPECT_EQ(array[2], 6);
+ EXPECT_EQ(array[3], 7);
+}
+
+TEST(array, SpanConstructor)
+{
+ int stackarray[4] = {6, 7, 8, 9};
+ Span<int> span(stackarray, ARRAY_SIZE(stackarray));
+ Array<int> array(span);
+ EXPECT_EQ(array.size(), 4);
+ EXPECT_EQ(array[0], 6);
+ EXPECT_EQ(array[1], 7);
+ EXPECT_EQ(array[2], 8);
+ EXPECT_EQ(array[3], 9);
+}
+
+TEST(array, CopyConstructor)
+{
+ Array<int> array = {5, 6, 7, 8};
+ Array<int> new_array(array);
+
+ EXPECT_EQ(array.size(), 4);
+ EXPECT_EQ(new_array.size(), 4);
+ EXPECT_NE(array.data(), new_array.data());
+ EXPECT_EQ(new_array[0], 5);
+ EXPECT_EQ(new_array[1], 6);
+ EXPECT_EQ(new_array[2], 7);
+ EXPECT_EQ(new_array[3], 8);
+}
+
+TEST(array, MoveConstructor)
+{
+ Array<int> array = {5, 6, 7, 8};
+ Array<int> new_array(std::move(array));
+
+ EXPECT_EQ(array.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(new_array.size(), 4);
+ EXPECT_EQ(new_array[0], 5);
+ EXPECT_EQ(new_array[1], 6);
+ EXPECT_EQ(new_array[2], 7);
+ EXPECT_EQ(new_array[3], 8);
+}
+
+TEST(array, CopyAssignment)
+{
+ Array<int> array = {1, 2, 3};
+ Array<int> new_array = {4};
+ EXPECT_EQ(new_array.size(), 1);
+ new_array = array;
+ EXPECT_EQ(new_array.size(), 3);
+ EXPECT_EQ(array.size(), 3);
+ EXPECT_NE(array.data(), new_array.data());
+ EXPECT_EQ(new_array[0], 1);
+ EXPECT_EQ(new_array[1], 2);
+ EXPECT_EQ(new_array[2], 3);
+}
+
+TEST(array, MoveAssignment)
+{
+ Array<int> array = {1, 2, 3};
+ Array<int> new_array = {4};
+ EXPECT_EQ(new_array.size(), 1);
+ new_array = std::move(array);
+ EXPECT_EQ(new_array.size(), 3);
+ EXPECT_EQ(array.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(new_array[0], 1);
+ EXPECT_EQ(new_array[1], 2);
+ EXPECT_EQ(new_array[2], 3);
+}
+
+/**
+ * Tests that the trivially constructible types are not zero-initialized. We do not want that for
+ * performance reasons.
+ */
+TEST(array, TrivialTypeSizeConstructor)
+{
+ Array<char, 1> *array = new Array<char, 1>(1);
+ char *ptr = &(*array)[0];
+ array->~Array();
+
+ const char magic = 42;
+ *ptr = magic;
+ EXPECT_EQ(*ptr, magic);
+
+ new (array) Array<char, 1>(1);
+ EXPECT_EQ((*array)[0], magic);
+ EXPECT_EQ(*ptr, magic);
+ delete array;
+}
+
+struct ConstructibleType {
+ char value;
+
+ ConstructibleType()
+ {
+ value = 42;
+ }
+};
+
+TEST(array, NoInitializationSizeConstructor)
+{
+ using MyArray = Array<ConstructibleType>;
+
+ TypedBuffer<MyArray> buffer;
+ memset((void *)&buffer, 100, sizeof(MyArray));
+
+ /* Doing this to avoid some compiler optimization. */
+ for (int64_t i : IndexRange(sizeof(MyArray))) {
+ EXPECT_EQ(((char *)buffer.ptr())[i], 100);
+ }
+
+ {
+ MyArray &array = *new (buffer) MyArray(1, NoInitialization());
+ EXPECT_EQ(array[0].value, 100);
+ array.clear_without_destruct();
+ array.~Array();
+ }
+ {
+ MyArray &array = *new (buffer) MyArray(1);
+ EXPECT_EQ(array[0].value, 42);
+ array.~Array();
+ }
+}
+
+TEST(array, Fill)
+{
+ Array<int> array(5);
+ array.fill(3);
+ EXPECT_EQ(array.size(), 5u);
+ EXPECT_EQ(array[0], 3);
+ EXPECT_EQ(array[1], 3);
+ EXPECT_EQ(array[2], 3);
+ EXPECT_EQ(array[3], 3);
+ EXPECT_EQ(array[4], 3);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_disjoint_set_test.cc b/source/blender/blenlib/tests/BLI_disjoint_set_test.cc
new file mode 100644
index 00000000000..f30ee610b2a
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_disjoint_set_test.cc
@@ -0,0 +1,36 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_disjoint_set.hh"
+#include "BLI_strict_flags.h"
+
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(disjoint_set, Test)
+{
+ DisjointSet disjoint_set(6);
+ EXPECT_FALSE(disjoint_set.in_same_set(1, 2));
+ EXPECT_FALSE(disjoint_set.in_same_set(5, 3));
+ EXPECT_TRUE(disjoint_set.in_same_set(2, 2));
+ EXPECT_EQ(disjoint_set.find_root(3), 3);
+
+ disjoint_set.join(1, 2);
+
+ EXPECT_TRUE(disjoint_set.in_same_set(1, 2));
+ EXPECT_FALSE(disjoint_set.in_same_set(0, 1));
+
+ disjoint_set.join(3, 4);
+
+ EXPECT_FALSE(disjoint_set.in_same_set(2, 3));
+ EXPECT_TRUE(disjoint_set.in_same_set(3, 4));
+
+ disjoint_set.join(1, 4);
+
+ EXPECT_TRUE(disjoint_set.in_same_set(1, 4));
+ EXPECT_TRUE(disjoint_set.in_same_set(1, 3));
+ EXPECT_TRUE(disjoint_set.in_same_set(2, 4));
+ EXPECT_FALSE(disjoint_set.in_same_set(0, 4));
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_edgehash_test.cc b/source/blender/blenlib/tests/BLI_edgehash_test.cc
new file mode 100644
index 00000000000..7106033df36
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_edgehash_test.cc
@@ -0,0 +1,408 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+#include <algorithm>
+#include <random>
+#include <vector>
+
+#include "BLI_edgehash.h"
+#include "BLI_utildefines.h"
+
+#define VALUE_1 POINTER_FROM_INT(1)
+#define VALUE_2 POINTER_FROM_INT(2)
+#define VALUE_3 POINTER_FROM_INT(3)
+
+TEST(edgehash, InsertIncreasesLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, ReinsertNewIncreasesLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+ BLI_edgehash_reinsert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, ReinsertExistingDoesNotIncreaseLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+ BLI_edgehash_reinsert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ BLI_edgehash_reinsert(eh, 1, 2, VALUE_2);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ BLI_edgehash_reinsert(eh, 2, 1, VALUE_2);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, ReinsertCanChangeValue)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_1);
+ BLI_edgehash_reinsert(eh, 2, 1, VALUE_2);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_2);
+ BLI_edgehash_reinsert(eh, 1, 2, VALUE_3);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 2, 1), VALUE_3);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 2, 1), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupNonExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), nullptr);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupNonExistingWithDefault)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_lookup_default(eh, 1, 2, VALUE_1), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupExistingWithDefault)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup_default(eh, 1, 2, VALUE_2), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupPExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ void *value = VALUE_1;
+ BLI_edgehash_insert(eh, 1, 2, value);
+ void **value_p = BLI_edgehash_lookup_p(eh, 1, 2);
+ ASSERT_EQ(*value_p, VALUE_1);
+ *value_p = VALUE_2;
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_2);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupPNonExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_lookup_p(eh, 1, 2), nullptr);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, EnsurePNonExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ void **value_p;
+ bool existed = BLI_edgehash_ensure_p(eh, 1, 2, &value_p);
+ ASSERT_FALSE(existed);
+ *value_p = VALUE_1;
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, EnsurePExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ void **value_p;
+ bool existed = BLI_edgehash_ensure_p(eh, 1, 2, &value_p);
+ ASSERT_TRUE(existed);
+ ASSERT_EQ(*value_p, VALUE_1);
+ *value_p = VALUE_2;
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_2);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, RemoveExistingDecreasesLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ bool has_been_removed = BLI_edgehash_remove(eh, 1, 2, nullptr);
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+ ASSERT_TRUE(has_been_removed);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, RemoveNonExistingDoesNotDecreaseLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ bool has_been_removed = BLI_edgehash_remove(eh, 4, 5, nullptr);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ ASSERT_FALSE(has_been_removed);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, PopKeyTwice)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_popkey(eh, 1, 2), VALUE_1);
+ ASSERT_EQ(BLI_edgehash_popkey(eh, 1, 2), nullptr);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupInvertedIndices)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 2, 1), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, HasKeyExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_TRUE(BLI_edgehash_haskey(eh, 1, 2));
+ ASSERT_TRUE(BLI_edgehash_haskey(eh, 2, 1));
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, HasKeyNonExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_FALSE(BLI_edgehash_haskey(eh, 1, 2));
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, ClearSetsLengthToZero)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ BLI_edgehash_insert(eh, 1, 2, VALUE_2);
+ ASSERT_EQ(BLI_edgehash_len(eh), 2);
+ BLI_edgehash_clear(eh, nullptr);
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, IteratorFindsAllValues)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ BLI_edgehash_insert(eh, 1, 3, VALUE_2);
+ BLI_edgehash_insert(eh, 1, 4, VALUE_3);
+
+ EdgeHashIterator *ehi = BLI_edgehashIterator_new(eh);
+ auto a = BLI_edgehashIterator_getValue(ehi);
+ BLI_edgehashIterator_step(ehi);
+ auto b = BLI_edgehashIterator_getValue(ehi);
+ BLI_edgehashIterator_step(ehi);
+ auto c = BLI_edgehashIterator_getValue(ehi);
+ BLI_edgehashIterator_step(ehi);
+
+ ASSERT_NE(a, b);
+ ASSERT_NE(b, c);
+ ASSERT_NE(a, c);
+ ASSERT_TRUE(ELEM(a, VALUE_1, VALUE_2, VALUE_3));
+ ASSERT_TRUE(ELEM(b, VALUE_1, VALUE_2, VALUE_3));
+ ASSERT_TRUE(ELEM(c, VALUE_1, VALUE_2, VALUE_3));
+
+ BLI_edgehashIterator_free(ehi);
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, IterateIsDone)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ BLI_edgehash_insert(eh, 1, 3, VALUE_2);
+ BLI_edgehash_insert(eh, 1, 4, VALUE_3);
+
+ EdgeHashIterator *ehi = BLI_edgehashIterator_new(eh);
+ ASSERT_FALSE(BLI_edgehashIterator_isDone(ehi));
+ BLI_edgehashIterator_step(ehi);
+ ASSERT_FALSE(BLI_edgehashIterator_isDone(ehi));
+ BLI_edgehashIterator_step(ehi);
+ ASSERT_FALSE(BLI_edgehashIterator_isDone(ehi));
+ BLI_edgehashIterator_step(ehi);
+ ASSERT_TRUE(BLI_edgehashIterator_isDone(ehi));
+
+ BLI_edgehashIterator_free(ehi);
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, DoubleRemove)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ BLI_edgehash_insert(eh, 1, 3, VALUE_2);
+ BLI_edgehash_insert(eh, 1, 4, VALUE_3);
+ ASSERT_EQ(BLI_edgehash_len(eh), 3);
+
+ BLI_edgehash_remove(eh, 1, 2, nullptr);
+ BLI_edgehash_remove(eh, 1, 3, nullptr);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+struct Edge {
+ uint v1, v2;
+};
+
+TEST(edgehash, StressTest)
+{
+ std::srand(0);
+ int amount = 10000;
+
+ std::vector<Edge> edges;
+ for (int i = 0; i < amount; i++) {
+ edges.push_back({(uint)i, amount + (uint)std::rand() % 12345});
+ }
+
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ /* first insert all the edges */
+ for (int i = 0; i < edges.size(); i++) {
+ BLI_edgehash_insert(eh, edges[i].v1, edges[i].v2, POINTER_FROM_INT(i));
+ }
+
+ std::vector<Edge> shuffled = edges;
+ std::shuffle(shuffled.begin(), shuffled.end(), std::default_random_engine());
+
+ /* then remove half of them */
+ int remove_until = shuffled.size() / 2;
+ for (int i = 0; i < remove_until; i++) {
+ BLI_edgehash_remove(eh, shuffled[i].v2, shuffled[i].v1, nullptr);
+ }
+
+ ASSERT_EQ(BLI_edgehash_len(eh), edges.size() - remove_until);
+
+ /* check if the right ones have been removed */
+ for (int i = 0; i < shuffled.size(); i++) {
+ bool haskey = BLI_edgehash_haskey(eh, shuffled[i].v1, shuffled[i].v2);
+ if (i < remove_until) {
+ ASSERT_FALSE(haskey);
+ }
+ else {
+ ASSERT_TRUE(haskey);
+ }
+ }
+
+ /* reinsert all edges */
+ for (int i = 0; i < edges.size(); i++) {
+ BLI_edgehash_reinsert(eh, edges[i].v1, edges[i].v2, POINTER_FROM_INT(i));
+ }
+
+ ASSERT_EQ(BLI_edgehash_len(eh), edges.size());
+
+ /* pop all edges */
+ for (int i = 0; i < edges.size(); i++) {
+ int value = POINTER_AS_INT(BLI_edgehash_popkey(eh, edges[i].v1, edges[i].v2));
+ ASSERT_EQ(i, value);
+ }
+
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgeset, AddNonExistingIncreasesLength)
+{
+ EdgeSet *es = BLI_edgeset_new(__func__);
+
+ ASSERT_EQ(BLI_edgeset_len(es), 0);
+ BLI_edgeset_add(es, 1, 2);
+ ASSERT_EQ(BLI_edgeset_len(es), 1);
+ BLI_edgeset_add(es, 1, 3);
+ ASSERT_EQ(BLI_edgeset_len(es), 2);
+ BLI_edgeset_add(es, 1, 4);
+ ASSERT_EQ(BLI_edgeset_len(es), 3);
+
+ BLI_edgeset_free(es);
+}
+
+TEST(edgeset, AddExistingDoesNotIncreaseLength)
+{
+ EdgeSet *es = BLI_edgeset_new(__func__);
+
+ ASSERT_EQ(BLI_edgeset_len(es), 0);
+ BLI_edgeset_add(es, 1, 2);
+ ASSERT_EQ(BLI_edgeset_len(es), 1);
+ BLI_edgeset_add(es, 2, 1);
+ ASSERT_EQ(BLI_edgeset_len(es), 1);
+ BLI_edgeset_add(es, 1, 2);
+ ASSERT_EQ(BLI_edgeset_len(es), 1);
+
+ BLI_edgeset_free(es);
+}
+
+TEST(edgeset, HasKeyNonExisting)
+{
+ EdgeSet *es = BLI_edgeset_new(__func__);
+
+ ASSERT_FALSE(BLI_edgeset_haskey(es, 1, 2));
+
+ BLI_edgeset_free(es);
+}
+
+TEST(edgeset, HasKeyExisting)
+{
+ EdgeSet *es = BLI_edgeset_new(__func__);
+
+ BLI_edgeset_insert(es, 1, 2);
+ ASSERT_TRUE(BLI_edgeset_haskey(es, 1, 2));
+
+ BLI_edgeset_free(es);
+}
diff --git a/source/blender/blenlib/tests/BLI_index_mask_test.cc b/source/blender/blenlib/tests/BLI_index_mask_test.cc
new file mode 100644
index 00000000000..4d6060e51c9
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_index_mask_test.cc
@@ -0,0 +1,43 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_index_mask.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(index_mask, DefaultConstructor)
+{
+ IndexMask mask;
+ EXPECT_EQ(mask.min_array_size(), 0);
+ EXPECT_EQ(mask.size(), 0);
+}
+
+TEST(index_mask, ArrayConstructor)
+{
+ [](IndexMask mask) {
+ EXPECT_EQ(mask.size(), 4);
+ EXPECT_EQ(mask.min_array_size(), 8);
+ EXPECT_FALSE(mask.is_range());
+ EXPECT_EQ(mask[0], 3);
+ EXPECT_EQ(mask[1], 5);
+ EXPECT_EQ(mask[2], 6);
+ EXPECT_EQ(mask[3], 7);
+ }({3, 5, 6, 7});
+}
+
+TEST(index_mask, RangeConstructor)
+{
+ IndexMask mask = IndexRange(3, 5);
+ EXPECT_EQ(mask.size(), 5);
+ EXPECT_EQ(mask.min_array_size(), 8);
+ EXPECT_EQ(mask.last(), 7);
+ EXPECT_TRUE(mask.is_range());
+ EXPECT_EQ(mask.as_range().first(), 3);
+ EXPECT_EQ(mask.as_range().last(), 7);
+ Span<int64_t> indices = mask.indices();
+ EXPECT_EQ(indices[0], 3);
+ EXPECT_EQ(indices[1], 4);
+ EXPECT_EQ(indices[2], 5);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_index_range_test.cc b/source/blender/blenlib/tests/BLI_index_range_test.cc
new file mode 100644
index 00000000000..d472ded0f18
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_index_range_test.cc
@@ -0,0 +1,143 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_index_range.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(index_range, DefaultConstructor)
+{
+ IndexRange range;
+ EXPECT_EQ(range.size(), 0);
+
+ Vector<int64_t> vector;
+ for (int64_t value : range) {
+ vector.append(value);
+ }
+ EXPECT_EQ(vector.size(), 0);
+}
+
+TEST(index_range, SingleElementRange)
+{
+ IndexRange range(4, 1);
+ EXPECT_EQ(range.size(), 1);
+ EXPECT_EQ(*range.begin(), 4);
+
+ Vector<int64_t> vector;
+ for (int64_t value : range) {
+ vector.append(value);
+ }
+
+ EXPECT_EQ(vector.size(), 1);
+ EXPECT_EQ(vector[0], 4);
+}
+
+TEST(index_range, MultipleElementRange)
+{
+ IndexRange range(6, 4);
+ EXPECT_EQ(range.size(), 4);
+
+ Vector<int64_t> vector;
+ for (int64_t value : range) {
+ vector.append(value);
+ }
+
+ EXPECT_EQ(vector.size(), 4);
+ for (int i = 0; i < 4; i++) {
+ EXPECT_EQ(vector[i], i + 6);
+ }
+}
+
+TEST(index_range, SubscriptOperator)
+{
+ IndexRange range(5, 5);
+ EXPECT_EQ(range[0], 5);
+ EXPECT_EQ(range[1], 6);
+ EXPECT_EQ(range[2], 7);
+}
+
+TEST(index_range, Before)
+{
+ IndexRange range = IndexRange(5, 5).before(3);
+ EXPECT_EQ(range[0], 2);
+ EXPECT_EQ(range[1], 3);
+ EXPECT_EQ(range[2], 4);
+ EXPECT_EQ(range.size(), 3);
+}
+
+TEST(index_range, After)
+{
+ IndexRange range = IndexRange(5, 5).after(4);
+ EXPECT_EQ(range[0], 10);
+ EXPECT_EQ(range[1], 11);
+ EXPECT_EQ(range[2], 12);
+ EXPECT_EQ(range[3], 13);
+ EXPECT_EQ(range.size(), 4);
+}
+
+TEST(index_range, Contains)
+{
+ IndexRange range = IndexRange(5, 3);
+ EXPECT_TRUE(range.contains(5));
+ EXPECT_TRUE(range.contains(6));
+ EXPECT_TRUE(range.contains(7));
+ EXPECT_FALSE(range.contains(4));
+ EXPECT_FALSE(range.contains(8));
+}
+
+TEST(index_range, First)
+{
+ IndexRange range = IndexRange(5, 3);
+ EXPECT_EQ(range.first(), 5);
+}
+
+TEST(index_range, Last)
+{
+ IndexRange range = IndexRange(5, 3);
+ EXPECT_EQ(range.last(), 7);
+}
+
+TEST(index_range, OneAfterEnd)
+{
+ IndexRange range = IndexRange(5, 3);
+ EXPECT_EQ(range.one_after_last(), 8);
+}
+
+TEST(index_range, Start)
+{
+ IndexRange range = IndexRange(6, 2);
+ EXPECT_EQ(range.start(), 6);
+}
+
+TEST(index_range, Slice)
+{
+ IndexRange range = IndexRange(5, 15);
+ IndexRange slice = range.slice(2, 6);
+ EXPECT_EQ(slice.size(), 6);
+ EXPECT_EQ(slice.first(), 7);
+ EXPECT_EQ(slice.last(), 12);
+}
+
+TEST(index_range, SliceRange)
+{
+ IndexRange range = IndexRange(5, 15);
+ IndexRange slice = range.slice(IndexRange(3, 5));
+ EXPECT_EQ(slice.size(), 5);
+ EXPECT_EQ(slice.first(), 8);
+ EXPECT_EQ(slice.last(), 12);
+}
+
+TEST(index_range, AsSpan)
+{
+ IndexRange range = IndexRange(4, 6);
+ Span<int64_t> span = range.as_span();
+ EXPECT_EQ(span.size(), 6);
+ EXPECT_EQ(span[0], 4);
+ EXPECT_EQ(span[1], 5);
+ EXPECT_EQ(span[2], 6);
+ EXPECT_EQ(span[3], 7);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
new file mode 100644
index 00000000000..44b70d1f55d
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
@@ -0,0 +1,118 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_linear_allocator.hh"
+#include "BLI_strict_flags.h"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+static bool is_aligned(void *ptr, uint alignment)
+{
+ BLI_assert(is_power_of_2_i((int)alignment));
+ return (POINTER_AS_UINT(ptr) & (alignment - 1)) == 0;
+}
+
+TEST(linear_allocator, AllocationAlignment)
+{
+ LinearAllocator<> allocator;
+
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 8), 8));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 16), 16));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 64), 64));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 64), 64));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 8), 8));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 128), 128));
+}
+
+TEST(linear_allocator, PackedAllocation)
+{
+ LinearAllocator<> allocator;
+ blender::AlignedBuffer<256, 32> buffer;
+ allocator.provide_buffer(buffer);
+
+ uintptr_t ptr1 = (uintptr_t)allocator.allocate(10, 4); /* 0 - 10 */
+ uintptr_t ptr2 = (uintptr_t)allocator.allocate(10, 4); /* 12 - 22 */
+ uintptr_t ptr3 = (uintptr_t)allocator.allocate(8, 32); /* 32 - 40 */
+ uintptr_t ptr4 = (uintptr_t)allocator.allocate(16, 8); /* 40 - 56 */
+ uintptr_t ptr5 = (uintptr_t)allocator.allocate(1, 8); /* 56 - 57 */
+ uintptr_t ptr6 = (uintptr_t)allocator.allocate(1, 4); /* 60 - 61 */
+ uintptr_t ptr7 = (uintptr_t)allocator.allocate(1, 1); /* 61 - 62 */
+
+ EXPECT_EQ(ptr2 - ptr1, 12); /* 12 - 0 = 12 */
+ EXPECT_EQ(ptr3 - ptr2, 20); /* 32 - 12 = 20 */
+ EXPECT_EQ(ptr4 - ptr3, 8); /* 40 - 32 = 8 */
+ EXPECT_EQ(ptr5 - ptr4, 16); /* 56 - 40 = 16 */
+ EXPECT_EQ(ptr6 - ptr5, 4); /* 60 - 56 = 4 */
+ EXPECT_EQ(ptr7 - ptr6, 1); /* 61 - 60 = 1 */
+}
+
+TEST(linear_allocator, CopyString)
+{
+ LinearAllocator<> allocator;
+ blender::AlignedBuffer<256, 1> buffer;
+ allocator.provide_buffer(buffer);
+
+ StringRefNull ref1 = allocator.copy_string("Hello");
+ StringRefNull ref2 = allocator.copy_string("World");
+
+ EXPECT_EQ(ref1, "Hello");
+ EXPECT_EQ(ref2, "World");
+ EXPECT_EQ(ref2.data() - ref1.data(), 6);
+}
+
+TEST(linear_allocator, AllocateArray)
+{
+ LinearAllocator<> allocator;
+
+ MutableSpan<int> span = allocator.allocate_array<int>(5);
+ EXPECT_EQ(span.size(), 5);
+}
+
+TEST(linear_allocator, Construct)
+{
+ LinearAllocator<> allocator;
+
+ std::array<int, 5> values = {1, 2, 3, 4, 5};
+ Vector<int> *vector = allocator.construct<Vector<int>>(values);
+ EXPECT_EQ(vector->size(), 5);
+ EXPECT_EQ((*vector)[3], 4);
+ vector->~Vector();
+}
+
+TEST(linear_allocator, ConstructElementsAndPointerArray)
+{
+ LinearAllocator<> allocator;
+
+ std::array<int, 7> values = {1, 2, 3, 4, 5, 6, 7};
+ Span<Vector<int> *> vectors = allocator.construct_elements_and_pointer_array<Vector<int>>(
+ 5, values);
+
+ EXPECT_EQ(vectors.size(), 5);
+ EXPECT_EQ(vectors[3]->size(), 7);
+ EXPECT_EQ((*vectors[2])[5], 6);
+
+ for (Vector<int> *vector : vectors) {
+ vector->~Vector();
+ }
+}
+
+TEST(linear_allocator, ConstructArrayCopy)
+{
+ LinearAllocator<> allocator;
+
+ Vector<int> values = {1, 2, 3};
+ MutableSpan<int> span1 = allocator.construct_array_copy(values.as_span());
+ MutableSpan<int> span2 = allocator.construct_array_copy(values.as_span());
+ EXPECT_NE(span1.data(), span2.data());
+ EXPECT_EQ(span1.size(), 3);
+ EXPECT_EQ(span2.size(), 3);
+ EXPECT_EQ(span1[1], 2);
+ EXPECT_EQ(span2[2], 3);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_map_test.cc b/source/blender/blenlib/tests/BLI_map_test.cc
new file mode 100644
index 00000000000..fe7b0f01279
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_map_test.cc
@@ -0,0 +1,590 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_map.hh"
+#include "BLI_rand.h"
+#include "BLI_set.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_timeit.hh"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(map, DefaultConstructor)
+{
+ Map<int, float> map;
+ EXPECT_EQ(map.size(), 0);
+ EXPECT_TRUE(map.is_empty());
+}
+
+TEST(map, AddIncreasesSize)
+{
+ Map<int, float> map;
+ EXPECT_EQ(map.size(), 0);
+ EXPECT_TRUE(map.is_empty());
+ map.add(2, 5.0f);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_FALSE(map.is_empty());
+ map.add(6, 2.0f);
+ EXPECT_EQ(map.size(), 2);
+ EXPECT_FALSE(map.is_empty());
+}
+
+TEST(map, Contains)
+{
+ Map<int, float> map;
+ EXPECT_FALSE(map.contains(4));
+ map.add(5, 6.0f);
+ EXPECT_FALSE(map.contains(4));
+ map.add(4, 2.0f);
+ EXPECT_TRUE(map.contains(4));
+}
+
+TEST(map, LookupExisting)
+{
+ Map<int, float> map;
+ map.add(2, 6.0f);
+ map.add(4, 1.0f);
+ EXPECT_EQ(map.lookup(2), 6.0f);
+ EXPECT_EQ(map.lookup(4), 1.0f);
+}
+
+TEST(map, LookupNotExisting)
+{
+ Map<int, float> map;
+ map.add(2, 4.0f);
+ map.add(1, 1.0f);
+ EXPECT_EQ(map.lookup_ptr(0), nullptr);
+ EXPECT_EQ(map.lookup_ptr(5), nullptr);
+}
+
+TEST(map, AddMany)
+{
+ Map<int, int> map;
+ for (int i = 0; i < 100; i++) {
+ map.add(i * 30, i);
+ map.add(i * 31, i);
+ }
+}
+
+TEST(map, PopItem)
+{
+ Map<int, float> map;
+ map.add(2, 3.0f);
+ map.add(1, 9.0f);
+ EXPECT_TRUE(map.contains(2));
+ EXPECT_TRUE(map.contains(1));
+
+ EXPECT_EQ(map.pop(1), 9.0f);
+ EXPECT_TRUE(map.contains(2));
+ EXPECT_FALSE(map.contains(1));
+
+ EXPECT_EQ(map.pop(2), 3.0f);
+ EXPECT_FALSE(map.contains(2));
+ EXPECT_FALSE(map.contains(1));
+}
+
+TEST(map, PopTry)
+{
+ Map<int, int> map;
+ map.add(1, 5);
+ map.add(2, 7);
+ EXPECT_EQ(map.size(), 2);
+ std::optional<int> value = map.pop_try(4);
+ EXPECT_EQ(map.size(), 2);
+ EXPECT_FALSE(value.has_value());
+ value = map.pop_try(2);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_TRUE(value.has_value());
+ EXPECT_EQ(*value, 7);
+ EXPECT_EQ(*map.pop_try(1), 5);
+ EXPECT_EQ(map.size(), 0);
+}
+
+TEST(map, PopDefault)
+{
+ Map<int, int> map;
+ map.add(1, 4);
+ map.add(2, 7);
+ map.add(3, 8);
+ EXPECT_EQ(map.size(), 3);
+ EXPECT_EQ(map.pop_default(4, 10), 10);
+ EXPECT_EQ(map.size(), 3);
+ EXPECT_EQ(map.pop_default(1, 10), 4);
+ EXPECT_EQ(map.size(), 2);
+ EXPECT_EQ(map.pop_default(2, 20), 7);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.pop_default(2, 20), 20);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.pop_default(3, 0), 8);
+ EXPECT_EQ(map.size(), 0);
+}
+
+TEST(map, PopItemMany)
+{
+ Map<int, int> map;
+ for (int i = 0; i < 100; i++) {
+ map.add_new(i, i);
+ }
+ for (int i = 25; i < 80; i++) {
+ EXPECT_EQ(map.pop(i), i);
+ }
+ for (int i = 0; i < 100; i++) {
+ EXPECT_EQ(map.contains(i), i < 25 || i >= 80);
+ }
+}
+
+TEST(map, ValueIterator)
+{
+ Map<int, float> map;
+ map.add(3, 5.0f);
+ map.add(1, 2.0f);
+ map.add(7, -2.0f);
+
+ blender::Set<float> values;
+
+ int iterations = 0;
+ for (float value : map.values()) {
+ values.add(value);
+ iterations++;
+ }
+
+ EXPECT_EQ(iterations, 3);
+ EXPECT_TRUE(values.contains(5.0f));
+ EXPECT_TRUE(values.contains(-2.0f));
+ EXPECT_TRUE(values.contains(2.0f));
+}
+
+TEST(map, KeyIterator)
+{
+ Map<int, float> map;
+ map.add(6, 3.0f);
+ map.add(2, 4.0f);
+ map.add(1, 3.0f);
+
+ blender::Set<int> keys;
+
+ int iterations = 0;
+ for (int key : map.keys()) {
+ keys.add(key);
+ iterations++;
+ }
+
+ EXPECT_EQ(iterations, 3);
+ EXPECT_TRUE(keys.contains(1));
+ EXPECT_TRUE(keys.contains(2));
+ EXPECT_TRUE(keys.contains(6));
+}
+
+TEST(map, ItemIterator)
+{
+ Map<int, float> map;
+ map.add(5, 3.0f);
+ map.add(2, 9.0f);
+ map.add(1, 0.0f);
+
+ blender::Set<int> keys;
+ blender::Set<float> values;
+
+ int iterations = 0;
+ const Map<int, float> &const_map = map;
+ for (auto item : const_map.items()) {
+ keys.add(item.key);
+ values.add(item.value);
+ iterations++;
+ }
+
+ EXPECT_EQ(iterations, 3);
+ EXPECT_TRUE(keys.contains(5));
+ EXPECT_TRUE(keys.contains(2));
+ EXPECT_TRUE(keys.contains(1));
+ EXPECT_TRUE(values.contains(3.0f));
+ EXPECT_TRUE(values.contains(9.0f));
+ EXPECT_TRUE(values.contains(0.0f));
+}
+
+TEST(map, MutableValueIterator)
+{
+ Map<int, int> map;
+ map.add(3, 6);
+ map.add(2, 1);
+
+ for (int &value : map.values()) {
+ value += 10;
+ }
+
+ EXPECT_EQ(map.lookup(3), 16);
+ EXPECT_EQ(map.lookup(2), 11);
+}
+
+TEST(map, MutableItemIterator)
+{
+ Map<int, int> map;
+ map.add(3, 6);
+ map.add(2, 1);
+
+ for (auto item : map.items()) {
+ item.value += item.key;
+ }
+
+ EXPECT_EQ(map.lookup(3), 9.0f);
+ EXPECT_EQ(map.lookup(2), 3.0f);
+}
+
+TEST(map, MutableItemToItemConversion)
+{
+ Map<int, int> map;
+ map.add(3, 6);
+ map.add(2, 1);
+
+ Vector<int> keys, values;
+ for (Map<int, int>::Item item : map.items()) {
+ keys.append(item.key);
+ values.append(item.value);
+ }
+
+ EXPECT_EQ(keys.size(), 2);
+ EXPECT_EQ(values.size(), 2);
+ EXPECT_TRUE(keys.contains(3));
+ EXPECT_TRUE(keys.contains(2));
+ EXPECT_TRUE(values.contains(6));
+ EXPECT_TRUE(values.contains(1));
+}
+
+static float return_42()
+{
+ return 42.0f;
+}
+
+TEST(map, LookupOrAddCB_SeparateFunction)
+{
+ Map<int, float> map;
+ EXPECT_EQ(map.lookup_or_add_cb(0, return_42), 42.0f);
+ EXPECT_EQ(map.lookup(0), 42);
+
+ map.keys();
+}
+
+TEST(map, LookupOrAddCB_Lambdas)
+{
+ Map<int, float> map;
+ auto lambda1 = []() { return 11.0f; };
+ EXPECT_EQ(map.lookup_or_add_cb(0, lambda1), 11.0f);
+ auto lambda2 = []() { return 20.0f; };
+ EXPECT_EQ(map.lookup_or_add_cb(1, lambda2), 20.0f);
+
+ EXPECT_EQ(map.lookup_or_add_cb(0, lambda2), 11.0f);
+ EXPECT_EQ(map.lookup_or_add_cb(1, lambda1), 20.0f);
+}
+
+TEST(map, AddOrModify)
+{
+ Map<int, float> map;
+ auto create_func = [](float *value) {
+ *value = 10.0f;
+ return true;
+ };
+ auto modify_func = [](float *value) {
+ *value += 5;
+ return false;
+ };
+ EXPECT_TRUE(map.add_or_modify(1, create_func, modify_func));
+ EXPECT_EQ(map.lookup(1), 10.0f);
+ EXPECT_FALSE(map.add_or_modify(1, create_func, modify_func));
+ EXPECT_EQ(map.lookup(1), 15.0f);
+}
+
+TEST(map, AddOverwrite)
+{
+ Map<int, float> map;
+ EXPECT_FALSE(map.contains(3));
+ EXPECT_TRUE(map.add_overwrite(3, 6.0f));
+ EXPECT_EQ(map.lookup(3), 6.0f);
+ EXPECT_FALSE(map.add_overwrite(3, 7.0f));
+ EXPECT_EQ(map.lookup(3), 7.0f);
+ EXPECT_FALSE(map.add(3, 8.0f));
+ EXPECT_EQ(map.lookup(3), 7.0f);
+}
+
+TEST(map, LookupOrAddDefault)
+{
+ Map<int, float> map;
+ map.lookup_or_add_default(3) = 6;
+ EXPECT_EQ(map.lookup(3), 6);
+ map.lookup_or_add_default(5) = 2;
+ EXPECT_EQ(map.lookup(5), 2);
+ map.lookup_or_add_default(3) += 4;
+ EXPECT_EQ(map.lookup(3), 10);
+}
+
+TEST(map, LookupOrAdd)
+{
+ Map<int, int> map;
+ EXPECT_EQ(map.lookup_or_add(6, 4), 4);
+ EXPECT_EQ(map.lookup_or_add(6, 5), 4);
+ map.lookup_or_add(6, 4) += 10;
+ EXPECT_EQ(map.lookup(6), 14);
+}
+
+TEST(map, MoveConstructorSmall)
+{
+ Map<int, float> map1;
+ map1.add(1, 2.0f);
+ map1.add(4, 1.0f);
+ Map<int, float> map2(std::move(map1));
+ EXPECT_EQ(map2.size(), 2);
+ EXPECT_EQ(map2.lookup(1), 2.0f);
+ EXPECT_EQ(map2.lookup(4), 1.0f);
+ EXPECT_EQ(map1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(map1.lookup_ptr(4), nullptr);
+}
+
+TEST(map, MoveConstructorLarge)
+{
+ Map<int, int> map1;
+ for (int i = 0; i < 100; i++) {
+ map1.add_new(i, i);
+ }
+ Map<int, int> map2(std::move(map1));
+ EXPECT_EQ(map2.size(), 100);
+ EXPECT_EQ(map2.lookup(1), 1);
+ EXPECT_EQ(map2.lookup(4), 4);
+ EXPECT_EQ(map1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(map1.lookup_ptr(4), nullptr);
+}
+
+TEST(map, MoveAssignment)
+{
+ Map<int, float> map1;
+ map1.add(1, 2.0f);
+ map1.add(4, 1.0f);
+ Map<int, float> map2;
+ map2 = std::move(map1);
+ EXPECT_EQ(map2.size(), 2);
+ EXPECT_EQ(map2.lookup(1), 2.0f);
+ EXPECT_EQ(map2.lookup(4), 1.0f);
+ EXPECT_EQ(map1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(map1.lookup_ptr(4), nullptr);
+}
+
+TEST(map, CopyAssignment)
+{
+ Map<int, float> map1;
+ map1.add(1, 2.0f);
+ map1.add(4, 1.0f);
+ Map<int, float> map2;
+ map2 = map1;
+ EXPECT_EQ(map2.size(), 2);
+ EXPECT_EQ(map2.lookup(1), 2.0f);
+ EXPECT_EQ(map2.lookup(4), 1.0f);
+ EXPECT_EQ(map1.size(), 2);
+ EXPECT_EQ(*map1.lookup_ptr(4), 1.0f);
+}
+
+TEST(map, Clear)
+{
+ Map<int, float> map;
+ map.add(1, 1.0f);
+ map.add(2, 5.0f);
+
+ EXPECT_EQ(map.size(), 2);
+ EXPECT_TRUE(map.contains(1));
+ EXPECT_TRUE(map.contains(2));
+
+ map.clear();
+
+ EXPECT_EQ(map.size(), 0);
+ EXPECT_FALSE(map.contains(1));
+ EXPECT_FALSE(map.contains(2));
+}
+
+TEST(map, UniquePtrValue)
+{
+ auto value1 = std::unique_ptr<int>(new int());
+ auto value2 = std::unique_ptr<int>(new int());
+ auto value3 = std::unique_ptr<int>(new int());
+
+ int *value1_ptr = value1.get();
+
+ Map<int, std::unique_ptr<int>> map;
+ map.add_new(1, std::move(value1));
+ map.add(2, std::move(value2));
+ map.add_overwrite(3, std::move(value3));
+ map.lookup_or_add_cb(4, []() { return std::unique_ptr<int>(new int()); });
+ map.add_new(5, std::unique_ptr<int>(new int()));
+ map.add(6, std::unique_ptr<int>(new int()));
+ map.add_overwrite(7, std::unique_ptr<int>(new int()));
+ map.lookup_or_add(8, std::unique_ptr<int>(new int()));
+ map.pop_default(9, std::unique_ptr<int>(new int()));
+
+ EXPECT_EQ(map.lookup(1).get(), value1_ptr);
+ EXPECT_EQ(map.lookup_ptr(100), nullptr);
+}
+
+TEST(map, Remove)
+{
+ Map<int, int> map;
+ map.add(2, 4);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_FALSE(map.remove(3));
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_TRUE(map.remove(2));
+ EXPECT_EQ(map.size(), 0);
+}
+
+TEST(map, PointerKeys)
+{
+ char a, b, c, d;
+
+ Map<char *, int> map;
+ EXPECT_TRUE(map.add(&a, 5));
+ EXPECT_FALSE(map.add(&a, 4));
+ map.add_new(&b, 1);
+ map.add_new(&c, 1);
+ EXPECT_EQ(map.size(), 3);
+ EXPECT_TRUE(map.remove(&b));
+ EXPECT_TRUE(map.add(&b, 8));
+ EXPECT_FALSE(map.remove(&d));
+ EXPECT_TRUE(map.remove(&a));
+ EXPECT_TRUE(map.remove(&b));
+ EXPECT_TRUE(map.remove(&c));
+ EXPECT_TRUE(map.is_empty());
+}
+
+TEST(map, ConstKeysAndValues)
+{
+ Map<const std::string, const std::string> map;
+ map.reserve(10);
+ map.add("45", "643");
+ EXPECT_TRUE(map.contains("45"));
+ EXPECT_FALSE(map.contains("54"));
+}
+
+TEST(map, ForeachItem)
+{
+ Map<int, int> map;
+ map.add(3, 4);
+ map.add(1, 8);
+
+ Vector<int> keys;
+ Vector<int> values;
+ map.foreach_item([&](int key, int value) {
+ keys.append(key);
+ values.append(value);
+ });
+
+ EXPECT_EQ(keys.size(), 2);
+ EXPECT_EQ(values.size(), 2);
+ EXPECT_EQ(keys.first_index_of(3), values.first_index_of(4));
+ EXPECT_EQ(keys.first_index_of(1), values.first_index_of(8));
+}
+
+/**
+ * Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot.
+ */
+#if 0
+template<typename MapT>
+BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor)
+{
+ RNG *rng = BLI_rng_new(0);
+ Vector<int> values;
+ for (int i = 0; i < amount; i++) {
+ values.append(BLI_rng_get_int(rng) * factor);
+ }
+ BLI_rng_free(rng);
+
+ MapT map;
+ {
+ SCOPED_TIMER(name + " Add");
+ for (int value : values) {
+ map.add(value, value);
+ }
+ }
+ int count = 0;
+ {
+ SCOPED_TIMER(name + " Contains");
+ for (int value : values) {
+ count += map.contains(value);
+ }
+ }
+ {
+ SCOPED_TIMER(name + " Remove");
+ for (int value : values) {
+ count += map.remove(value);
+ }
+ }
+
+ /* Print the value for simple error checking and to avoid some compiler optimizations. */
+ std::cout << "Count: " << count << "\n";
+}
+
+TEST(map, Benchmark)
+{
+ for (int i = 0; i < 3; i++) {
+ benchmark_random_ints<blender::Map<int, int>>("blender::Map ", 1000000, 1);
+ benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>("std::unordered_map", 1000000, 1);
+ }
+ std::cout << "\n";
+ for (int i = 0; i < 3; i++) {
+ uint32_t factor = (3 << 10);
+ benchmark_random_ints<blender::Map<int, int>>("blender::Map ", 1000000, factor);
+ benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>(
+ "std::unordered_map", 1000000, factor);
+ }
+}
+
+/**
+ * Timer 'blender::Map Add' took 61.7616 ms
+ * Timer 'blender::Map Contains' took 18.4989 ms
+ * Timer 'blender::Map Remove' took 20.5864 ms
+ * Count: 1999755
+ * Timer 'std::unordered_map Add' took 188.674 ms
+ * Timer 'std::unordered_map Contains' took 44.3741 ms
+ * Timer 'std::unordered_map Remove' took 169.52 ms
+ * Count: 1999755
+ * Timer 'blender::Map Add' took 37.9196 ms
+ * Timer 'blender::Map Contains' took 16.7361 ms
+ * Timer 'blender::Map Remove' took 20.9568 ms
+ * Count: 1999755
+ * Timer 'std::unordered_map Add' took 166.09 ms
+ * Timer 'std::unordered_map Contains' took 40.6133 ms
+ * Timer 'std::unordered_map Remove' took 142.85 ms
+ * Count: 1999755
+ * Timer 'blender::Map Add' took 37.3053 ms
+ * Timer 'blender::Map Contains' took 16.6731 ms
+ * Timer 'blender::Map Remove' took 18.8304 ms
+ * Count: 1999755
+ * Timer 'std::unordered_map Add' took 170.964 ms
+ * Timer 'std::unordered_map Contains' took 38.1824 ms
+ * Timer 'std::unordered_map Remove' took 140.263 ms
+ * Count: 1999755
+ *
+ * Timer 'blender::Map Add' took 50.1131 ms
+ * Timer 'blender::Map Contains' took 25.0491 ms
+ * Timer 'blender::Map Remove' took 32.4225 ms
+ * Count: 1889920
+ * Timer 'std::unordered_map Add' took 150.129 ms
+ * Timer 'std::unordered_map Contains' took 34.6999 ms
+ * Timer 'std::unordered_map Remove' took 120.907 ms
+ * Count: 1889920
+ * Timer 'blender::Map Add' took 50.4438 ms
+ * Timer 'blender::Map Contains' took 25.2677 ms
+ * Timer 'blender::Map Remove' took 32.3047 ms
+ * Count: 1889920
+ * Timer 'std::unordered_map Add' took 144.015 ms
+ * Timer 'std::unordered_map Contains' took 36.3387 ms
+ * Timer 'std::unordered_map Remove' took 119.109 ms
+ * Count: 1889920
+ * Timer 'blender::Map Add' took 48.6995 ms
+ * Timer 'blender::Map Contains' took 25.1846 ms
+ * Timer 'blender::Map Remove' took 33.0283 ms
+ * Count: 1889920
+ * Timer 'std::unordered_map Add' took 143.494 ms
+ * Timer 'std::unordered_map Contains' took 34.8905 ms
+ * Timer 'std::unordered_map Remove' took 122.739 ms
+ * Count: 1889920
+ */
+
+#endif /* Benchmark */
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_math_base_safe_test.cc b/source/blender/blenlib/tests/BLI_math_base_safe_test.cc
new file mode 100644
index 00000000000..2e3e083cf92
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_math_base_safe_test.cc
@@ -0,0 +1,37 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "BLI_math_base_safe.h"
+
+TEST(math_base, SafePowf)
+{
+ EXPECT_FLOAT_EQ(safe_powf(4.0f, 3.0f), 64.0f);
+ EXPECT_FLOAT_EQ(safe_powf(3.2f, 5.6f), 674.2793796f);
+ EXPECT_FLOAT_EQ(safe_powf(4.0f, -2.0f), 0.0625f);
+ EXPECT_FLOAT_EQ(safe_powf(6.0f, -3.2f), 0.003235311f);
+ EXPECT_FLOAT_EQ(safe_powf(-4.0f, 6), 4096.0f);
+ EXPECT_FLOAT_EQ(safe_powf(-3.0f, 5.5), 0.0f);
+ EXPECT_FLOAT_EQ(safe_powf(-2.5f, -4.0f), 0.0256f);
+ EXPECT_FLOAT_EQ(safe_powf(-3.7f, -4.5f), 0.0f);
+}
+
+TEST(math_base, SafeModf)
+{
+ EXPECT_FLOAT_EQ(safe_modf(3.4, 2.2f), 1.2f);
+ EXPECT_FLOAT_EQ(safe_modf(3.4, -2.2f), 1.2f);
+ EXPECT_FLOAT_EQ(safe_modf(-3.4, -2.2f), -1.2f);
+ EXPECT_FLOAT_EQ(safe_modf(-3.4, 0.0f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_modf(0.0f, 3.0f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_modf(55.0f, 10.0f), 5.0f);
+}
+
+TEST(math_base, SafeLogf)
+{
+ EXPECT_FLOAT_EQ(safe_logf(3.3f, 2.5f), 1.302995247f);
+ EXPECT_FLOAT_EQ(safe_logf(0.0f, 3.0f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_logf(3.0f, 0.0f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_logf(-2.0f, 4.3f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_logf(2.0f, -4.3f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_logf(-2.0f, -4.3f), 0.0f);
+}
diff --git a/source/blender/blenlib/tests/BLI_memory_utils_test.cc b/source/blender/blenlib/tests/BLI_memory_utils_test.cc
new file mode 100644
index 00000000000..f3cb02b63d7
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_memory_utils_test.cc
@@ -0,0 +1,159 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_float3.hh"
+#include "BLI_memory_utils.hh"
+#include "BLI_strict_flags.h"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+struct MyValue {
+ static inline int alive = 0;
+
+ MyValue()
+ {
+ if (alive == 15) {
+ throw std::exception();
+ }
+
+ alive++;
+ }
+
+ MyValue(const MyValue &UNUSED(other))
+ {
+ if (alive == 15) {
+ throw std::exception();
+ }
+
+ alive++;
+ }
+
+ ~MyValue()
+ {
+ alive--;
+ }
+};
+
+TEST(memory_utils, DefaultConstructN_ActuallyCallsConstructor)
+{
+ constexpr int amount = 10;
+ TypedBuffer<MyValue, amount> buffer;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ default_construct_n(buffer.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, amount);
+ destruct_n(buffer.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, DefaultConstructN_StrongExceptionSafety)
+{
+ constexpr int amount = 20;
+ TypedBuffer<MyValue, amount> buffer;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ EXPECT_THROW(default_construct_n(buffer.ptr(), amount), std::exception);
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, UninitializedCopyN_ActuallyCopies)
+{
+ constexpr int amount = 5;
+ TypedBuffer<MyValue, amount> buffer1;
+ TypedBuffer<MyValue, amount> buffer2;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ default_construct_n(buffer1.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, amount);
+ uninitialized_copy_n(buffer1.ptr(), amount, buffer2.ptr());
+ EXPECT_EQ(MyValue::alive, 2 * amount);
+ destruct_n(buffer1.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, amount);
+ destruct_n(buffer2.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, UninitializedCopyN_StrongExceptionSafety)
+{
+ constexpr int amount = 10;
+ TypedBuffer<MyValue, amount> buffer1;
+ TypedBuffer<MyValue, amount> buffer2;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ default_construct_n(buffer1.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, amount);
+ EXPECT_THROW(uninitialized_copy_n(buffer1.ptr(), amount, buffer2.ptr()), std::exception);
+ EXPECT_EQ(MyValue::alive, amount);
+ destruct_n(buffer1.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, UninitializedFillN_ActuallyCopies)
+{
+ constexpr int amount = 10;
+ TypedBuffer<MyValue, amount> buffer;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ {
+ MyValue value;
+ EXPECT_EQ(MyValue::alive, 1);
+ uninitialized_fill_n(buffer.ptr(), amount, value);
+ EXPECT_EQ(MyValue::alive, 1 + amount);
+ destruct_n(buffer.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, 1);
+ }
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, UninitializedFillN_StrongExceptionSafety)
+{
+ constexpr int amount = 20;
+ TypedBuffer<MyValue, amount> buffer;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ {
+ MyValue value;
+ EXPECT_EQ(MyValue::alive, 1);
+ EXPECT_THROW(uninitialized_fill_n(buffer.ptr(), amount, value), std::exception);
+ EXPECT_EQ(MyValue::alive, 1);
+ }
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+class TestBaseClass {
+ virtual void mymethod(){};
+};
+
+class TestChildClass : public TestBaseClass {
+ void mymethod() override
+ {
+ }
+};
+
+static_assert(is_convertible_pointer_v<int *, int *>);
+static_assert(is_convertible_pointer_v<int *, const int *>);
+static_assert(is_convertible_pointer_v<int *, int *const>);
+static_assert(is_convertible_pointer_v<int *, const int *const>);
+static_assert(!is_convertible_pointer_v<const int *, int *>);
+static_assert(!is_convertible_pointer_v<int, int *>);
+static_assert(!is_convertible_pointer_v<int *, int>);
+static_assert(is_convertible_pointer_v<TestBaseClass *, const TestBaseClass *>);
+static_assert(!is_convertible_pointer_v<const TestBaseClass *, TestBaseClass *>);
+static_assert(is_convertible_pointer_v<TestChildClass *, TestBaseClass *>);
+static_assert(!is_convertible_pointer_v<TestBaseClass *, TestChildClass *>);
+static_assert(is_convertible_pointer_v<const TestChildClass *, const TestBaseClass *>);
+static_assert(!is_convertible_pointer_v<TestBaseClass, const TestChildClass *>);
+static_assert(!is_convertible_pointer_v<float3, float *>);
+static_assert(!is_convertible_pointer_v<float *, float3>);
+static_assert(!is_convertible_pointer_v<int **, int *>);
+static_assert(!is_convertible_pointer_v<int *, int **>);
+static_assert(is_convertible_pointer_v<int **, int **>);
+static_assert(is_convertible_pointer_v<const int **, const int **>);
+static_assert(!is_convertible_pointer_v<const int **, int **>);
+static_assert(!is_convertible_pointer_v<int *const *, int **>);
+static_assert(!is_convertible_pointer_v<int *const *const, int **>);
+static_assert(is_convertible_pointer_v<int **, int **const>);
+static_assert(is_convertible_pointer_v<int **, int *const *>);
+static_assert(is_convertible_pointer_v<int **, int const *const *>);
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_multi_value_map_test.cc b/source/blender/blenlib/tests/BLI_multi_value_map_test.cc
new file mode 100644
index 00000000000..7501fbe0d87
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_multi_value_map_test.cc
@@ -0,0 +1,109 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_multi_value_map.hh"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(multi_value_map, LookupNotExistant)
+{
+ MultiValueMap<int, int> map;
+ EXPECT_EQ(map.lookup(5).size(), 0);
+ map.add(2, 5);
+ EXPECT_EQ(map.lookup(5).size(), 0);
+}
+
+TEST(multi_value_map, LookupExistant)
+{
+ MultiValueMap<int, int> map;
+ map.add(2, 4);
+ map.add(2, 5);
+ map.add(3, 6);
+
+ EXPECT_EQ(map.lookup(2).size(), 2);
+ EXPECT_EQ(map.lookup(2)[0], 4);
+ EXPECT_EQ(map.lookup(2)[1], 5);
+
+ EXPECT_EQ(map.lookup(3).size(), 1);
+ EXPECT_EQ(map.lookup(3)[0], 6);
+}
+
+TEST(multi_value_map, AddMultiple)
+{
+ MultiValueMap<int, int> map;
+ map.add_multiple(2, {4, 5, 6});
+ map.add_multiple(2, {1, 2});
+ map.add_multiple(5, {7, 5, 3});
+
+ EXPECT_EQ(map.lookup(2).size(), 5);
+ EXPECT_EQ(map.lookup(2)[0], 4);
+ EXPECT_EQ(map.lookup(2)[1], 5);
+ EXPECT_EQ(map.lookup(2)[2], 6);
+ EXPECT_EQ(map.lookup(2)[3], 1);
+ EXPECT_EQ(map.lookup(2)[4], 2);
+
+ EXPECT_EQ(map.lookup(5).size(), 3);
+ EXPECT_EQ(map.lookup(5)[0], 7);
+ EXPECT_EQ(map.lookup(5)[1], 5);
+ EXPECT_EQ(map.lookup(5)[2], 3);
+}
+
+TEST(multi_value_map, Keys)
+{
+ MultiValueMap<int, int> map;
+ map.add(5, 7);
+ map.add(5, 7);
+ map.add_multiple(2, {6, 7, 8});
+
+ Vector<int> keys;
+ for (int key : map.keys()) {
+ keys.append(key);
+ }
+
+ EXPECT_EQ(keys.size(), 2);
+ EXPECT_TRUE(keys.contains(5));
+ EXPECT_TRUE(keys.contains(2));
+}
+
+TEST(multi_value_map, Values)
+{
+ MultiValueMap<int, int> map;
+ map.add(3, 5);
+ map.add_multiple(3, {1, 2});
+ map.add(6, 1);
+
+ Vector<Span<int>> values;
+ for (Span<int> value_span : map.values()) {
+ values.append(value_span);
+ }
+
+ EXPECT_EQ(values.size(), 2);
+}
+
+TEST(multi_value_map, Items)
+{
+ MultiValueMap<int, int> map;
+ map.add_multiple(4, {1, 2, 3});
+
+ for (auto &&item : map.items()) {
+ int key = item.key;
+ Span<int> values = item.value;
+ EXPECT_EQ(key, 4);
+ EXPECT_EQ(values.size(), 3);
+ EXPECT_EQ(values[0], 1);
+ EXPECT_EQ(values[1], 2);
+ EXPECT_EQ(values[2], 3);
+ }
+}
+
+TEST(multi_value_map, UniquePtr)
+{
+ /* Mostly testing if it compiles here. */
+ MultiValueMap<std::unique_ptr<int>, std::unique_ptr<int>> map;
+ map.add(std::make_unique<int>(4), std::make_unique<int>(6));
+ map.add(std::make_unique<int>(4), std::make_unique<int>(7));
+ EXPECT_EQ(map.lookup(std::make_unique<int>(10)).size(), 0);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_set_test.cc b/source/blender/blenlib/tests/BLI_set_test.cc
new file mode 100644
index 00000000000..7bd0b258df8
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_set_test.cc
@@ -0,0 +1,565 @@
+/* Apache License, Version 2.0 */
+
+#include <set>
+#include <unordered_set>
+
+#include "BLI_ghash.h"
+#include "BLI_rand.h"
+#include "BLI_set.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_timeit.hh"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender {
+namespace tests {
+
+TEST(set, DefaultConstructor)
+{
+ Set<int> set;
+ EXPECT_EQ(set.size(), 0);
+ EXPECT_TRUE(set.is_empty());
+}
+
+TEST(set, ContainsNotExistant)
+{
+ Set<int> set;
+ EXPECT_FALSE(set.contains(3));
+}
+
+TEST(set, ContainsExistant)
+{
+ Set<int> set;
+ EXPECT_FALSE(set.contains(5));
+ EXPECT_TRUE(set.is_empty());
+ set.add(5);
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_FALSE(set.is_empty());
+}
+
+TEST(set, AddMany)
+{
+ Set<int> set;
+ for (int i = 0; i < 100; i++) {
+ set.add(i);
+ }
+
+ for (int i = 50; i < 100; i++) {
+ EXPECT_TRUE(set.contains(i));
+ }
+ for (int i = 100; i < 150; i++) {
+ EXPECT_FALSE(set.contains(i));
+ }
+}
+
+TEST(set, InitializerListConstructor)
+{
+ Set<int> set = {4, 5, 6};
+ EXPECT_EQ(set.size(), 3);
+ EXPECT_TRUE(set.contains(4));
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_TRUE(set.contains(6));
+ EXPECT_FALSE(set.contains(2));
+ EXPECT_FALSE(set.contains(3));
+}
+
+TEST(set, CopyConstructor)
+{
+ Set<int> set = {3};
+ EXPECT_TRUE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+
+ Set<int> set2(set);
+ set2.add(4);
+ EXPECT_TRUE(set2.contains(3));
+ EXPECT_TRUE(set2.contains(4));
+
+ EXPECT_FALSE(set.contains(4));
+}
+
+TEST(set, MoveConstructor)
+{
+ Set<int> set = {1, 2, 3};
+ EXPECT_EQ(set.size(), 3);
+ Set<int> set2(std::move(set));
+ EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(set2.size(), 3);
+}
+
+TEST(set, CopyAssignment)
+{
+ Set<int> set = {3};
+ EXPECT_TRUE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+
+ Set<int> set2;
+ set2 = set;
+ set2.add(4);
+ EXPECT_TRUE(set2.contains(3));
+ EXPECT_TRUE(set2.contains(4));
+
+ EXPECT_FALSE(set.contains(4));
+}
+
+TEST(set, MoveAssignment)
+{
+ Set<int> set = {1, 2, 3};
+ EXPECT_EQ(set.size(), 3);
+ Set<int> set2;
+ set2 = std::move(set);
+ EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(set2.size(), 3);
+}
+
+TEST(set, RemoveContained)
+{
+ Set<int> set = {3, 4, 5};
+ EXPECT_TRUE(set.contains(3));
+ EXPECT_TRUE(set.contains(4));
+ EXPECT_TRUE(set.contains(5));
+ set.remove_contained(4);
+ EXPECT_TRUE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+ EXPECT_TRUE(set.contains(5));
+ set.remove_contained(3);
+ EXPECT_FALSE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+ EXPECT_TRUE(set.contains(5));
+ set.remove_contained(5);
+ EXPECT_FALSE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+ EXPECT_FALSE(set.contains(5));
+}
+
+TEST(set, RemoveContainedMany)
+{
+ Set<int> set;
+ for (int i = 0; i < 1000; i++) {
+ set.add(i);
+ }
+ for (int i = 100; i < 1000; i++) {
+ set.remove_contained(i);
+ }
+ for (int i = 900; i < 1000; i++) {
+ set.add(i);
+ }
+
+ for (int i = 0; i < 1000; i++) {
+ if (i < 100 || i >= 900) {
+ EXPECT_TRUE(set.contains(i));
+ }
+ else {
+ EXPECT_FALSE(set.contains(i));
+ }
+ }
+}
+
+TEST(set, Intersects)
+{
+ Set<int> a = {3, 4, 5, 6};
+ Set<int> b = {1, 2, 5};
+ EXPECT_TRUE(Set<int>::Intersects(a, b));
+ EXPECT_FALSE(Set<int>::Disjoint(a, b));
+}
+
+TEST(set, Disjoint)
+{
+ Set<int> a = {5, 6, 7, 8};
+ Set<int> b = {2, 3, 4, 9};
+ EXPECT_FALSE(Set<int>::Intersects(a, b));
+ EXPECT_TRUE(Set<int>::Disjoint(a, b));
+}
+
+TEST(set, AddMultiple)
+{
+ Set<int> a;
+ a.add_multiple({5, 7});
+ EXPECT_TRUE(a.contains(5));
+ EXPECT_TRUE(a.contains(7));
+ EXPECT_FALSE(a.contains(4));
+ a.add_multiple({2, 4, 7});
+ EXPECT_TRUE(a.contains(4));
+ EXPECT_TRUE(a.contains(2));
+ EXPECT_EQ(a.size(), 4);
+}
+
+TEST(set, AddMultipleNew)
+{
+ Set<int> a;
+ a.add_multiple_new({5, 6});
+ EXPECT_TRUE(a.contains(5));
+ EXPECT_TRUE(a.contains(6));
+}
+
+TEST(set, Iterator)
+{
+ Set<int> set = {1, 3, 2, 5, 4};
+ blender::Vector<int> vec;
+ for (int value : set) {
+ vec.append(value);
+ }
+ EXPECT_EQ(vec.size(), 5);
+ EXPECT_TRUE(vec.contains(1));
+ EXPECT_TRUE(vec.contains(3));
+ EXPECT_TRUE(vec.contains(2));
+ EXPECT_TRUE(vec.contains(5));
+ EXPECT_TRUE(vec.contains(4));
+}
+
+TEST(set, OftenAddRemoveContained)
+{
+ Set<int> set;
+ for (int i = 0; i < 100; i++) {
+ set.add(42);
+ EXPECT_EQ(set.size(), 1);
+ set.remove_contained(42);
+ EXPECT_EQ(set.size(), 0);
+ }
+}
+
+TEST(set, UniquePtrValues)
+{
+ Set<std::unique_ptr<int>> set;
+ set.add_new(std::unique_ptr<int>(new int()));
+ auto value1 = std::unique_ptr<int>(new int());
+ set.add_new(std::move(value1));
+ set.add(std::unique_ptr<int>(new int()));
+
+ EXPECT_EQ(set.size(), 3);
+}
+
+TEST(set, Clear)
+{
+ Set<int> set = {3, 4, 6, 7};
+ EXPECT_EQ(set.size(), 4);
+ set.clear();
+ EXPECT_EQ(set.size(), 0);
+}
+
+TEST(set, StringSet)
+{
+ Set<std::string> set;
+ set.add("hello");
+ set.add("world");
+ EXPECT_EQ(set.size(), 2);
+ EXPECT_TRUE(set.contains("hello"));
+ EXPECT_TRUE(set.contains("world"));
+ EXPECT_FALSE(set.contains("world2"));
+}
+
+TEST(set, PointerSet)
+{
+ int a, b, c;
+ Set<int *> set;
+ set.add(&a);
+ set.add(&b);
+ EXPECT_EQ(set.size(), 2);
+ EXPECT_TRUE(set.contains(&a));
+ EXPECT_TRUE(set.contains(&b));
+ EXPECT_FALSE(set.contains(&c));
+}
+
+TEST(set, Remove)
+{
+ Set<int> set = {1, 2, 3, 4, 5, 6};
+ EXPECT_EQ(set.size(), 6);
+ EXPECT_TRUE(set.remove(2));
+ EXPECT_EQ(set.size(), 5);
+ EXPECT_FALSE(set.contains(2));
+ EXPECT_FALSE(set.remove(2));
+ EXPECT_EQ(set.size(), 5);
+ EXPECT_TRUE(set.remove(5));
+ EXPECT_EQ(set.size(), 4);
+}
+
+struct Type1 {
+ uint32_t value;
+};
+
+struct Type2 {
+ uint32_t value;
+};
+
+static bool operator==(const Type1 &a, const Type1 &b)
+{
+ return a.value == b.value;
+}
+static bool operator==(const Type2 &a, const Type1 &b)
+{
+ return a.value == b.value;
+}
+
+} // namespace tests
+
+/* This has to be defined in ::blender namespace. */
+template<> struct DefaultHash<tests::Type1> {
+ uint32_t operator()(const tests::Type1 &value) const
+ {
+ return value.value;
+ }
+
+ uint32_t operator()(const tests::Type2 &value) const
+ {
+ return value.value;
+ }
+};
+
+namespace tests {
+
+TEST(set, ContainsAs)
+{
+ Set<Type1> set;
+ set.add(Type1{5});
+ EXPECT_TRUE(set.contains_as(Type1{5}));
+ EXPECT_TRUE(set.contains_as(Type2{5}));
+ EXPECT_FALSE(set.contains_as(Type1{6}));
+ EXPECT_FALSE(set.contains_as(Type2{6}));
+}
+
+TEST(set, ContainsAsString)
+{
+ Set<std::string> set;
+ set.add("test");
+ EXPECT_TRUE(set.contains_as("test"));
+ EXPECT_TRUE(set.contains_as(StringRef("test")));
+ EXPECT_FALSE(set.contains_as("string"));
+ EXPECT_FALSE(set.contains_as(StringRef("string")));
+}
+
+TEST(set, RemoveContainedAs)
+{
+ Set<Type1> set;
+ set.add(Type1{5});
+ EXPECT_TRUE(set.contains_as(Type2{5}));
+ set.remove_contained_as(Type2{5});
+ EXPECT_FALSE(set.contains_as(Type2{5}));
+}
+
+TEST(set, RemoveAs)
+{
+ Set<Type1> set;
+ set.add(Type1{5});
+ EXPECT_TRUE(set.contains_as(Type2{5}));
+ set.remove_as(Type2{6});
+ EXPECT_TRUE(set.contains_as(Type2{5}));
+ set.remove_as(Type2{5});
+ EXPECT_FALSE(set.contains_as(Type2{5}));
+ set.remove_as(Type2{5});
+ EXPECT_FALSE(set.contains_as(Type2{5}));
+}
+
+TEST(set, AddAs)
+{
+ Set<std::string> set;
+ EXPECT_TRUE(set.add_as("test"));
+ EXPECT_TRUE(set.add_as(StringRef("qwe")));
+ EXPECT_FALSE(set.add_as(StringRef("test")));
+ EXPECT_FALSE(set.add_as("qwe"));
+}
+
+template<uint N> struct EqualityIntModN {
+ bool operator()(uint a, uint b) const
+ {
+ return (a % N) == (b % N);
+ }
+};
+
+template<uint N> struct HashIntModN {
+ uint64_t operator()(uint value) const
+ {
+ return value % N;
+ }
+};
+
+TEST(set, CustomizeHashAndEquality)
+{
+ Set<uint, 0, DefaultProbingStrategy, HashIntModN<10>, EqualityIntModN<10>> set;
+ set.add(4);
+ EXPECT_TRUE(set.contains(4));
+ EXPECT_TRUE(set.contains(14));
+ EXPECT_TRUE(set.contains(104));
+ EXPECT_FALSE(set.contains(5));
+ set.add(55);
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_TRUE(set.contains(14));
+ set.remove(1004);
+ EXPECT_FALSE(set.contains(14));
+}
+
+TEST(set, IntrusiveIntKey)
+{
+ Set<int,
+ 2,
+ DefaultProbingStrategy,
+ DefaultHash<int>,
+ DefaultEquality,
+ IntegerSetSlot<int, 100, 200>>
+ set;
+ EXPECT_TRUE(set.add(4));
+ EXPECT_TRUE(set.add(3));
+ EXPECT_TRUE(set.add(11));
+ EXPECT_TRUE(set.add(8));
+ EXPECT_FALSE(set.add(3));
+ EXPECT_FALSE(set.add(4));
+ EXPECT_TRUE(set.remove(4));
+ EXPECT_FALSE(set.remove(7));
+ EXPECT_TRUE(set.add(4));
+ EXPECT_TRUE(set.remove(4));
+}
+
+struct MyKeyType {
+ uint32_t key;
+ int32_t attached_data;
+
+ uint64_t hash() const
+ {
+ return key;
+ }
+
+ friend bool operator==(const MyKeyType &a, const MyKeyType &b)
+ {
+ return a.key == b.key;
+ }
+};
+
+TEST(set, LookupKey)
+{
+ Set<MyKeyType> set;
+ set.add({1, 10});
+ set.add({2, 20});
+ EXPECT_EQ(set.lookup_key({1, 30}).attached_data, 10);
+ EXPECT_EQ(set.lookup_key({2, 0}).attached_data, 20);
+}
+
+TEST(set, LookupKeyDefault)
+{
+ Set<MyKeyType> set;
+ set.add({1, 10});
+ set.add({2, 20});
+
+ MyKeyType fallback{5, 50};
+ EXPECT_EQ(set.lookup_key_default({1, 66}, fallback).attached_data, 10);
+ EXPECT_EQ(set.lookup_key_default({4, 40}, fallback).attached_data, 50);
+}
+
+TEST(set, LookupKeyPtr)
+{
+ Set<MyKeyType> set;
+ set.add({1, 10});
+ set.add({2, 20});
+ EXPECT_EQ(set.lookup_key_ptr({1, 50})->attached_data, 10);
+ EXPECT_EQ(set.lookup_key_ptr({2, 50})->attached_data, 20);
+ EXPECT_EQ(set.lookup_key_ptr({3, 50}), nullptr);
+}
+
+/**
+ * Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot.
+ */
+#if 0
+template<typename SetT>
+BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor)
+{
+ RNG *rng = BLI_rng_new(0);
+ Vector<int> values;
+ for (int i = 0; i < amount; i++) {
+ values.append(BLI_rng_get_int(rng) * factor);
+ }
+ BLI_rng_free(rng);
+
+ SetT set;
+ {
+ SCOPED_TIMER(name + " Add");
+ for (int value : values) {
+ set.add(value);
+ }
+ }
+ int count = 0;
+ {
+ SCOPED_TIMER(name + " Contains");
+ for (int value : values) {
+ count += set.contains(value);
+ }
+ }
+ {
+ SCOPED_TIMER(name + " Remove");
+ for (int value : values) {
+ count += set.remove(value);
+ }
+ }
+
+ /* Print the value for simple error checking and to avoid some compiler optimizations. */
+ std::cout << "Count: " << count << "\n";
+}
+
+TEST(set, Benchmark)
+{
+ for (int i = 0; i < 3; i++) {
+ benchmark_random_ints<blender::Set<int>>("blender::Set ", 100000, 1);
+ benchmark_random_ints<blender::StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, 1);
+ }
+ std::cout << "\n";
+ for (int i = 0; i < 3; i++) {
+ uint32_t factor = (3 << 10);
+ benchmark_random_ints<blender::Set<int>>("blender::Set ", 100000, factor);
+ benchmark_random_ints<blender::StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, factor);
+ }
+}
+
+/**
+ * Output of the rudimentary benchmark above on my hardware.
+ *
+ * Timer 'blender::Set Add' took 5.5573 ms
+ * Timer 'blender::Set Contains' took 0.807384 ms
+ * Timer 'blender::Set Remove' took 0.953436 ms
+ * Count: 199998
+ * Timer 'std::unordered_set Add' took 12.551 ms
+ * Timer 'std::unordered_set Contains' took 2.3323 ms
+ * Timer 'std::unordered_set Remove' took 5.07082 ms
+ * Count: 199998
+ * Timer 'blender::Set Add' took 2.62526 ms
+ * Timer 'blender::Set Contains' took 0.407499 ms
+ * Timer 'blender::Set Remove' took 0.472981 ms
+ * Count: 199998
+ * Timer 'std::unordered_set Add' took 6.26945 ms
+ * Timer 'std::unordered_set Contains' took 1.17236 ms
+ * Timer 'std::unordered_set Remove' took 3.77402 ms
+ * Count: 199998
+ * Timer 'blender::Set Add' took 2.59152 ms
+ * Timer 'blender::Set Contains' took 0.415254 ms
+ * Timer 'blender::Set Remove' took 0.477559 ms
+ * Count: 199998
+ * Timer 'std::unordered_set Add' took 6.28129 ms
+ * Timer 'std::unordered_set Contains' took 1.17562 ms
+ * Timer 'std::unordered_set Remove' took 3.77811 ms
+ * Count: 199998
+ *
+ * Timer 'blender::Set Add' took 3.16514 ms
+ * Timer 'blender::Set Contains' took 0.732895 ms
+ * Timer 'blender::Set Remove' took 1.08171 ms
+ * Count: 198790
+ * Timer 'std::unordered_set Add' took 6.57377 ms
+ * Timer 'std::unordered_set Contains' took 1.17008 ms
+ * Timer 'std::unordered_set Remove' took 3.7946 ms
+ * Count: 198790
+ * Timer 'blender::Set Add' took 3.11439 ms
+ * Timer 'blender::Set Contains' took 0.740159 ms
+ * Timer 'blender::Set Remove' took 1.06749 ms
+ * Count: 198790
+ * Timer 'std::unordered_set Add' took 6.35597 ms
+ * Timer 'std::unordered_set Contains' took 1.17713 ms
+ * Timer 'std::unordered_set Remove' took 3.77826 ms
+ * Count: 198790
+ * Timer 'blender::Set Add' took 3.09876 ms
+ * Timer 'blender::Set Contains' took 0.742072 ms
+ * Timer 'blender::Set Remove' took 1.06622 ms
+ * Count: 198790
+ * Timer 'std::unordered_set Add' took 6.4469 ms
+ * Timer 'std::unordered_set Contains' took 1.16515 ms
+ * Timer 'std::unordered_set Remove' took 3.80639 ms
+ * Count: 198790
+ */
+
+#endif /* Benchmark */
+
+} // namespace tests
+} // namespace blender
diff --git a/source/blender/blenlib/tests/BLI_span_test.cc b/source/blender/blenlib/tests/BLI_span_test.cc
new file mode 100644
index 00000000000..587497624f4
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_span_test.cc
@@ -0,0 +1,311 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_span.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(span, FromSmallVector)
+{
+ Vector<int> a = {1, 2, 3};
+ Span<int> a_span = a;
+ EXPECT_EQ(a_span.size(), 3);
+ EXPECT_EQ(a_span[0], 1);
+ EXPECT_EQ(a_span[1], 2);
+ EXPECT_EQ(a_span[2], 3);
+}
+
+TEST(span, AddConstToPointer)
+{
+ int a = 0;
+ std::vector<int *> vec = {&a};
+ Span<int *> span = vec;
+ Span<const int *> const_span = span;
+ EXPECT_EQ(const_span.size(), 1);
+}
+
+TEST(span, IsReferencing)
+{
+ int array[] = {3, 5, 8};
+ MutableSpan<int> span(array, ARRAY_SIZE(array));
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_EQ(span[1], 5);
+ array[1] = 10;
+ EXPECT_EQ(span[1], 10);
+}
+
+TEST(span, DropBack)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).drop_back(2);
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 4);
+ EXPECT_EQ(slice[1], 5);
+}
+
+TEST(span, DropBackAll)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).drop_back(a.size());
+ EXPECT_EQ(slice.size(), 0);
+}
+
+TEST(span, DropFront)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).drop_front(1);
+ EXPECT_EQ(slice.size(), 3);
+ EXPECT_EQ(slice[0], 5);
+ EXPECT_EQ(slice[1], 6);
+ EXPECT_EQ(slice[2], 7);
+}
+
+TEST(span, DropFrontAll)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).drop_front(a.size());
+ EXPECT_EQ(slice.size(), 0);
+}
+
+TEST(span, TakeFront)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).take_front(2);
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 4);
+ EXPECT_EQ(slice[1], 5);
+}
+
+TEST(span, TakeBack)
+{
+ Vector<int> a = {5, 6, 7, 8};
+ auto slice = Span<int>(a).take_back(2);
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 7);
+ EXPECT_EQ(slice[1], 8);
+}
+
+TEST(span, Slice)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).slice(1, 2);
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 5);
+ EXPECT_EQ(slice[1], 6);
+}
+
+TEST(span, SliceEmpty)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).slice(2, 0);
+ EXPECT_EQ(slice.size(), 0);
+}
+
+TEST(span, SliceRange)
+{
+ Vector<int> a = {1, 2, 3, 4, 5};
+ auto slice = Span<int>(a).slice(IndexRange(2, 2));
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 3);
+ EXPECT_EQ(slice[1], 4);
+}
+
+TEST(span, Contains)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ Span<int> a_span = a;
+ EXPECT_TRUE(a_span.contains(4));
+ EXPECT_TRUE(a_span.contains(5));
+ EXPECT_TRUE(a_span.contains(6));
+ EXPECT_TRUE(a_span.contains(7));
+ EXPECT_FALSE(a_span.contains(3));
+ EXPECT_FALSE(a_span.contains(8));
+}
+
+TEST(span, Count)
+{
+ Vector<int> a = {2, 3, 4, 3, 3, 2, 2, 2, 2};
+ Span<int> a_span = a;
+ EXPECT_EQ(a_span.count(1), 0);
+ EXPECT_EQ(a_span.count(2), 5);
+ EXPECT_EQ(a_span.count(3), 3);
+ EXPECT_EQ(a_span.count(4), 1);
+ EXPECT_EQ(a_span.count(5), 0);
+}
+
+static void test_ref_from_initializer_list(Span<int> span)
+{
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_EQ(span[0], 3);
+ EXPECT_EQ(span[1], 6);
+ EXPECT_EQ(span[2], 8);
+ EXPECT_EQ(span[3], 9);
+}
+
+TEST(span, FromInitializerList)
+{
+ test_ref_from_initializer_list({3, 6, 8, 9});
+}
+
+TEST(span, FromVector)
+{
+ std::vector<int> a = {1, 2, 3, 4};
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(a_span[0], 1);
+ EXPECT_EQ(a_span[1], 2);
+ EXPECT_EQ(a_span[2], 3);
+ EXPECT_EQ(a_span[3], 4);
+}
+
+TEST(span, FromArray)
+{
+ std::array<int, 2> a = {5, 6};
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.size(), 2);
+ EXPECT_EQ(a_span[0], 5);
+ EXPECT_EQ(a_span[1], 6);
+}
+
+TEST(span, Fill)
+{
+ std::array<int, 5> a = {4, 5, 6, 7, 8};
+ MutableSpan<int> a_span(a);
+ a_span.fill(1);
+ EXPECT_EQ(a[0], 1);
+ EXPECT_EQ(a[1], 1);
+ EXPECT_EQ(a[2], 1);
+ EXPECT_EQ(a[3], 1);
+ EXPECT_EQ(a[4], 1);
+}
+
+TEST(span, FillIndices)
+{
+ std::array<int, 5> a = {0, 0, 0, 0, 0};
+ MutableSpan<int> a_span(a);
+ a_span.fill_indices({0, 2, 3}, 1);
+ EXPECT_EQ(a[0], 1);
+ EXPECT_EQ(a[1], 0);
+ EXPECT_EQ(a[2], 1);
+ EXPECT_EQ(a[3], 1);
+ EXPECT_EQ(a[4], 0);
+}
+
+TEST(span, SizeInBytes)
+{
+ std::array<int, 10> a;
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.size_in_bytes(), (int64_t)sizeof(a));
+ EXPECT_EQ(a_span.size_in_bytes(), 40);
+}
+
+TEST(span, FirstLast)
+{
+ std::array<int, 4> a = {6, 7, 8, 9};
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.first(), 6);
+ EXPECT_EQ(a_span.last(), 9);
+}
+
+TEST(span, FirstLast_OneElement)
+{
+ int a = 3;
+ Span<int> a_span(&a, 1);
+ EXPECT_EQ(a_span.first(), 3);
+ EXPECT_EQ(a_span.last(), 3);
+}
+
+TEST(span, Get)
+{
+ std::array<int, 3> a = {5, 6, 7};
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.get(0, 42), 5);
+ EXPECT_EQ(a_span.get(1, 42), 6);
+ EXPECT_EQ(a_span.get(2, 42), 7);
+ EXPECT_EQ(a_span.get(3, 42), 42);
+ EXPECT_EQ(a_span.get(4, 42), 42);
+}
+
+TEST(span, ContainsPtr)
+{
+ std::array<int, 3> a = {5, 6, 7};
+ int other = 10;
+ Span<int> a_span(a);
+ EXPECT_TRUE(a_span.contains_ptr(&a[0] + 0));
+ EXPECT_TRUE(a_span.contains_ptr(&a[0] + 1));
+ EXPECT_TRUE(a_span.contains_ptr(&a[0] + 2));
+ EXPECT_FALSE(a_span.contains_ptr(&a[0] + 3));
+ EXPECT_FALSE(a_span.contains_ptr(&a[0] - 1));
+ EXPECT_FALSE(a_span.contains_ptr(&other));
+}
+
+TEST(span, FirstIndex)
+{
+ std::array<int, 5> a = {4, 5, 4, 2, 5};
+ Span<int> a_span(a);
+
+ EXPECT_EQ(a_span.first_index(4), 0);
+ EXPECT_EQ(a_span.first_index(5), 1);
+ EXPECT_EQ(a_span.first_index(2), 3);
+}
+
+TEST(span, CastSameSize)
+{
+ int value = 0;
+ std::array<int *, 4> a = {&value, nullptr, nullptr, nullptr};
+ Span<int *> a_span = a;
+ Span<float *> new_a_span = a_span.cast<float *>();
+
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(new_a_span.size(), 4);
+
+ EXPECT_EQ(a_span[0], &value);
+ EXPECT_EQ(new_a_span[0], (float *)&value);
+}
+
+TEST(span, CastSmallerSize)
+{
+ std::array<uint32_t, 4> a = {3, 4, 5, 6};
+ Span<uint32_t> a_span = a;
+ Span<uint16_t> new_a_span = a_span.cast<uint16_t>();
+
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(new_a_span.size(), 8);
+}
+
+TEST(span, CastLargerSize)
+{
+ std::array<uint16_t, 4> a = {4, 5, 6, 7};
+ Span<uint16_t> a_span = a;
+ Span<uint32_t> new_a_span = a_span.cast<uint32_t>();
+
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(new_a_span.size(), 2);
+}
+
+TEST(span, VoidPointerSpan)
+{
+ int a;
+ float b;
+ double c;
+
+ auto func1 = [](Span<void *> span) { EXPECT_EQ(span.size(), 3); };
+ func1({&a, &b, &c});
+}
+
+TEST(span, CopyFrom)
+{
+ std::array<int, 4> src = {5, 6, 7, 8};
+ std::array<int, 4> dst = {1, 2, 3, 4};
+
+ EXPECT_EQ(dst[2], 3);
+ MutableSpan(dst).copy_from(src);
+ EXPECT_EQ(dst[0], 5);
+ EXPECT_EQ(dst[1], 6);
+ EXPECT_EQ(dst[2], 7);
+ EXPECT_EQ(dst[3], 8);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_stack_cxx_test.cc b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
new file mode 100644
index 00000000000..3572e751b88
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
@@ -0,0 +1,188 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_stack.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(stack, DefaultConstructor)
+{
+ Stack<int> stack;
+ EXPECT_EQ(stack.size(), 0);
+ EXPECT_TRUE(stack.is_empty());
+}
+
+TEST(stack, SpanConstructor)
+{
+ std::array<int, 3> array = {4, 7, 2};
+ Stack<int> stack(array);
+ EXPECT_EQ(stack.size(), 3);
+ EXPECT_EQ(stack.pop(), 2);
+ EXPECT_EQ(stack.pop(), 7);
+ EXPECT_EQ(stack.pop(), 4);
+ EXPECT_TRUE(stack.is_empty());
+}
+
+TEST(stack, CopyConstructor)
+{
+ Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
+ Stack<int> stack2 = stack1;
+ EXPECT_EQ(stack1.size(), 7);
+ EXPECT_EQ(stack2.size(), 7);
+ for (int i = 7; i >= 1; i--) {
+ EXPECT_FALSE(stack1.is_empty());
+ EXPECT_FALSE(stack2.is_empty());
+ EXPECT_EQ(stack1.pop(), i);
+ EXPECT_EQ(stack2.pop(), i);
+ }
+ EXPECT_TRUE(stack1.is_empty());
+ EXPECT_TRUE(stack2.is_empty());
+}
+
+TEST(stack, MoveConstructor)
+{
+ Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
+ Stack<int> stack2 = std::move(stack1);
+ EXPECT_EQ(stack1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(stack2.size(), 7);
+ for (int i = 7; i >= 1; i--) {
+ EXPECT_EQ(stack2.pop(), i);
+ }
+}
+
+TEST(stack, CopyAssignment)
+{
+ Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
+ Stack<int> stack2 = {2, 3, 4, 5, 6, 7};
+ stack2 = stack1;
+
+ EXPECT_EQ(stack1.size(), 7);
+ EXPECT_EQ(stack2.size(), 7);
+ for (int i = 7; i >= 1; i--) {
+ EXPECT_FALSE(stack1.is_empty());
+ EXPECT_FALSE(stack2.is_empty());
+ EXPECT_EQ(stack1.pop(), i);
+ EXPECT_EQ(stack2.pop(), i);
+ }
+ EXPECT_TRUE(stack1.is_empty());
+ EXPECT_TRUE(stack2.is_empty());
+}
+
+TEST(stack, MoveAssignment)
+{
+ Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
+ Stack<int> stack2 = {5, 3, 7, 2, 2};
+ stack2 = std::move(stack1);
+ EXPECT_EQ(stack1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(stack2.size(), 7);
+ for (int i = 7; i >= 1; i--) {
+ EXPECT_EQ(stack2.pop(), i);
+ }
+}
+
+TEST(stack, Push)
+{
+ Stack<int> stack;
+ EXPECT_EQ(stack.size(), 0);
+ stack.push(3);
+ EXPECT_EQ(stack.size(), 1);
+ stack.push(5);
+ EXPECT_EQ(stack.size(), 2);
+}
+
+TEST(stack, PushMultiple)
+{
+ Stack<int> stack;
+ EXPECT_EQ(stack.size(), 0);
+ stack.push_multiple({1, 2, 3});
+ EXPECT_EQ(stack.size(), 3);
+ EXPECT_EQ(stack.pop(), 3);
+ EXPECT_EQ(stack.pop(), 2);
+ EXPECT_EQ(stack.pop(), 1);
+}
+
+TEST(stack, PushPopMany)
+{
+ Stack<int> stack;
+ for (int i = 0; i < 1000; i++) {
+ stack.push(i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
+ }
+ for (int i = 999; i > 50; i--) {
+ EXPECT_EQ(stack.pop(), i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
+ }
+ for (int i = 51; i < 5000; i++) {
+ stack.push(i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
+ }
+ for (int i = 4999; i >= 0; i--) {
+ EXPECT_EQ(stack.pop(), i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
+ }
+}
+
+TEST(stack, PushMultipleAfterPop)
+{
+ Stack<int> stack;
+ for (int i = 0; i < 1000; i++) {
+ stack.push(i);
+ }
+ for (int i = 999; i >= 0; i--) {
+ EXPECT_EQ(stack.pop(), i);
+ }
+
+ Vector<int> values;
+ for (int i = 0; i < 5000; i++) {
+ values.append(i);
+ }
+ stack.push_multiple(values);
+ EXPECT_EQ(stack.size(), 5000);
+
+ for (int i = 4999; i >= 0; i--) {
+ EXPECT_EQ(stack.pop(), i);
+ }
+}
+
+TEST(stack, Pop)
+{
+ Stack<int> stack;
+ stack.push(4);
+ stack.push(6);
+ EXPECT_EQ(stack.pop(), 6);
+ EXPECT_EQ(stack.pop(), 4);
+}
+
+TEST(stack, Peek)
+{
+ Stack<int> stack;
+ stack.push(3);
+ stack.push(4);
+ EXPECT_EQ(stack.peek(), 4);
+ EXPECT_EQ(stack.peek(), 4);
+ stack.pop();
+ EXPECT_EQ(stack.peek(), 3);
+}
+
+TEST(stack, UniquePtrValues)
+{
+ Stack<std::unique_ptr<int>> stack;
+ stack.push(std::unique_ptr<int>(new int()));
+ stack.push(std::unique_ptr<int>(new int()));
+ std::unique_ptr<int> a = stack.pop();
+ std::unique_ptr<int> &b = stack.peek();
+ UNUSED_VARS(a, b);
+}
+
+TEST(stack, OveralignedValues)
+{
+ Stack<AlignedBuffer<1, 512>, 2> stack;
+ for (int i = 0; i < 100; i++) {
+ stack.push({});
+ EXPECT_EQ((uintptr_t)&stack.peek() % 512, 0);
+ }
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_string_ref_test.cc b/source/blender/blenlib/tests/BLI_string_ref_test.cc
new file mode 100644
index 00000000000..d08c8a77455
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_string_ref_test.cc
@@ -0,0 +1,277 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_strict_flags.h"
+#include "BLI_string_ref.hh"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(string_ref_null, DefaultConstructor)
+{
+ StringRefNull ref;
+ EXPECT_EQ(ref.size(), 0);
+ EXPECT_EQ(ref[0], '\0');
+}
+
+TEST(string_ref_null, CStringConstructor)
+{
+ const char *str = "Hello";
+ StringRefNull ref(str);
+ EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref.data(), str);
+}
+
+TEST(string_ref_null, CStringLengthConstructor)
+{
+ const char *str = "Hello";
+ StringRefNull ref(str, 5);
+ EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref.data(), str);
+}
+
+TEST(string_ref, DefaultConstructor)
+{
+ StringRef ref;
+ EXPECT_EQ(ref.size(), 0);
+}
+
+TEST(string_ref, StartEndConstructor)
+{
+ const char *text = "hello world";
+ StringRef ref(text, text + 5);
+ EXPECT_EQ(ref.size(), 5);
+ EXPECT_TRUE(ref == "hello");
+ EXPECT_FALSE(ref == "hello ");
+}
+
+TEST(string_ref, StartEndConstructorNullptr)
+{
+ StringRef ref(nullptr, nullptr);
+ EXPECT_EQ(ref.size(), 0);
+ EXPECT_TRUE(ref == "");
+}
+
+TEST(string_ref, StartEndConstructorSame)
+{
+ const char *text = "hello world";
+ StringRef ref(text, text);
+ EXPECT_EQ(ref.size(), 0);
+ EXPECT_TRUE(ref == "");
+}
+
+TEST(string_ref, CStringConstructor)
+{
+ const char *str = "Test";
+ StringRef ref(str);
+ EXPECT_EQ(ref.size(), 4);
+ EXPECT_EQ(ref.data(), str);
+}
+
+TEST(string_ref, PointerWithLengthConstructor)
+{
+ const char *str = "Test";
+ StringRef ref(str, 2);
+ EXPECT_EQ(ref.size(), 2);
+ EXPECT_EQ(ref.data(), str);
+}
+
+TEST(string_ref, StdStringConstructor)
+{
+ std::string str = "Test";
+ StringRef ref(str);
+ EXPECT_EQ(ref.size(), 4);
+ EXPECT_EQ(ref.data(), str.data());
+}
+
+TEST(string_ref, SubscriptOperator)
+{
+ StringRef ref("hello");
+ EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref[0], 'h');
+ EXPECT_EQ(ref[1], 'e');
+ EXPECT_EQ(ref[2], 'l');
+ EXPECT_EQ(ref[3], 'l');
+ EXPECT_EQ(ref[4], 'o');
+}
+
+TEST(string_ref, ToStdString)
+{
+ StringRef ref("test");
+ std::string str = ref;
+ EXPECT_EQ(str.size(), 4);
+ EXPECT_EQ(str, "test");
+}
+
+TEST(string_ref, Print)
+{
+ StringRef ref("test");
+ std::stringstream ss;
+ ss << ref;
+ ss << ref;
+ std::string str = ss.str();
+ EXPECT_EQ(str.size(), 8);
+ EXPECT_EQ(str, "testtest");
+}
+
+TEST(string_ref, Add)
+{
+ StringRef a("qwe");
+ StringRef b("asd");
+ std::string result = a + b;
+ EXPECT_EQ(result, "qweasd");
+}
+
+TEST(string_ref, AddCharPtr1)
+{
+ StringRef ref("test");
+ std::string result = ref + "qwe";
+ EXPECT_EQ(result, "testqwe");
+}
+
+TEST(string_ref, AddCharPtr2)
+{
+ StringRef ref("test");
+ std::string result = "qwe" + ref;
+ EXPECT_EQ(result, "qwetest");
+}
+
+TEST(string_ref, AddString1)
+{
+ StringRef ref("test");
+ std::string result = ref + std::string("asd");
+ EXPECT_EQ(result, "testasd");
+}
+
+TEST(string_ref, AddString2)
+{
+ StringRef ref("test");
+ std::string result = std::string("asd") + ref;
+ EXPECT_EQ(result, "asdtest");
+}
+
+TEST(string_ref, CompareEqual)
+{
+ StringRef ref1("test");
+ StringRef ref2("test");
+ StringRef ref3("other");
+ EXPECT_TRUE(ref1 == ref2);
+ EXPECT_FALSE(ref1 == ref3);
+ EXPECT_TRUE(ref1 != ref3);
+ EXPECT_FALSE(ref1 != ref2);
+}
+
+TEST(string_ref, CompareEqualCharPtr1)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(ref == "test");
+ EXPECT_FALSE(ref == "other");
+ EXPECT_TRUE(ref != "other");
+ EXPECT_FALSE(ref != "test");
+}
+
+TEST(string_ref, CompareEqualCharPtr2)
+{
+ StringRef ref("test");
+ EXPECT_TRUE("test" == ref);
+ EXPECT_FALSE("other" == ref);
+ EXPECT_TRUE(ref != "other");
+ EXPECT_FALSE(ref != "test");
+}
+
+TEST(string_ref, CompareEqualString1)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(ref == std::string("test"));
+ EXPECT_FALSE(ref == std::string("other"));
+ EXPECT_TRUE(ref != std::string("other"));
+ EXPECT_FALSE(ref != std::string("test"));
+}
+
+TEST(string_ref, CompareEqualString2)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(std::string("test") == ref);
+ EXPECT_FALSE(std::string("other") == ref);
+ EXPECT_TRUE(std::string("other") != ref);
+ EXPECT_FALSE(std::string("test") != ref);
+}
+
+TEST(string_ref, Iterate)
+{
+ StringRef ref("test");
+ Vector<char> chars;
+ for (char c : ref) {
+ chars.append(c);
+ }
+ EXPECT_EQ(chars.size(), 4);
+ EXPECT_EQ(chars[0], 't');
+ EXPECT_EQ(chars[1], 'e');
+ EXPECT_EQ(chars[2], 's');
+ EXPECT_EQ(chars[3], 't');
+}
+
+TEST(string_ref, StartsWith)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(ref.startswith(""));
+ EXPECT_TRUE(ref.startswith("t"));
+ EXPECT_TRUE(ref.startswith("te"));
+ EXPECT_TRUE(ref.startswith("tes"));
+ EXPECT_TRUE(ref.startswith("test"));
+ EXPECT_FALSE(ref.startswith("test "));
+ EXPECT_FALSE(ref.startswith("a"));
+}
+
+TEST(string_ref, EndsWith)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(ref.endswith(""));
+ EXPECT_TRUE(ref.endswith("t"));
+ EXPECT_TRUE(ref.endswith("st"));
+ EXPECT_TRUE(ref.endswith("est"));
+ EXPECT_TRUE(ref.endswith("test"));
+ EXPECT_FALSE(ref.endswith(" test"));
+ EXPECT_FALSE(ref.endswith("a"));
+}
+
+TEST(string_ref, DropPrefixN)
+{
+ StringRef ref("test");
+ StringRef ref2 = ref.drop_prefix(2);
+ StringRef ref3 = ref2.drop_prefix(2);
+ EXPECT_EQ(ref2.size(), 2);
+ EXPECT_EQ(ref3.size(), 0);
+ EXPECT_EQ(ref2, "st");
+ EXPECT_EQ(ref3, "");
+}
+
+TEST(string_ref, DropPrefix)
+{
+ StringRef ref("test");
+ StringRef ref2 = ref.drop_prefix("tes");
+ EXPECT_EQ(ref2.size(), 1);
+ EXPECT_EQ(ref2, "t");
+}
+
+TEST(string_ref, Substr)
+{
+ StringRef ref("hello world");
+ EXPECT_EQ(ref.substr(0, 5), "hello");
+ EXPECT_EQ(ref.substr(4, 0), "");
+ EXPECT_EQ(ref.substr(3, 4), "lo w");
+ EXPECT_EQ(ref.substr(6, 5), "world");
+}
+
+TEST(string_ref, Copy)
+{
+ StringRef ref("hello");
+ char dst[10];
+ memset(dst, 0xFF, 10);
+ ref.copy(dst);
+ EXPECT_EQ(dst[5], '\0');
+ EXPECT_EQ(dst[6], 0xFF);
+ EXPECT_EQ(ref, dst);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_vector_set_test.cc b/source/blender/blenlib/tests/BLI_vector_set_test.cc
new file mode 100644
index 00000000000..8f3db8d8403
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_vector_set_test.cc
@@ -0,0 +1,164 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_strict_flags.h"
+#include "BLI_vector_set.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(vector_set, DefaultConstructor)
+{
+ VectorSet<int> set;
+ EXPECT_EQ(set.size(), 0);
+ EXPECT_TRUE(set.is_empty());
+}
+
+TEST(vector_set, InitializerListConstructor_WithoutDuplicates)
+{
+ VectorSet<int> set = {1, 4, 5};
+ EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set[0], 1);
+ EXPECT_EQ(set[1], 4);
+ EXPECT_EQ(set[2], 5);
+}
+
+TEST(vector_set, InitializerListConstructor_WithDuplicates)
+{
+ VectorSet<int> set = {1, 3, 3, 2, 1, 5};
+ EXPECT_EQ(set.size(), 4);
+ EXPECT_EQ(set[0], 1);
+ EXPECT_EQ(set[1], 3);
+ EXPECT_EQ(set[2], 2);
+ EXPECT_EQ(set[3], 5);
+}
+
+TEST(vector_set, Copy)
+{
+ VectorSet<int> set1 = {1, 2, 3};
+ VectorSet<int> set2 = set1;
+ EXPECT_EQ(set1.size(), 3);
+ EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set1.index_of(2), 1);
+ EXPECT_EQ(set2.index_of(2), 1);
+}
+
+TEST(vector_set, CopyAssignment)
+{
+ VectorSet<int> set1 = {1, 2, 3};
+ VectorSet<int> set2 = {};
+ set2 = set1;
+ EXPECT_EQ(set1.size(), 3);
+ EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set1.index_of(2), 1);
+ EXPECT_EQ(set2.index_of(2), 1);
+}
+
+TEST(vector_set, Move)
+{
+ VectorSet<int> set1 = {1, 2, 3};
+ VectorSet<int> set2 = std::move(set1);
+ EXPECT_EQ(set1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(set2.size(), 3);
+}
+
+TEST(vector_set, MoveAssignment)
+{
+ VectorSet<int> set1 = {1, 2, 3};
+ VectorSet<int> set2 = {};
+ set2 = std::move(set1);
+ EXPECT_EQ(set1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(set2.size(), 3);
+}
+
+TEST(vector_set, AddNewIncreasesSize)
+{
+ VectorSet<int> set;
+ EXPECT_TRUE(set.is_empty());
+ EXPECT_EQ(set.size(), 0);
+ set.add(5);
+ EXPECT_FALSE(set.is_empty());
+ EXPECT_EQ(set.size(), 1);
+}
+
+TEST(vector_set, AddExistingDoesNotIncreaseSize)
+{
+ VectorSet<int> set;
+ EXPECT_EQ(set.size(), 0);
+ EXPECT_TRUE(set.add(5));
+ EXPECT_EQ(set.size(), 1);
+ EXPECT_FALSE(set.add(5));
+ EXPECT_EQ(set.size(), 1);
+}
+
+TEST(vector_set, Index)
+{
+ VectorSet<int> set = {3, 6, 4};
+ EXPECT_EQ(set.index_of(6), 1);
+ EXPECT_EQ(set.index_of(3), 0);
+ EXPECT_EQ(set.index_of(4), 2);
+}
+
+TEST(vector_set, IndexTry)
+{
+ VectorSet<int> set = {3, 6, 4};
+ EXPECT_EQ(set.index_of_try(5), -1);
+ EXPECT_EQ(set.index_of_try(3), 0);
+ EXPECT_EQ(set.index_of_try(6), 1);
+ EXPECT_EQ(set.index_of_try(2), -1);
+}
+
+TEST(vector_set, RemoveContained)
+{
+ VectorSet<int> set = {4, 5, 6, 7};
+ EXPECT_EQ(set.size(), 4);
+ set.remove_contained(5);
+ EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set[0], 4);
+ EXPECT_EQ(set[1], 7);
+ EXPECT_EQ(set[2], 6);
+ set.remove_contained(6);
+ EXPECT_EQ(set.size(), 2);
+ EXPECT_EQ(set[0], 4);
+ EXPECT_EQ(set[1], 7);
+ set.remove_contained(4);
+ EXPECT_EQ(set.size(), 1);
+ EXPECT_EQ(set[0], 7);
+ set.remove_contained(7);
+ EXPECT_EQ(set.size(), 0);
+}
+
+TEST(vector_set, AddMultipleTimes)
+{
+ VectorSet<int> set;
+ for (int i = 0; i < 100; i++) {
+ EXPECT_FALSE(set.contains(i * 13));
+ set.add(i * 12);
+ set.add(i * 13);
+ EXPECT_TRUE(set.contains(i * 13));
+ }
+}
+
+TEST(vector_set, UniquePtrValue)
+{
+ VectorSet<std::unique_ptr<int>> set;
+ set.add_new(std::unique_ptr<int>(new int()));
+ set.add(std::unique_ptr<int>(new int()));
+ set.index_of_try(std::unique_ptr<int>(new int()));
+ std::unique_ptr<int> value = set.pop();
+ UNUSED_VARS(value);
+}
+
+TEST(vector_set, Remove)
+{
+ VectorSet<int> set;
+ EXPECT_TRUE(set.add(5));
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_FALSE(set.remove(6));
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_TRUE(set.remove(5));
+ EXPECT_FALSE(set.contains(5));
+ EXPECT_FALSE(set.remove(5));
+ EXPECT_FALSE(set.contains(5));
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_vector_test.cc b/source/blender/blenlib/tests/BLI_vector_test.cc
new file mode 100644
index 00000000000..f72dfc5deb8
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_vector_test.cc
@@ -0,0 +1,639 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_strict_flags.h"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+#include <forward_list>
+
+namespace blender::tests {
+
+TEST(vector, DefaultConstructor)
+{
+ Vector<int> vec;
+ EXPECT_EQ(vec.size(), 0);
+}
+
+TEST(vector, SizeConstructor)
+{
+ Vector<int> vec(3);
+ EXPECT_EQ(vec.size(), 3);
+}
+
+/**
+ * Tests that the trivially constructible types are not zero-initialized. We do not want that for
+ * performance reasons.
+ */
+TEST(vector, TrivialTypeSizeConstructor)
+{
+ Vector<char, 1> *vec = new Vector<char, 1>(1);
+ char *ptr = &(*vec)[0];
+ vec->~Vector();
+
+ const char magic = 42;
+ *ptr = magic;
+ EXPECT_EQ(*ptr, magic);
+
+ new (vec) Vector<char, 1>(1);
+ EXPECT_EQ((*vec)[0], magic);
+ EXPECT_EQ(*ptr, magic);
+ delete vec;
+}
+
+TEST(vector, SizeValueConstructor)
+{
+ Vector<int> vec(4, 10);
+ EXPECT_EQ(vec.size(), 4);
+ EXPECT_EQ(vec[0], 10);
+ EXPECT_EQ(vec[1], 10);
+ EXPECT_EQ(vec[2], 10);
+ EXPECT_EQ(vec[3], 10);
+}
+
+TEST(vector, InitializerListConstructor)
+{
+ Vector<int> vec = {1, 3, 4, 6};
+ EXPECT_EQ(vec.size(), 4);
+ EXPECT_EQ(vec[0], 1);
+ EXPECT_EQ(vec[1], 3);
+ EXPECT_EQ(vec[2], 4);
+ EXPECT_EQ(vec[3], 6);
+}
+
+TEST(vector, ConvertingConstructor)
+{
+ std::array<float, 5> values = {5.4f, 7.3f, -8.1f, 5.0f, 0.0f};
+ Vector<int> vec = values;
+ EXPECT_EQ(vec.size(), 5);
+ EXPECT_EQ(vec[0], 5);
+ EXPECT_EQ(vec[1], 7);
+ EXPECT_EQ(vec[2], -8);
+ EXPECT_EQ(vec[3], 5);
+ EXPECT_EQ(vec[4], 0);
+}
+
+struct TestListValue {
+ TestListValue *next, *prev;
+ int value;
+};
+
+TEST(vector, ListBaseConstructor)
+{
+ TestListValue *value1 = new TestListValue{0, 0, 4};
+ TestListValue *value2 = new TestListValue{0, 0, 5};
+ TestListValue *value3 = new TestListValue{0, 0, 6};
+
+ ListBase list = {NULL, NULL};
+ BLI_addtail(&list, value1);
+ BLI_addtail(&list, value2);
+ BLI_addtail(&list, value3);
+ Vector<TestListValue *> vec(list);
+
+ EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec[0]->value, 4);
+ EXPECT_EQ(vec[1]->value, 5);
+ EXPECT_EQ(vec[2]->value, 6);
+
+ delete value1;
+ delete value2;
+ delete value3;
+}
+
+TEST(vector, ContainerConstructor)
+{
+ std::forward_list<int> list;
+ list.push_front(3);
+ list.push_front(1);
+ list.push_front(5);
+
+ Vector<int> vec = Vector<int>::FromContainer(list);
+ EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec[0], 5);
+ EXPECT_EQ(vec[1], 1);
+ EXPECT_EQ(vec[2], 3);
+}
+
+TEST(vector, CopyConstructor)
+{
+ Vector<int> vec1 = {1, 2, 3};
+ Vector<int> vec2(vec1);
+ EXPECT_EQ(vec2.size(), 3);
+ EXPECT_EQ(vec2[0], 1);
+ EXPECT_EQ(vec2[1], 2);
+ EXPECT_EQ(vec2[2], 3);
+
+ vec1[1] = 5;
+ EXPECT_EQ(vec1[1], 5);
+ EXPECT_EQ(vec2[1], 2);
+}
+
+TEST(vector, CopyConstructor2)
+{
+ Vector<int, 2> vec1 = {1, 2, 3, 4};
+ Vector<int, 3> vec2(vec1);
+
+ EXPECT_EQ(vec1.size(), 4);
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_NE(vec1.data(), vec2.data());
+ EXPECT_EQ(vec2[0], 1);
+ EXPECT_EQ(vec2[1], 2);
+ EXPECT_EQ(vec2[2], 3);
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, CopyConstructor3)
+{
+ Vector<int, 20> vec1 = {1, 2, 3, 4};
+ Vector<int, 1> vec2(vec1);
+
+ EXPECT_EQ(vec1.size(), 4);
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_NE(vec1.data(), vec2.data());
+ EXPECT_EQ(vec2[2], 3);
+}
+
+TEST(vector, CopyConstructor4)
+{
+ Vector<int, 5> vec1 = {1, 2, 3, 4};
+ Vector<int, 6> vec2(vec1);
+
+ EXPECT_EQ(vec1.size(), 4);
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_NE(vec1.data(), vec2.data());
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, MoveConstructor)
+{
+ Vector<int> vec1 = {1, 2, 3, 4};
+ Vector<int> vec2(std::move(vec1));
+
+ EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec2[0], 1);
+ EXPECT_EQ(vec2[1], 2);
+ EXPECT_EQ(vec2[2], 3);
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, MoveConstructor2)
+{
+ Vector<int, 2> vec1 = {1, 2, 3, 4};
+ Vector<int, 3> vec2(std::move(vec1));
+
+ EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec2[0], 1);
+ EXPECT_EQ(vec2[1], 2);
+ EXPECT_EQ(vec2[2], 3);
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, MoveConstructor3)
+{
+ Vector<int, 20> vec1 = {1, 2, 3, 4};
+ Vector<int, 1> vec2(std::move(vec1));
+
+ EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec2[2], 3);
+}
+
+TEST(vector, MoveConstructor4)
+{
+ Vector<int, 5> vec1 = {1, 2, 3, 4};
+ Vector<int, 6> vec2(std::move(vec1));
+
+ EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, MoveAssignment)
+{
+ Vector<int> vec = {1, 2};
+ EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec[0], 1);
+ EXPECT_EQ(vec[1], 2);
+
+ vec = Vector<int>({5});
+ EXPECT_EQ(vec.size(), 1);
+ EXPECT_EQ(vec[0], 5);
+}
+
+TEST(vector, CopyAssignment)
+{
+ Vector<int> vec1 = {1, 2, 3};
+ Vector<int> vec2 = {4, 5};
+ EXPECT_EQ(vec1.size(), 3);
+ EXPECT_EQ(vec2.size(), 2);
+
+ vec2 = vec1;
+ EXPECT_EQ(vec2.size(), 3);
+
+ vec1[0] = 7;
+ EXPECT_EQ(vec1[0], 7);
+ EXPECT_EQ(vec2[0], 1);
+}
+
+TEST(vector, Append)
+{
+ Vector<int> vec;
+ vec.append(3);
+ vec.append(6);
+ vec.append(7);
+ EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec[0], 3);
+ EXPECT_EQ(vec[1], 6);
+ EXPECT_EQ(vec[2], 7);
+}
+
+TEST(vector, AppendAndGetIndex)
+{
+ Vector<int> vec;
+ EXPECT_EQ(vec.append_and_get_index(10), 0);
+ EXPECT_EQ(vec.append_and_get_index(10), 1);
+ EXPECT_EQ(vec.append_and_get_index(10), 2);
+ vec.append(10);
+ EXPECT_EQ(vec.append_and_get_index(10), 4);
+}
+
+TEST(vector, AppendNonDuplicates)
+{
+ Vector<int> vec;
+ vec.append_non_duplicates(4);
+ EXPECT_EQ(vec.size(), 1);
+ vec.append_non_duplicates(5);
+ EXPECT_EQ(vec.size(), 2);
+ vec.append_non_duplicates(4);
+ EXPECT_EQ(vec.size(), 2);
+}
+
+TEST(vector, ExtendNonDuplicates)
+{
+ Vector<int> vec;
+ vec.extend_non_duplicates({1, 2});
+ EXPECT_EQ(vec.size(), 2);
+ vec.extend_non_duplicates({3, 4});
+ EXPECT_EQ(vec.size(), 4);
+ vec.extend_non_duplicates({0, 1, 2, 3});
+ EXPECT_EQ(vec.size(), 5);
+}
+
+TEST(vector, Iterator)
+{
+ Vector<int> vec({1, 4, 9, 16});
+ int i = 1;
+ for (int value : vec) {
+ EXPECT_EQ(value, i * i);
+ i++;
+ }
+}
+
+TEST(vector, BecomeLarge)
+{
+ Vector<int, 4> vec;
+ for (int i = 0; i < 100; i++) {
+ vec.append(i * 5);
+ }
+ EXPECT_EQ(vec.size(), 100);
+ for (int i = 0; i < 100; i++) {
+ EXPECT_EQ(vec[i], static_cast<int>(i * 5));
+ }
+}
+
+static Vector<int> return_by_value_helper()
+{
+ return Vector<int>({3, 5, 1});
+}
+
+TEST(vector, ReturnByValue)
+{
+ Vector<int> vec = return_by_value_helper();
+ EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec[0], 3);
+ EXPECT_EQ(vec[1], 5);
+ EXPECT_EQ(vec[2], 1);
+}
+
+TEST(vector, VectorOfVectors_Append)
+{
+ Vector<Vector<int>> vec;
+ EXPECT_EQ(vec.size(), 0);
+
+ Vector<int> v({1, 2});
+ vec.append(v);
+ vec.append({7, 8});
+ EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec[0][0], 1);
+ EXPECT_EQ(vec[0][1], 2);
+ EXPECT_EQ(vec[1][0], 7);
+ EXPECT_EQ(vec[1][1], 8);
+}
+
+TEST(vector, RemoveLast)
+{
+ Vector<int> vec = {5, 6};
+ EXPECT_EQ(vec.size(), 2);
+ vec.remove_last();
+ EXPECT_EQ(vec.size(), 1);
+ vec.remove_last();
+ EXPECT_EQ(vec.size(), 0);
+}
+
+TEST(vector, IsEmpty)
+{
+ Vector<int> vec;
+ EXPECT_TRUE(vec.is_empty());
+ vec.append(1);
+ EXPECT_FALSE(vec.is_empty());
+ vec.remove_last();
+ EXPECT_TRUE(vec.is_empty());
+}
+
+TEST(vector, RemoveReorder)
+{
+ Vector<int> vec = {4, 5, 6, 7};
+ vec.remove_and_reorder(1);
+ EXPECT_EQ(vec[0], 4);
+ EXPECT_EQ(vec[1], 7);
+ EXPECT_EQ(vec[2], 6);
+ vec.remove_and_reorder(2);
+ EXPECT_EQ(vec[0], 4);
+ EXPECT_EQ(vec[1], 7);
+ vec.remove_and_reorder(0);
+ EXPECT_EQ(vec[0], 7);
+ vec.remove_and_reorder(0);
+ EXPECT_TRUE(vec.is_empty());
+}
+
+TEST(vector, RemoveFirstOccurrenceAndReorder)
+{
+ Vector<int> vec = {4, 5, 6, 7};
+ vec.remove_first_occurrence_and_reorder(5);
+ EXPECT_EQ(vec[0], 4);
+ EXPECT_EQ(vec[1], 7);
+ EXPECT_EQ(vec[2], 6);
+ vec.remove_first_occurrence_and_reorder(6);
+ EXPECT_EQ(vec[0], 4);
+ EXPECT_EQ(vec[1], 7);
+ vec.remove_first_occurrence_and_reorder(4);
+ EXPECT_EQ(vec[0], 7);
+ vec.remove_first_occurrence_and_reorder(7);
+ EXPECT_EQ(vec.size(), 0);
+}
+
+TEST(vector, Remove)
+{
+ Vector<int> vec = {1, 2, 3, 4, 5, 6};
+ vec.remove(3);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({1, 2, 3, 5, 6}).begin()));
+ vec.remove(0);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5, 6}).begin()));
+ vec.remove(3);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5}).begin()));
+ vec.remove(1);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 5}).begin()));
+ vec.remove(1);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2}).begin()));
+ vec.remove(0);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({}).begin()));
+}
+
+TEST(vector, ExtendSmallVector)
+{
+ Vector<int> a = {2, 3, 4};
+ Vector<int> b = {11, 12};
+ b.extend(a);
+ EXPECT_EQ(b.size(), 5);
+ EXPECT_EQ(b[0], 11);
+ EXPECT_EQ(b[1], 12);
+ EXPECT_EQ(b[2], 2);
+ EXPECT_EQ(b[3], 3);
+ EXPECT_EQ(b[4], 4);
+}
+
+TEST(vector, ExtendArray)
+{
+ int array[] = {3, 4, 5, 6};
+
+ Vector<int> a;
+ a.extend(array, 2);
+
+ EXPECT_EQ(a.size(), 2);
+ EXPECT_EQ(a[0], 3);
+ EXPECT_EQ(a[1], 4);
+}
+
+TEST(vector, Last)
+{
+ Vector<int> a{3, 5, 7};
+ EXPECT_EQ(a.last(), 7);
+}
+
+TEST(vector, AppendNTimes)
+{
+ Vector<int> a;
+ a.append_n_times(5, 3);
+ a.append_n_times(2, 2);
+ EXPECT_EQ(a.size(), 5);
+ EXPECT_EQ(a[0], 5);
+ EXPECT_EQ(a[1], 5);
+ EXPECT_EQ(a[2], 5);
+ EXPECT_EQ(a[3], 2);
+ EXPECT_EQ(a[4], 2);
+}
+
+TEST(vector, UniquePtrValue)
+{
+ Vector<std::unique_ptr<int>> vec;
+ vec.append(std::unique_ptr<int>(new int()));
+ vec.append(std::unique_ptr<int>(new int()));
+ vec.append(std::unique_ptr<int>(new int()));
+ vec.append(std::unique_ptr<int>(new int()));
+ EXPECT_EQ(vec.size(), 4);
+
+ std::unique_ptr<int> &a = vec.last();
+ std::unique_ptr<int> b = vec.pop_last();
+ vec.remove_and_reorder(0);
+ vec.remove(0);
+ EXPECT_EQ(vec.size(), 1);
+
+ UNUSED_VARS(a, b);
+}
+
+class TypeConstructMock {
+ public:
+ bool default_constructed = false;
+ bool copy_constructed = false;
+ bool move_constructed = false;
+ bool copy_assigned = false;
+ bool move_assigned = false;
+
+ TypeConstructMock() : default_constructed(true)
+ {
+ }
+
+ TypeConstructMock(const TypeConstructMock &UNUSED(other)) : copy_constructed(true)
+ {
+ }
+
+ TypeConstructMock(TypeConstructMock &&UNUSED(other)) noexcept : move_constructed(true)
+ {
+ }
+
+ TypeConstructMock &operator=(const TypeConstructMock &other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ copy_assigned = true;
+ return *this;
+ }
+
+ TypeConstructMock &operator=(TypeConstructMock &&other) noexcept
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ move_assigned = true;
+ return *this;
+ }
+};
+
+TEST(vector, SizeConstructorCallsDefaultConstructor)
+{
+ Vector<TypeConstructMock> vec(3);
+ EXPECT_TRUE(vec[0].default_constructed);
+ EXPECT_TRUE(vec[1].default_constructed);
+ EXPECT_TRUE(vec[2].default_constructed);
+}
+
+TEST(vector, SizeValueConstructorCallsCopyConstructor)
+{
+ Vector<TypeConstructMock> vec(3, TypeConstructMock());
+ EXPECT_TRUE(vec[0].copy_constructed);
+ EXPECT_TRUE(vec[1].copy_constructed);
+ EXPECT_TRUE(vec[2].copy_constructed);
+}
+
+TEST(vector, AppendCallsCopyConstructor)
+{
+ Vector<TypeConstructMock> vec;
+ TypeConstructMock value;
+ vec.append(value);
+ EXPECT_TRUE(vec[0].copy_constructed);
+}
+
+TEST(vector, AppendCallsMoveConstructor)
+{
+ Vector<TypeConstructMock> vec;
+ vec.append(TypeConstructMock());
+ EXPECT_TRUE(vec[0].move_constructed);
+}
+
+TEST(vector, SmallVectorCopyCallsCopyConstructor)
+{
+ Vector<TypeConstructMock, 2> src(2);
+ Vector<TypeConstructMock, 2> dst(src);
+ EXPECT_TRUE(dst[0].copy_constructed);
+ EXPECT_TRUE(dst[1].copy_constructed);
+}
+
+TEST(vector, LargeVectorCopyCallsCopyConstructor)
+{
+ Vector<TypeConstructMock, 2> src(5);
+ Vector<TypeConstructMock, 2> dst(src);
+ EXPECT_TRUE(dst[0].copy_constructed);
+ EXPECT_TRUE(dst[1].copy_constructed);
+}
+
+TEST(vector, SmallVectorMoveCallsMoveConstructor)
+{
+ Vector<TypeConstructMock, 2> src(2);
+ Vector<TypeConstructMock, 2> dst(std::move(src));
+ EXPECT_TRUE(dst[0].move_constructed);
+ EXPECT_TRUE(dst[1].move_constructed);
+}
+
+TEST(vector, LargeVectorMoveCallsNoConstructor)
+{
+ Vector<TypeConstructMock, 2> src(5);
+ Vector<TypeConstructMock, 2> dst(std::move(src));
+
+ EXPECT_TRUE(dst[0].default_constructed);
+ EXPECT_FALSE(dst[0].move_constructed);
+ EXPECT_FALSE(dst[0].copy_constructed);
+}
+
+TEST(vector, Resize)
+{
+ std::string long_string = "012345678901234567890123456789";
+ Vector<std::string> vec;
+ EXPECT_EQ(vec.size(), 0);
+ vec.resize(2);
+ EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec[0], "");
+ EXPECT_EQ(vec[1], "");
+ vec.resize(5, long_string);
+ EXPECT_EQ(vec.size(), 5);
+ EXPECT_EQ(vec[0], "");
+ EXPECT_EQ(vec[1], "");
+ EXPECT_EQ(vec[2], long_string);
+ EXPECT_EQ(vec[3], long_string);
+ EXPECT_EQ(vec[4], long_string);
+ vec.resize(1);
+ EXPECT_EQ(vec.size(), 1);
+ EXPECT_EQ(vec[0], "");
+}
+
+TEST(vector, FirstIndexOf)
+{
+ Vector<int> vec = {2, 3, 5, 7, 5, 9};
+ EXPECT_EQ(vec.first_index_of(2), 0);
+ EXPECT_EQ(vec.first_index_of(5), 2);
+ EXPECT_EQ(vec.first_index_of(9), 5);
+}
+
+TEST(vector, FirstIndexTryOf)
+{
+ Vector<int> vec = {2, 3, 5, 7, 5, 9};
+ EXPECT_EQ(vec.first_index_of_try(2), 0);
+ EXPECT_EQ(vec.first_index_of_try(4), -1);
+ EXPECT_EQ(vec.first_index_of_try(5), 2);
+ EXPECT_EQ(vec.first_index_of_try(9), 5);
+ EXPECT_EQ(vec.first_index_of_try(1), -1);
+}
+
+TEST(vector, OveralignedValues)
+{
+ Vector<AlignedBuffer<1, 512>, 2> vec;
+ for (int i = 0; i < 100; i++) {
+ vec.append({});
+ EXPECT_EQ((uintptr_t)&vec.last() % 512, 0);
+ }
+}
+
+TEST(vector, ConstructVoidPointerVector)
+{
+ int a;
+ float b;
+ double c;
+ Vector<void *> vec = {&a, &b, &c};
+ EXPECT_EQ(vec.size(), 3);
+}
+
+TEST(vector, Fill)
+{
+ Vector<int> vec(5);
+ vec.fill(3);
+ EXPECT_EQ(vec.size(), 5u);
+ EXPECT_EQ(vec[0], 3);
+ EXPECT_EQ(vec[1], 3);
+ EXPECT_EQ(vec[2], 3);
+ EXPECT_EQ(vec[3], 3);
+ EXPECT_EQ(vec[4], 3);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenloader/BLO_blend_defs.h b/source/blender/blenloader/BLO_blend_defs.h
index fec61605dca..40da63f20e8 100644
--- a/source/blender/blenloader/BLO_blend_defs.h
+++ b/source/blender/blenloader/BLO_blend_defs.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLO_BLEND_DEFS_H__
-#define __BLO_BLEND_DEFS_H__
+#pragma once
/** \file
* \ingroup blenloader
@@ -72,5 +71,3 @@ enum {
};
#define BLEN_THUMB_MEMSIZE_FILE(_x, _y) (sizeof(int) * (2 + (size_t)(_x) * (size_t)(_y)))
-
-#endif /* __BLO_BLEND_DEFS_H__ */
diff --git a/source/blender/blenloader/BLO_blend_validate.h b/source/blender/blenloader/BLO_blend_validate.h
index 1ffaddef02f..78aa481d4b1 100644
--- a/source/blender/blenloader/BLO_blend_validate.h
+++ b/source/blender/blenloader/BLO_blend_validate.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLO_BLEND_VALIDATE_H__
-#define __BLO_BLEND_VALIDATE_H__
+#pragma once
/** \file
* \ingroup blenloader
@@ -31,5 +30,3 @@ struct ReportList;
bool BLO_main_validate_libraries(struct Main *bmain, struct ReportList *reports);
bool BLO_main_validate_shapekeys(struct Main *bmain, struct ReportList *reports);
-
-#endif
diff --git a/source/blender/blenloader/BLO_read_write.h b/source/blender/blenloader/BLO_read_write.h
index 59116b4eefc..024b6a6c5e4 100644
--- a/source/blender/blenloader/BLO_read_write.h
+++ b/source/blender/blenloader/BLO_read_write.h
@@ -38,8 +38,7 @@
* necessary.
*/
-#ifndef __BLO_READ_WRITE_H__
-#define __BLO_READ_WRITE_H__
+#pragma once
/* for SDNA_TYPE_FROM_STRUCT() macro */
#include "dna_type_offsets.h"
@@ -180,7 +179,7 @@ bool BLO_write_is_undo(BlendWriter *writer);
void *BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_address);
#define BLO_read_data_address(reader, ptr_p) \
- *(ptr_p) = BLO_read_get_new_data_address((reader), *(ptr_p))
+ *((void **)ptr_p) = BLO_read_get_new_data_address((reader), *(ptr_p))
typedef void (*BlendReadListFn)(BlendDataReader *reader, void *data);
void BLO_read_list_cb(BlendDataReader *reader, struct ListBase *list, BlendReadListFn callback);
@@ -223,5 +222,3 @@ void BLO_expand_id(BlendExpander *expander, struct ID *id);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLO_READ_WRITE_H__ */
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index e4908eb7257..97c77ed2e19 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __BLO_READFILE_H__
-#define __BLO_READFILE_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -196,5 +195,3 @@ extern const struct UserDef U_default;
#ifdef __cplusplus
}
#endif
-
-#endif /* __BLO_READFILE_H__ */
diff --git a/source/blender/blenloader/BLO_undofile.h b/source/blender/blenloader/BLO_undofile.h
index f9300f8a521..f5527c13429 100644
--- a/source/blender/blenloader/BLO_undofile.h
+++ b/source/blender/blenloader/BLO_undofile.h
@@ -18,8 +18,7 @@
* external writefile function prototypes
*/
-#ifndef __BLO_UNDOFILE_H__
-#define __BLO_UNDOFILE_H__
+#pragma once
/** \file
* \ingroup blenloader
@@ -85,5 +84,3 @@ extern struct Main *BLO_memfile_main_get(struct MemFile *memfile,
struct Main *bmain,
struct Scene **r_scene);
extern bool BLO_memfile_write_file(struct MemFile *memfile, const char *filename);
-
-#endif /* __BLO_UNDOFILE_H__ */
diff --git a/source/blender/blenloader/BLO_writefile.h b/source/blender/blenloader/BLO_writefile.h
index 8fe04e764f9..746c663926d 100644
--- a/source/blender/blenloader/BLO_writefile.h
+++ b/source/blender/blenloader/BLO_writefile.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BLO_WRITEFILE_H__
-#define __BLO_WRITEFILE_H__
+#pragma once
/** \file
* \ingroup blenloader
@@ -73,5 +72,3 @@ extern bool BLO_write_file_mem(struct Main *mainvar,
int write_flags);
/** \} */
-
-#endif
diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt
index 09e2f4bf417..7eab0651d97 100644
--- a/source/blender/blenloader/CMakeLists.txt
+++ b/source/blender/blenloader/CMakeLists.txt
@@ -63,8 +63,8 @@ set(SRC
BLO_blend_defs.h
BLO_blend_validate.h
- BLO_readfile.h
BLO_read_write.h
+ BLO_readfile.h
BLO_undofile.h
BLO_writefile.h
intern/readfile.h
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index e1350f9de66..cb2094d050f 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -56,7 +56,7 @@
#endif
/* local prototypes --------------------- */
-void BLO_blendhandle_print_sizes(BlendHandle *, void *);
+void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp);
/* Access routines used by filesel. */
@@ -390,32 +390,17 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain,
blo_make_old_idmap_from_main(fd, old_mainlist.first);
}
- /* makes lookup of existing images in old main */
- blo_make_image_pointer_map(fd, oldmain);
-
- /* makes lookup of existing light caches in old main */
- blo_make_scene_pointer_map(fd, oldmain);
-
- /* makes lookup of existing video clips in old main */
- blo_make_movieclip_pointer_map(fd, oldmain);
-
/* removed packed data from this trick - it's internal data that needs saves */
+ /* Store all existing ID caches pointers into a mapping, to allow restoring them into newly
+ * read IDs whenever possible. */
blo_cache_storage_init(fd, oldmain);
bfd = blo_read_file_internal(fd, filename);
+ /* Ensure relinked caches are not freed together with their old IDs. */
blo_cache_storage_old_bmain_clear(fd, oldmain);
- /* ensures relinked light caches are not freed */
- blo_end_scene_pointer_map(fd, oldmain);
-
- /* ensures relinked images are not freed */
- blo_end_image_pointer_map(fd, oldmain);
-
- /* ensures relinked movie clips are not freed */
- blo_end_movieclip_pointer_map(fd, oldmain);
-
/* Still in-use libraries have already been moved from oldmain to new mainlist,
* but oldmain itself shall *never* be 'transferred' to new mainlist! */
BLI_assert(old_mainlist.first == oldmain);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 5a2b8da6ef9..435c96711bd 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1613,21 +1613,6 @@ void blo_filedata_free(FileData *fd)
if (fd->globmap) {
oldnewmap_free(fd->globmap);
}
- if (fd->imamap) {
- oldnewmap_free(fd->imamap);
- }
- if (fd->movieclipmap) {
- oldnewmap_free(fd->movieclipmap);
- }
- if (fd->scenemap) {
- oldnewmap_free(fd->scenemap);
- }
- if (fd->soundmap) {
- oldnewmap_free(fd->soundmap);
- }
- if (fd->volumemap) {
- oldnewmap_free(fd->volumemap);
- }
if (fd->packedmap) {
oldnewmap_free(fd->packedmap);
}
@@ -1804,51 +1789,6 @@ static void *newglobadr(FileData *fd, const void *adr)
return oldnewmap_lookup_and_inc(fd->globmap, adr, true);
}
-/* used to restore image data after undo */
-static void *newimaadr(FileData *fd, const void *adr)
-{
- if (fd->imamap && adr) {
- return oldnewmap_lookup_and_inc(fd->imamap, adr, true);
- }
- return NULL;
-}
-
-/* used to restore scene data after undo */
-static void *newsceadr(FileData *fd, const void *adr)
-{
- if (fd->scenemap && adr) {
- return oldnewmap_lookup_and_inc(fd->scenemap, adr, true);
- }
- return NULL;
-}
-
-/* used to restore movie clip data after undo */
-static void *newmclipadr(FileData *fd, const void *adr)
-{
- if (fd->movieclipmap && adr) {
- return oldnewmap_lookup_and_inc(fd->movieclipmap, adr, true);
- }
- return NULL;
-}
-
-/* used to restore sound data after undo */
-static void *newsoundadr(FileData *fd, const void *adr)
-{
- if (fd->soundmap && adr) {
- return oldnewmap_lookup_and_inc(fd->soundmap, adr, true);
- }
- return NULL;
-}
-
-/* used to restore volume data after undo */
-static void *newvolumeadr(FileData *fd, const void *adr)
-{
- if (fd->volumemap && adr) {
- return oldnewmap_lookup_and_inc(fd->volumemap, adr, true);
- }
- return NULL;
-}
-
/* used to restore packed data after undo */
static void *newpackedadr(FileData *fd, const void *adr)
{
@@ -1926,219 +1866,6 @@ void blo_clear_proxy_pointers_from_lib(Main *oldmain)
}
}
-void blo_make_scene_pointer_map(FileData *fd, Main *oldmain)
-{
- Scene *sce = oldmain->scenes.first;
-
- fd->scenemap = oldnewmap_new();
-
- for (; sce; sce = sce->id.next) {
- if (sce->eevee.light_cache_data) {
- struct LightCache *light_cache = sce->eevee.light_cache_data;
- oldnewmap_insert(fd->scenemap, light_cache, light_cache, 0);
- }
- }
-}
-
-void blo_end_scene_pointer_map(FileData *fd, Main *oldmain)
-{
- OldNew *entry = fd->scenemap->entries;
- Scene *sce = oldmain->scenes.first;
- int i;
-
- /* used entries were restored, so we put them to zero */
- for (i = 0; i < fd->scenemap->nentries; i++, entry++) {
- if (entry->nr > 0) {
- entry->newp = NULL;
- }
- }
-
- for (; sce; sce = sce->id.next) {
- sce->eevee.light_cache_data = newsceadr(fd, sce->eevee.light_cache_data);
- }
-}
-
-void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
-{
- Scene *sce = oldmain->scenes.first;
- fd->imamap = oldnewmap_new();
-
- for (; sce; sce = sce->id.next) {
- if (sce->nodetree && sce->nodetree->previews) {
- bNodeInstanceHashIterator iter;
- NODE_INSTANCE_HASH_ITER (iter, sce->nodetree->previews) {
- bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
- oldnewmap_insert(fd->imamap, preview, preview, 0);
- }
- }
- }
-}
-
-/* set old main image ibufs to zero if it has been restored */
-/* this works because freeing old main only happens after this call */
-void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
-{
- OldNew *entry = fd->imamap->entries;
- Scene *sce = oldmain->scenes.first;
- int i;
-
- /* used entries were restored, so we put them to zero */
- for (i = 0; i < fd->imamap->nentries; i++, entry++) {
- if (entry->nr > 0) {
- entry->newp = NULL;
- }
- }
-
- for (; sce; sce = sce->id.next) {
- if (sce->nodetree && sce->nodetree->previews) {
- bNodeInstanceHash *new_previews = BKE_node_instance_hash_new("node previews");
- bNodeInstanceHashIterator iter;
-
- /* reconstruct the preview hash, only using remaining pointers */
- NODE_INSTANCE_HASH_ITER (iter, sce->nodetree->previews) {
- bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
- if (preview) {
- bNodePreview *new_preview = newimaadr(fd, preview);
- if (new_preview) {
- bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
- BKE_node_instance_hash_insert(new_previews, key, new_preview);
- }
- }
- }
- BKE_node_instance_hash_free(sce->nodetree->previews, NULL);
- sce->nodetree->previews = new_previews;
- }
- }
-}
-
-void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain)
-{
- MovieClip *clip = oldmain->movieclips.first;
- Scene *sce = oldmain->scenes.first;
-
- fd->movieclipmap = oldnewmap_new();
-
- for (; clip; clip = clip->id.next) {
- if (clip->cache) {
- oldnewmap_insert(fd->movieclipmap, clip->cache, clip->cache, 0);
- }
-
- if (clip->tracking.camera.intrinsics) {
- oldnewmap_insert(
- fd->movieclipmap, clip->tracking.camera.intrinsics, clip->tracking.camera.intrinsics, 0);
- }
- }
-
- for (; sce; sce = sce->id.next) {
- if (sce->nodetree) {
- bNode *node;
- for (node = sce->nodetree->nodes.first; node; node = node->next) {
- if (node->type == CMP_NODE_MOVIEDISTORTION) {
- oldnewmap_insert(fd->movieclipmap, node->storage, node->storage, 0);
- }
- }
- }
- }
-}
-
-/* set old main movie clips caches to zero if it has been restored */
-/* this works because freeing old main only happens after this call */
-void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain)
-{
- OldNew *entry = fd->movieclipmap->entries;
- MovieClip *clip = oldmain->movieclips.first;
- Scene *sce = oldmain->scenes.first;
- int i;
-
- /* used entries were restored, so we put them to zero */
- for (i = 0; i < fd->movieclipmap->nentries; i++, entry++) {
- if (entry->nr > 0) {
- entry->newp = NULL;
- }
- }
-
- for (; clip; clip = clip->id.next) {
- clip->cache = newmclipadr(fd, clip->cache);
- clip->tracking.camera.intrinsics = newmclipadr(fd, clip->tracking.camera.intrinsics);
- BLI_freelistN(&clip->runtime.gputextures);
- }
-
- for (; sce; sce = sce->id.next) {
- if (sce->nodetree) {
- bNode *node;
- for (node = sce->nodetree->nodes.first; node; node = node->next) {
- if (node->type == CMP_NODE_MOVIEDISTORTION) {
- node->storage = newmclipadr(fd, node->storage);
- }
- }
- }
- }
-}
-
-void blo_make_sound_pointer_map(FileData *fd, Main *oldmain)
-{
- bSound *sound = oldmain->sounds.first;
-
- fd->soundmap = oldnewmap_new();
-
- for (; sound; sound = sound->id.next) {
- if (sound->waveform) {
- oldnewmap_insert(fd->soundmap, sound->waveform, sound->waveform, 0);
- }
- }
-}
-
-/* set old main sound caches to zero if it has been restored */
-/* this works because freeing old main only happens after this call */
-void blo_end_sound_pointer_map(FileData *fd, Main *oldmain)
-{
- OldNew *entry = fd->soundmap->entries;
- bSound *sound = oldmain->sounds.first;
- int i;
-
- /* used entries were restored, so we put them to zero */
- for (i = 0; i < fd->soundmap->nentries; i++, entry++) {
- if (entry->nr > 0) {
- entry->newp = NULL;
- }
- }
-
- for (; sound; sound = sound->id.next) {
- sound->waveform = newsoundadr(fd, sound->waveform);
- }
-}
-
-void blo_make_volume_pointer_map(FileData *fd, Main *oldmain)
-{
- fd->volumemap = oldnewmap_new();
-
- Volume *volume = oldmain->volumes.first;
- for (; volume; volume = volume->id.next) {
- if (volume->runtime.grids) {
- oldnewmap_insert(fd->volumemap, volume->runtime.grids, volume->runtime.grids, 0);
- }
- }
-}
-
-/* set old main volume caches to zero if it has been restored */
-/* this works because freeing old main only happens after this call */
-void blo_end_volume_pointer_map(FileData *fd, Main *oldmain)
-{
- OldNew *entry = fd->volumemap->entries;
- Volume *volume = oldmain->volumes.first;
- int i;
-
- /* used entries were restored, so we put them to zero */
- for (i = 0; i < fd->volumemap->nentries; i++, entry++) {
- if (entry->nr > 0)
- entry->newp = NULL;
- }
-
- for (; volume; volume = volume->id.next) {
- volume->runtime.grids = newvolumeadr(fd, volume->runtime.grids);
- }
-}
-
/* XXX disabled this feature - packed files also belong in temp saves and quit.blend,
* to make restore work. */
@@ -2281,9 +2008,11 @@ typedef struct BLOCacheStorage {
static void blo_cache_storage_entry_register(ID *id,
const IDCacheKey *key,
void **UNUSED(cache_p),
+ eIDTypeInfoCacheCallbackFlags UNUSED(flags),
void *cache_storage_v)
{
BLI_assert(key->id_session_uuid == id->session_uuid);
+ UNUSED_VARS_NDEBUG(id);
BLOCacheStorage *cache_storage = cache_storage_v;
BLI_assert(!BLI_ghash_haskey(cache_storage->cache_map, key));
@@ -2297,12 +2026,18 @@ static void blo_cache_storage_entry_register(ID *id,
static void blo_cache_storage_entry_restore_in_new(ID *UNUSED(id),
const IDCacheKey *key,
void **cache_p,
+ eIDTypeInfoCacheCallbackFlags flags,
void *cache_storage_v)
{
BLOCacheStorage *cache_storage = cache_storage_v;
if (cache_storage == NULL) {
- *cache_p = NULL;
+ /* In non-undo case, only clear the pointer if it is a purely runtime one.
+ * If it may be stored in a persistent way in the .blend file, direct_link code is responsible
+ * to properly deal with it. */
+ if ((flags & IDTYPE_CACHE_CB_FLAGS_PERSISTENT) == 0) {
+ *cache_p = NULL;
+ }
return;
}
@@ -2319,6 +2054,7 @@ static void blo_cache_storage_entry_restore_in_new(ID *UNUSED(id),
static void blo_cache_storage_entry_clear_in_old(ID *UNUSED(id),
const IDCacheKey *key,
void **cache_p,
+ eIDTypeInfoCacheCallbackFlags UNUSED(flags),
void *cache_storage_v)
{
BLOCacheStorage *cache_storage = cache_storage_v;
@@ -2358,7 +2094,7 @@ void blo_cache_storage_init(FileData *fd, Main *bmain)
if (ID_IS_LINKED(id)) {
continue;
}
- type_info->foreach_cache(id, blo_cache_storage_entry_register, fd->cache_storage);
+ BKE_idtype_id_foreach_cache(id, blo_cache_storage_entry_register, fd->cache_storage);
}
FOREACH_MAIN_LISTBASE_ID_END;
}
@@ -2388,7 +2124,7 @@ void blo_cache_storage_old_bmain_clear(FileData *fd, Main *bmain_old)
if (ID_IS_LINKED(id)) {
continue;
}
- type_info->foreach_cache(id, blo_cache_storage_entry_clear_in_old, fd->cache_storage);
+ BKE_idtype_id_foreach_cache(id, blo_cache_storage_entry_clear_in_old, fd->cache_storage);
}
FOREACH_MAIN_LISTBASE_ID_END;
}
@@ -3761,7 +3497,8 @@ static void direct_link_nodetree(BlendDataReader *reader, bNodeTree *ntree)
}
if (node->type == CMP_NODE_MOVIEDISTORTION) {
- node->storage = newmclipadr(reader->fd, node->storage);
+ /* Do nothing, this is runtime cache and hence handled by generic code using
+ * `IDTypeInfo.foreach_cache` callback. */
}
else {
BLO_read_data_address(reader, &node->storage);
@@ -3860,28 +3597,8 @@ static void direct_link_nodetree(BlendDataReader *reader, bNodeTree *ntree)
BLO_read_data_address(reader, &link->tosock);
}
-#if 0
- if (ntree->previews) {
- bNodeInstanceHash* new_previews = BKE_node_instance_hash_new("node previews");
- bNodeInstanceHashIterator iter;
-
- NODE_INSTANCE_HASH_ITER(iter, ntree->previews) {
- bNodePreview* preview = BKE_node_instance_hash_iterator_get_value(&iter);
- if (preview) {
- bNodePreview* new_preview = newimaadr(fd, preview);
- if (new_preview) {
- bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
- BKE_node_instance_hash_insert(new_previews, key, new_preview);
- }
- }
- }
- BKE_node_instance_hash_free(ntree->previews, NULL);
- ntree->previews = new_previews;
- }
-#else
- /* XXX TODO */
+ /* TODO, should be dealt by new generic cache handling of IDs... */
ntree->previews = NULL;
-#endif
/* type verification is in lib-link */
}
@@ -4445,7 +4162,7 @@ static void direct_link_curve(BlendDataReader *reader, Curve *cu)
direct_link_animdata(reader, cu->adt);
/* Protect against integer overflow vulnerability. */
- CLAMP(cu->len_wchar, 0, INT_MAX - 4);
+ CLAMP(cu->len_char32, 0, INT_MAX - 4);
BLO_read_pointer_array(reader, (void **)&cu->mat);
@@ -4908,7 +4625,6 @@ static void direct_link_particlesystems(BlendDataReader *reader, ListBase *parti
psys->orig_psys = NULL;
psys->batch_cache = NULL;
}
- return;
}
/** \} */
@@ -5429,6 +5145,9 @@ static void direct_link_pose(BlendDataReader *reader, bPose *pose)
pose->chan_array = NULL;
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ BKE_pose_channel_runtime_reset(&pchan->runtime);
+ BKE_pose_channel_session_uuid_generate(pchan);
+
pchan->bone = NULL;
BLO_read_data_address(reader, &pchan->parent);
BLO_read_data_address(reader, &pchan->child);
@@ -5454,7 +5173,6 @@ static void direct_link_pose(BlendDataReader *reader, bPose *pose)
CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
pchan->draw_data = NULL;
- BKE_pose_channel_runtime_reset(&pchan->runtime);
}
pose->ikdata = NULL;
if (pose->ikparam != NULL) {
@@ -5800,7 +5518,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
/* initialize the curve. Maybe this could be moved to modififer logic */
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
else if (md->type == eGpencilModifierType_Thick) {
@@ -5809,7 +5527,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_thickness);
if (gpmd->curve_thickness) {
BKE_curvemapping_blend_read(reader, gpmd->curve_thickness);
- BKE_curvemapping_initialize(gpmd->curve_thickness);
+ BKE_curvemapping_init(gpmd->curve_thickness);
}
}
else if (md->type == eGpencilModifierType_Tint) {
@@ -5818,7 +5536,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
else if (md->type == eGpencilModifierType_Smooth) {
@@ -5826,7 +5544,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
else if (md->type == eGpencilModifierType_Color) {
@@ -5834,7 +5552,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
else if (md->type == eGpencilModifierType_Opacity) {
@@ -5842,7 +5560,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
}
@@ -6314,7 +6032,7 @@ static void direct_link_lightcache_texture(BlendDataReader *reader, LightCacheTe
if (lctex->data) {
BLO_read_data_address(reader, &lctex->data);
- if (BLO_read_requires_endian_switch(reader)) {
+ if (lctex->data && BLO_read_requires_endian_switch(reader)) {
int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] *
lctex->tex_size[2];
@@ -6326,10 +6044,15 @@ static void direct_link_lightcache_texture(BlendDataReader *reader, LightCacheTe
}
}
}
+
+ if (lctex->data == NULL) {
+ zero_v3_int(lctex->tex_size);
+ }
}
static void direct_link_lightcache(BlendDataReader *reader, LightCache *cache)
{
+ cache->flag &= ~LIGHTCACHE_NOT_USABLE;
direct_link_lightcache_texture(reader, &cache->cube_tx);
direct_link_lightcache_texture(reader, &cache->grid_tx);
@@ -6370,6 +6093,14 @@ static bool scene_validate_setscene__liblink(Scene *sce, const int totscene)
}
for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) {
+ /* This runs per library (before each libraries #Main has been joined),
+ * so we can't step into other libraries since `totscene` is only for this library.
+ *
+ * Also, other libraries may not have been linked yet,
+ * while we could check #LIB_TAG_NEED_LINK the library pointer check is sufficient. */
+ if (sce->id.lib != sce_iter->id.lib) {
+ return true;
+ }
if (sce_iter->flag & SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK) {
return true;
}
@@ -6745,6 +6476,9 @@ static void direct_link_scene(BlendDataReader *reader, Scene *sce)
link_recurs_seq(reader, &ed->seqbase);
SEQ_BEGIN (ed, seq) {
+ /* Do as early as possible, so that other parts of reading can rely on valid session UUID. */
+ BKE_sequence_session_uuid_generate(seq);
+
BLO_read_data_address(reader, &seq->seq1);
BLO_read_data_address(reader, &seq->seq2);
BLO_read_data_address(reader, &seq->seq3);
@@ -6943,13 +6677,7 @@ static void direct_link_scene(BlendDataReader *reader, Scene *sce)
}
if (reader->fd->memfile) {
- /* If it's undo try to recover the cache. */
- if (reader->fd->scenemap) {
- sce->eevee.light_cache_data = newsceadr(reader->fd, sce->eevee.light_cache_data);
- }
- else {
- sce->eevee.light_cache_data = NULL;
- }
+ /* If it's undo do nothing here, caches are handled by higher-level generic calling code. */
}
else {
/* else try to read the cache from file. */
@@ -8477,20 +8205,6 @@ static void direct_link_movieclip(BlendDataReader *reader, MovieClip *clip)
BLO_read_data_address(reader, &clip->adt);
- if (reader->fd->movieclipmap) {
- clip->cache = newmclipadr(reader->fd, clip->cache);
- }
- else {
- clip->cache = NULL;
- }
-
- if (reader->fd->movieclipmap) {
- clip->tracking.camera.intrinsics = newmclipadr(reader->fd, clip->tracking.camera.intrinsics);
- }
- else {
- clip->tracking.camera.intrinsics = NULL;
- }
-
direct_link_movieTracks(reader, &tracking->tracks);
direct_link_moviePlaneTracks(reader, &tracking->plane_tracks);
direct_link_movieReconstruction(reader, &tracking->reconstruction);
@@ -8502,6 +8216,10 @@ static void direct_link_movieclip(BlendDataReader *reader, MovieClip *clip)
clip->tracking_context = NULL;
clip->tracking.stats = NULL;
+ /* TODO we could store those in undo cache storage as well, and preserve them instead of
+ * re-creating them... */
+ BLI_listbase_clear(&clip->runtime.gputextures);
+
/* Needed for proper versioning, will be NULL for all newer files anyway. */
BLO_read_data_address(reader, &clip->tracking.stabilization.rot_track);
@@ -8910,7 +8628,7 @@ static void direct_link_hair(BlendDataReader *reader, Hair *hair)
BKE_hair_update_customdata_pointers(hair);
/* Materials */
- BLO_read_pointer_array(reader, (void **)hair->mat);
+ BLO_read_pointer_array(reader, (void **)&hair->mat);
}
/** \} */
@@ -8975,8 +8693,11 @@ static void direct_link_volume(BlendDataReader *reader, Volume *volume)
/** \name Read ID: Simulation
* \{ */
-static void lib_link_simulation(BlendLibReader *UNUSED(reader), Simulation *UNUSED(simulation))
+static void lib_link_simulation(BlendLibReader *reader, Simulation *simulation)
{
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ BLO_read_id_address(reader, simulation->id.lib, &dependency->id);
+ }
}
static void direct_link_simulation(BlendDataReader *reader, Simulation *simulation)
@@ -8986,16 +8707,15 @@ static void direct_link_simulation(BlendDataReader *reader, Simulation *simulati
BLO_read_list(reader, &simulation->states);
LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
- switch ((eSimulationStateType)state->type) {
- case SIM_STATE_TYPE_PARTICLES: {
- ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
- direct_link_customdata(reader, &particle_state->attributes, particle_state->tot_particles);
- direct_link_pointcache_list(
- reader, &particle_state->ptcaches, &particle_state->point_cache, 0);
- break;
- };
+ BLO_read_data_address(reader, &state->name);
+ BLO_read_data_address(reader, &state->type);
+ if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) {
+ ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+ direct_link_customdata(reader, &particle_state->attributes, particle_state->tot_particles);
}
}
+
+ BLO_read_list(reader, &simulation->dependencies);
}
/** \} */
@@ -9268,7 +8988,8 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
/* try to restore (when undoing) or clear ID's cache pointers. */
if (id_type->foreach_cache != NULL) {
- id_type->foreach_cache(id, blo_cache_storage_entry_restore_in_new, reader.fd->cache_storage);
+ BKE_idtype_id_foreach_cache(
+ id, blo_cache_storage_entry_restore_in_new, reader.fd->cache_storage);
}
return success;
@@ -9280,18 +9001,23 @@ static BHead *read_data_into_datamap(FileData *fd, BHead *bhead, const char *all
bhead = blo_bhead_next(fd, bhead);
while (bhead && bhead->code == DATA) {
- void *data;
+ /* The code below is useful for debugging leaks in data read from the blend file.
+ * Without this the messages only tell us what ID-type the memory came from,
+ * eg: `Data from OB len 64`, see #dataname.
+ * With the code below we get the struct-name to help tracking down the leak.
+ * This is kept disabled as the #malloc for the text always leaks memory. */
#if 0
- /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */
- short* sp = fd->filesdna->structs[bhead->SDNAnr];
- char* tmp = malloc(100);
- allocname = fd->filesdna->types[sp[0]];
- strcpy(tmp, allocname);
- data = read_struct(fd, bhead, tmp);
-#else
- data = read_struct(fd, bhead, allocname);
+ {
+ const short *sp = fd->filesdna->structs[bhead->SDNAnr];
+ allocname = fd->filesdna->types[sp[0]];
+ size_t allocname_size = strlen(allocname) + 1;
+ char *allocname_buf = malloc(allocname_size);
+ memcpy(allocname_buf, allocname, allocname_size);
+ allocname = allocname_buf;
+ }
#endif
+ void *data = read_struct(fd, bhead, allocname);
if (data) {
oldnewmap_insert(fd->datamap, bhead->old, data, 0);
}
@@ -11398,6 +11124,9 @@ static void expand_simulation(BlendExpander *expander, Simulation *simulation)
if (simulation->adt) {
expand_animdata(expander, simulation->adt);
}
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ BLO_expand(expander, dependency->id);
+ }
}
/**
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index 57c86f7128c..34a670a8357 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -22,8 +22,7 @@
* \ingroup blenloader
*/
-#ifndef __READFILE_H__
-#define __READFILE_H__
+#pragma once
#include "DNA_sdna_types.h"
#include "DNA_space_types.h"
@@ -116,11 +115,6 @@ typedef struct FileData {
struct OldNewMap *datamap;
struct OldNewMap *globmap;
struct OldNewMap *libmap;
- struct OldNewMap *imamap;
- struct OldNewMap *movieclipmap;
- struct OldNewMap *scenemap;
- struct OldNewMap *soundmap;
- struct OldNewMap *volumemap;
struct OldNewMap *packedmap;
struct BLOCacheStorage *cache_storage;
@@ -154,16 +148,6 @@ FileData *blo_filedata_from_memfile(struct MemFile *memfile,
struct ReportList *reports);
void blo_clear_proxy_pointers_from_lib(struct Main *oldmain);
-void blo_make_image_pointer_map(FileData *fd, struct Main *oldmain);
-void blo_end_image_pointer_map(FileData *fd, struct Main *oldmain);
-void blo_make_scene_pointer_map(FileData *fd, struct Main *oldmain);
-void blo_end_scene_pointer_map(FileData *fd, struct Main *oldmain);
-void blo_make_movieclip_pointer_map(FileData *fd, struct Main *oldmain);
-void blo_end_movieclip_pointer_map(FileData *fd, struct Main *oldmain);
-void blo_make_sound_pointer_map(FileData *fd, struct Main *oldmain);
-void blo_end_sound_pointer_map(FileData *fd, struct Main *oldmain);
-void blo_make_volume_pointer_map(FileData *fd, struct Main *oldmain);
-void blo_end_volume_pointer_map(FileData *fd, struct Main *oldmain);
void blo_make_packed_pointer_map(FileData *fd, struct Main *oldmain);
void blo_end_packed_pointer_map(FileData *fd, struct Main *oldmain);
void blo_add_library_pointer_map(ListBase *old_mainlist, FileData *fd);
@@ -214,5 +198,3 @@ void do_versions_after_linking_270(struct Main *bmain);
void do_versions_after_linking_280(struct Main *bmain, struct ReportList *reports);
void do_versions_after_linking_290(struct Main *bmain, struct ReportList *reports);
void do_versions_after_linking_cycles(struct Main *bmain);
-
-#endif
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 3ed59a0baa1..1432fbeb4e2 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -280,7 +280,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb)
region->v2d.keepzoom |= (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_KEEPASPECT);
region->v2d.keeptot = V2D_KEEPTOT_STRICT;
region->v2d.minzoom = region->v2d.maxzoom = 1.0f;
- // region->v2d.flag |= V2D_IS_INITIALISED;
+ // region->v2d.flag |= V2D_IS_INIT;
break;
}
case SPACE_GRAPH: {
@@ -297,7 +297,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb)
region->v2d.max[0] = MAXFRAMEF;
region->v2d.max[1] = FLT_MAX;
- // region->v2d.flag |= V2D_IS_INITIALISED;
+ // region->v2d.flag |= V2D_IS_INIT;
break;
}
case SPACE_NLA: {
@@ -355,7 +355,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb)
region->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
region->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_VERTICAL_HANDLES);
region->v2d.align = V2D_ALIGN_NO_NEG_Y;
- region->v2d.flag |= V2D_IS_INITIALISED;
+ region->v2d.flag |= V2D_IS_INIT;
break;
}
case SPACE_NODE: {
@@ -965,7 +965,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
bPoseChannel *pchan;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- /* just need to initialise rotation axis properly... */
+ /* Just need to initialize rotation axis properly. */
pchan->rotAxis[1] = 1.0f;
}
}
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index b3bf8991c3e..f74ee9cd735 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -1205,7 +1205,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (region->regiontype == RGN_TYPE_PREVIEW) {
if (region->alignment != RGN_ALIGN_NONE) {
region->flag |= RGN_FLAG_HIDDEN;
- region->v2d.flag &= ~V2D_IS_INITIALISED;
+ region->v2d.flag &= ~V2D_IS_INIT;
region->alignment = RGN_ALIGN_NONE;
hide = true;
@@ -2520,7 +2520,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
for (cu = bmain->curves.first; cu; cu = cu->id.next) {
if (cu->str) {
- cu->len_wchar = BLI_strlen_utf8(cu->str);
+ cu->len_char32 = BLI_strlen_utf8(cu->str);
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index 521fc4b9b82..2c4602f546b 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1108,7 +1108,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
for (scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
CurveMapping *curve_mapping = &scene->r.mblur_shutter_curve;
BKE_curvemapping_set_defaults(curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(curve_mapping);
+ BKE_curvemapping_init(curve_mapping);
BKE_curvemap_reset(
curve_mapping->cm, &curve_mapping->clipr, CURVE_PRESET_MAX, CURVEMAP_SLOPE_POS_NEG);
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 111ac728cc3..fc3e81a2005 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -190,7 +190,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
static void do_version_area_change_space_to_space_action(ScrArea *area, const Scene *scene)
{
SpaceType *stype = BKE_spacetype_from_id(SPACE_ACTION);
- SpaceAction *saction = (SpaceAction *)stype->new (area, scene);
+ SpaceAction *saction = (SpaceAction *)stype->create(area, scene);
ARegion *region_channels;
/* Properly free current regions */
@@ -1958,7 +1958,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
GP_Sculpt_Settings *gset = &scene->toolsettings->gp_sculpt;
if ((gset) && (gset->cur_falloff == NULL)) {
gset->cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(gset->cur_falloff);
+ BKE_curvemapping_init(gset->cur_falloff);
BKE_curvemap_reset(gset->cur_falloff->cm,
&gset->cur_falloff->clipr,
CURVE_PRESET_GAUSS,
@@ -3371,7 +3371,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
GP_Sculpt_Settings *gset = &scene->toolsettings->gp_sculpt;
if ((gset) && (gset->cur_primitive == NULL)) {
gset->cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(gset->cur_primitive);
+ BKE_curvemapping_init(gset->cur_primitive);
BKE_curvemap_reset(gset->cur_primitive->cm,
&gset->cur_primitive->clipr,
CURVE_PRESET_BELL,
@@ -4767,7 +4767,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
@@ -4778,7 +4778,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
@@ -4788,7 +4788,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
@@ -4798,7 +4798,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
@@ -4808,7 +4808,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 2e93df09e1e..12b5a297df5 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -21,12 +21,16 @@
#define DNA_DEPRECATED_ALLOW
#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "DNA_brush_types.h"
+#include "DNA_cachefile_types.h"
#include "DNA_constraint_types.h"
#include "DNA_genfile.h"
#include "DNA_gpencil_modifier_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
@@ -34,8 +38,10 @@
#include "BKE_collection.h"
#include "BKE_colortools.h"
+#include "BKE_gpencil.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
+#include "BKE_node.h"
#include "BLO_readfile.h"
#include "readfile.h"
@@ -181,6 +187,23 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
}
}
}
+
+ /* Patch first frame for old files. */
+ Scene *scene = bmain->scenes.first;
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ if (ob->type != OB_GPENCIL) {
+ continue;
+ }
+ bGPdata *gpd = ob->data;
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *gpf = gpl->frames.first;
+ if (gpf && gpf->framenum > scene->r.sfra) {
+ bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf);
+ gpf_dup->framenum = scene->r.sfra;
+ BLI_addhead(&gpl->frames, gpf_dup);
+ }
+ }
+ }
}
/**
@@ -194,6 +217,14 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
* \note Keep this message at the bottom of the function.
*/
{
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
+ if (BKE_collection_cycles_fix(bmain, collection)) {
+ printf(
+ "WARNING: Cycle detected in collection '%s', fixed as best as possible.\n"
+ "You may have to reconstruct your View Layers...\n",
+ collection->id.name);
+ }
+ }
/* Keep this block, even when empty. */
}
}
@@ -255,20 +286,31 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
- }
- /**
- * Versioning code until next subversion bump goes here.
- *
- * \note Be sure to check when bumping the version:
- * - "versioning_userdef.c", #BLO_version_defaults_userpref_blend
- * - "versioning_userdef.c", #do_versions_theme
- *
- * \note Keep this message at the bottom of the function.
- */
- {
- /* Keep this block, even when empty. */
+ /* Initialize parameters of the new Nishita sky model. */
+ if (!DNA_struct_elem_find(fd->filesdna, "NodeTexSky", "float", "sun_size")) {
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type == NTREE_SHADER) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == SH_NODE_TEX_SKY && node->storage) {
+ NodeTexSky *tex = (NodeTexSky *)node->storage;
+ tex->sun_disc = true;
+ tex->sun_size = DEG2RADF(0.545);
+ tex->sun_elevation = M_PI_2;
+ tex->sun_rotation = 0.0f;
+ tex->altitude = 0.0f;
+ tex->air_density = 1.0f;
+ tex->dust_density = 1.0f;
+ tex->ozone_density = 1.0f;
+ }
+ }
+ }
+ }
+ FOREACH_NODETREE_END;
+ }
+ }
+ if (!MAIN_VERSION_ATLEAST(bmain, 290, 6)) {
/* Transition to saving expansion for all of a modifier's sub-panels. */
if (!DNA_struct_elem_find(fd->filesdna, "ModifierData", "short", "ui_expand_flag")) {
for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
@@ -338,17 +380,105 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
- }
- /* Refactor bevel profile type to use an enum. */
- if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "short", "profile_type")) {
+ /* Refactor bevel profile type to use an enum. */
+ if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "short", "profile_type")) {
+ for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_Bevel) {
+ BevelModifierData *bmd = (BevelModifierData *)md;
+ bool use_custom_profile = bmd->flags & MOD_BEVEL_CUSTOM_PROFILE_DEPRECATED;
+ bmd->profile_type = use_custom_profile ? MOD_BEVEL_PROFILE_CUSTOM :
+ MOD_BEVEL_PROFILE_SUPERELLIPSE;
+ }
+ }
+ }
+ }
+
+ /* Change ocean modifier values from [0, 10] to [0, 1] ranges. */
for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
- if (md->type == eModifierType_Bevel) {
- BevelModifierData *bmd = (BevelModifierData *)md;
- bool use_custom_profile = bmd->flags & MOD_BEVEL_CUSTOM_PROFILE_DEPRECATED;
- bmd->profile_type = use_custom_profile ? MOD_BEVEL_PROFILE_CUSTOM :
- MOD_BEVEL_PROFILE_SUPERELLIPSE;
+ if (md->type == eModifierType_Ocean) {
+ OceanModifierData *omd = (OceanModifierData *)md;
+ omd->wave_alignment *= 0.1f;
+ omd->sharpen_peak_jonswap *= 0.1f;
+ }
+ }
+ }
+ }
+
+ /**
+ * Versioning code until next subversion bump goes here.
+ *
+ * \note Be sure to check when bumping the version:
+ * - "versioning_userdef.c", #BLO_version_defaults_userpref_blend
+ * - "versioning_userdef.c", #do_versions_theme
+ *
+ * \note Keep this message at the bottom of the function.
+ */
+ {
+ /* Keep this block, even when empty. */
+
+ /* Initialize additional parameter of the Nishita sky model and change altitude unit. */
+ if (!DNA_struct_elem_find(fd->filesdna, "NodeTexSky", "float", "sun_intensity")) {
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type == NTREE_SHADER) {
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == SH_NODE_TEX_SKY && node->storage) {
+ NodeTexSky *tex = (NodeTexSky *)node->storage;
+ tex->sun_intensity = 1.0f;
+ tex->altitude *= 0.001f;
+ }
+ }
+ }
+ }
+ FOREACH_NODETREE_END;
+ }
+
+ /* Refactor bevel affect type to use an enum. */
+ if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "char", "affect_type")) {
+ for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_Bevel) {
+ BevelModifierData *bmd = (BevelModifierData *)md;
+ const bool use_vertex_bevel = bmd->flags & MOD_BEVEL_VERT_DEPRECATED;
+ bmd->affect_type = use_vertex_bevel ? MOD_BEVEL_AFFECT_VERTICES :
+ MOD_BEVEL_AFFECT_EDGES;
+ }
+ }
+ }
+ }
+
+ /* Initialise additional velocity parameter for CacheFiles. */
+ if (!DNA_struct_elem_find(
+ fd->filesdna, "MeshSeqCacheModifierData", "float", "velocity_scale")) {
+ for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_MeshSequenceCache) {
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
+ mcmd->velocity_scale = 1.0f;
+ mcmd->vertex_velocities = NULL;
+ mcmd->num_vertices = 0;
+ }
+ }
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "CacheFile", "char", "velocity_unit")) {
+ for (CacheFile *cache_file = bmain->cachefiles.first; cache_file != NULL;
+ cache_file = cache_file->id.next) {
+ BLI_strncpy(cache_file->velocity_name, ".velocities", sizeof(cache_file->velocity_name));
+ cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND;
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "OceanModifierData", "int", "viewport_resolution")) {
+ for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_Ocean) {
+ OceanModifierData *omd = (OceanModifierData *)md;
+ omd->viewport_resolution = omd->resolution;
+ }
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 1217b69f1b5..ae6d3a58091 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -106,7 +106,7 @@ static void blo_update_defaults_screen(bScreen *screen,
/* Some toolbars have been saved as initialized,
* we don't want them to have odd zoom-level or scrolling set, see: T47047 */
if (ELEM(region->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS)) {
- region->v2d.flag &= ~V2D_IS_INITIALISED;
+ region->v2d.flag &= ~V2D_IS_INIT;
}
}
@@ -315,7 +315,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
copy_v2_fl2(scene->safe_areas.title, 0.1f, 0.05f);
copy_v2_fl2(scene->safe_areas.action, 0.035f, 0.035f);
- /* Change default cubemap quality. */
+ /* Change default cube-map quality. */
scene->eevee.gi_filter_quality = 3.0f;
/* Enable Soft Shadows by default. */
@@ -326,7 +326,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
if (ts->gp_sculpt.cur_falloff == NULL) {
ts->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_falloff_curve = ts->gp_sculpt.cur_falloff;
- BKE_curvemapping_initialize(gp_falloff_curve);
+ BKE_curvemapping_init(gp_falloff_curve);
BKE_curvemap_reset(gp_falloff_curve->cm,
&gp_falloff_curve->clipr,
CURVE_PRESET_GAUSS,
@@ -335,7 +335,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
if (ts->gp_sculpt.cur_primitive == NULL) {
ts->gp_sculpt.cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_primitive_curve = ts->gp_sculpt.cur_primitive;
- BKE_curvemapping_initialize(gp_primitive_curve);
+ BKE_curvemapping_init(gp_primitive_curve);
BKE_curvemap_reset(gp_primitive_curve->cm,
&gp_primitive_curve->clipr,
CURVE_PRESET_BELL,
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index ce472a97337..d25e340d4fc 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -579,7 +579,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
}
if (bmain->versionfile <= 109) {
- /* new variable: gridlines */
+ /* New variable: `gridlines`. */
bScreen *screen = bmain->screens.first;
while (screen) {
ScrArea *area = screen->areabase.first;
@@ -1339,7 +1339,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
arm = blo_do_versions_newlibadr(fd, lib, ob->data);
enum { ARM_DRAWXRAY = (1 << 1) };
if (arm->flag & ARM_DRAWXRAY) {
- ob->dtx |= OB_DRAWXRAY;
+ ob->dtx |= OB_DRAW_IN_FRONT;
}
}
else if (ob->type == OB_MESH) {
@@ -2096,7 +2096,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
if (la->curfalloff == NULL) {
la->curfalloff = BKE_curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
- BKE_curvemapping_initialize(la->curfalloff);
+ BKE_curvemapping_init(la->curfalloff);
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index 1b0e41ec54a..e2dc27d7e88 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -366,7 +366,7 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef)
}
if (!USER_VERSION_ATLEAST(250, 0)) {
/* adjust grease-pencil distances */
- userdef->gp_manhattendist = 1;
+ userdef->gp_manhattandist = 1;
userdef->gp_euclideandist = 2;
/* adjust default interpolation for new IPO-curves */
@@ -753,6 +753,10 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef)
userdef->transopts &= ~USER_DOTRANSLATE_DEPRECATED;
}
+ if (!USER_VERSION_ATLEAST(290, 7)) {
+ userdef->statusbar_flag = STATUSBAR_SHOW_VERSION;
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 2ce8abff3c5..d842c204ba1 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2007,7 +2007,7 @@ static void write_curve(BlendWriter *writer, Curve *cu, const void *id_address)
if (cu->vfont) {
BLO_write_raw(writer, cu->len + 1, cu->str);
- BLO_write_struct_array(writer, CharInfo, cu->len_wchar + 1, cu->strinfo);
+ BLO_write_struct_array(writer, CharInfo, cu->len_char32 + 1, cu->strinfo);
BLO_write_struct_array(writer, TextBox, cu->totbox, cu->tb);
}
else {
@@ -2497,7 +2497,12 @@ static void write_lightcache_texture(BlendWriter *writer, LightCacheTexture *tex
else if (tex->data_type == LIGHTCACHETEX_UINT) {
data_size *= sizeof(uint);
}
- BLO_write_raw(writer, data_size, tex->data);
+
+ /* FIXME: We can't save more than what 32bit systems can handle.
+ * The solution would be to split the texture but it is too late for 2.90. (see T78529) */
+ if (data_size < INT_MAX) {
+ BLO_write_raw(writer, data_size, tex->data);
+ }
}
}
@@ -3832,28 +3837,37 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const
}
LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
- switch ((eSimulationStateType)state->type) {
- case SIM_STATE_TYPE_PARTICLES: {
- ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
- BLO_write_struct(writer, ParticleSimulationState, particle_state);
-
- CustomDataLayer *layers = NULL;
- CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE];
- CustomData_file_write_prepare(
- &particle_state->attributes, &layers, layers_buff, ARRAY_SIZE(layers_buff));
-
- write_customdata(writer,
- &simulation->id,
- particle_state->tot_particles,
- &particle_state->attributes,
- layers,
- CD_MASK_ALL);
-
- write_pointcaches(writer, &particle_state->ptcaches);
- break;
+ BLO_write_string(writer, state->name);
+ BLO_write_string(writer, state->type);
+ /* TODO: Decentralize this part. */
+ if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) {
+ ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+ BLO_write_struct(writer, ParticleSimulationState, particle_state);
+
+ CustomDataLayer *layers = NULL;
+ CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE];
+ CustomData_file_write_prepare(
+ &particle_state->attributes, &layers, layers_buff, ARRAY_SIZE(layers_buff));
+
+ write_customdata(writer,
+ &simulation->id,
+ particle_state->tot_particles,
+ &particle_state->attributes,
+ layers,
+ CD_MASK_ALL);
+
+ if (layers != NULL && layers != layers_buff) {
+ MEM_freeN(layers);
}
}
+ else if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER)) {
+ ParticleMeshEmitterSimulationState *emitter_state = (ParticleMeshEmitterSimulationState *)
+ state;
+ BLO_write_struct(writer, ParticleMeshEmitterSimulationState, emitter_state);
+ }
}
+
+ BLO_write_struct_list(writer, SimulationDependency, &simulation->dependencies);
}
}
@@ -4038,8 +4052,9 @@ static bool write_file_handle(Main *mainvar,
* avoid thumbnail detecting changes because of this. */
mywrite_flush(wd);
- OverrideLibraryStorage *override_storage =
- wd->use_memfile ? NULL : BKE_lib_override_library_operations_store_initialize();
+ OverrideLibraryStorage *override_storage = wd->use_memfile ?
+ NULL :
+ BKE_lib_override_library_operations_store_init();
#define ID_BUFFER_STATIC_SIZE 8192
/* This outer loop allows to save first data-blocks from real mainvar,
diff --git a/source/blender/blentranslation/BLT_lang.h b/source/blender/blentranslation/BLT_lang.h
index 6ce9a0ba71c..dcd4de10416 100644
--- a/source/blender/blentranslation/BLT_lang.h
+++ b/source/blender/blentranslation/BLT_lang.h
@@ -21,8 +21,7 @@
* \ingroup blt
*/
-#ifndef __BLT_LANG_H__
-#define __BLT_LANG_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -60,5 +59,3 @@ struct EnumPropertyItem *BLT_lang_RNA_enum_properties(void);
#ifdef __cplusplus
};
#endif
-
-#endif /* __BLT_LANG_H__ */
diff --git a/source/blender/blentranslation/BLT_translation.h b/source/blender/blentranslation/BLT_translation.h
index 817b99e8b91..b8979caa909 100644
--- a/source/blender/blentranslation/BLT_translation.h
+++ b/source/blender/blentranslation/BLT_translation.h
@@ -21,8 +21,7 @@
* \ingroup blt
*/
-#ifndef __BLT_TRANSLATION_H__
-#define __BLT_TRANSLATION_H__
+#pragma once
#include "BLI_utildefines.h" /* for bool type */
@@ -221,5 +220,3 @@ typedef struct {
#ifdef __cplusplus
};
#endif
-
-#endif /* __BLT_TRANSLATION_H__ */
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 7a389c63abd..fca411e594f 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -118,6 +118,8 @@ set(SRC
intern/bmesh_query.c
intern/bmesh_query.h
intern/bmesh_query_inline.h
+ intern/bmesh_query_uv.c
+ intern/bmesh_query_uv.h
intern/bmesh_structure.c
intern/bmesh_structure.h
intern/bmesh_structure_inline.h
@@ -151,6 +153,10 @@ set(SRC
tools/bmesh_path.h
tools/bmesh_path_region.c
tools/bmesh_path_region.h
+ tools/bmesh_path_uv.c
+ tools/bmesh_path_uv.h
+ tools/bmesh_path_region_uv.c
+ tools/bmesh_path_region_uv.h
tools/bmesh_region_match.c
tools/bmesh_region_match.h
tools/bmesh_separate.c
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index c0791e6fdbc..5f5d6baaba2 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_H__
-#define __BMESH_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -223,6 +222,7 @@ extern "C" {
#include "intern/bmesh_polygon.h"
#include "intern/bmesh_polygon_edgenet.h"
#include "intern/bmesh_query.h"
+#include "intern/bmesh_query_uv.h"
#include "intern/bmesh_walkers.h"
#include "intern/bmesh_inline.h"
@@ -230,5 +230,3 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BMESH_H__ */
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 1393e24e48e..edb355993c1 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_CLASS_H__
-#define __BMESH_CLASS_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -472,5 +471,3 @@ typedef bool (*BMLoopFilterFunc)(const BMLoop *, void *user_data);
#else
# define BM_OMP_LIMIT 10000
#endif
-
-#endif /* __BMESH_CLASS_H__ */
diff --git a/source/blender/bmesh/bmesh_tools.h b/source/blender/bmesh/bmesh_tools.h
index d0e91d033fb..ee53cb9804d 100644
--- a/source/blender/bmesh/bmesh_tools.h
+++ b/source/blender/bmesh/bmesh_tools.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_TOOLS_H__
-#define __BMESH_TOOLS_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -36,6 +35,8 @@ extern "C" {
#include "tools/bmesh_edgesplit.h"
#include "tools/bmesh_path.h"
#include "tools/bmesh_path_region.h"
+#include "tools/bmesh_path_region_uv.h"
+#include "tools/bmesh_path_uv.h"
#include "tools/bmesh_region_match.h"
#include "tools/bmesh_separate.h"
#include "tools/bmesh_triangulate.h"
@@ -43,5 +44,3 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* __BMESH_TOOLS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.h b/source/blender/bmesh/intern/bmesh_callback_generic.h
index 5191bd31873..3f3a48fd546 100644
--- a/source/blender/bmesh/intern/bmesh_callback_generic.h
+++ b/source/blender/bmesh/intern/bmesh_callback_generic.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_CALLBACK_GENERIC_H__
-#define __BMESH_CALLBACK_GENERIC_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -35,5 +34,3 @@ bool BM_elem_cb_check_elem_not_equal(BMElem *ele, void *user_data);
#define BM_elem_cb_check_hflag_disabled_simple(type, hflag_n) \
(bool (*)(type, void *)) BM_elem_cb_check_hflag_disabled, POINTER_FROM_UINT(hflag_n)
-
-#endif /* __BMESH_CALLBACK_GENERIC_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h
index ae2b137d38a..3523c4aec1a 100644
--- a/source/blender/bmesh/intern/bmesh_construct.h
+++ b/source/blender/bmesh/intern/bmesh_construct.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_CONSTRUCT_H__
-#define __BMESH_CONSTRUCT_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -78,5 +77,3 @@ char BM_vert_flag_from_mflag(const char mflag);
char BM_face_flag_to_mflag(BMFace *f);
short BM_edge_flag_to_mflag(BMEdge *e);
char BM_vert_flag_to_mflag(BMVert *v);
-
-#endif /* __BMESH_CONSTRUCT_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 35fb698eac1..4e9775bcfa7 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -101,6 +101,7 @@ BMVert *BM_vert_create(BMesh *bm,
/* may add to middle of the pool */
bm->elem_index_dirty |= BM_VERT;
bm->elem_table_dirty |= BM_VERT;
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
bm->totvert++;
@@ -190,6 +191,7 @@ BMEdge *BM_edge_create(
/* may add to middle of the pool */
bm->elem_index_dirty |= BM_EDGE;
bm->elem_table_dirty |= BM_EDGE;
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
bm->totedge++;
@@ -259,6 +261,7 @@ static BMLoop *bm_loop_create(BMesh *bm,
/* may add to middle of the pool */
bm->elem_index_dirty |= BM_LOOP;
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
bm->totloop++;
@@ -402,6 +405,7 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
/* may add to middle of the pool */
bm->elem_index_dirty |= BM_FACE;
bm->elem_table_dirty |= BM_FACE;
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
bm->totface++;
@@ -748,6 +752,7 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
bm->totvert--;
bm->elem_index_dirty |= BM_VERT;
bm->elem_table_dirty |= BM_VERT;
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
BM_select_history_remove(bm, v);
@@ -770,6 +775,7 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e)
bm->totedge--;
bm->elem_index_dirty |= BM_EDGE;
bm->elem_table_dirty |= BM_EDGE;
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
BM_select_history_remove(bm, (BMElem *)e);
@@ -796,6 +802,7 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f)
bm->totface--;
bm->elem_index_dirty |= BM_FACE;
bm->elem_table_dirty |= BM_FACE;
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
BM_select_history_remove(bm, (BMElem *)f);
@@ -817,6 +824,8 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
{
bm->totloop--;
bm->elem_index_dirty |= BM_LOOP;
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+
if (l->head.data) {
CustomData_bmesh_free_block(&bm->ldata, &l->head.data);
}
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index 3308f93d5d3..0e19437a527 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_CORE_H__
-#define __BMESH_CORE_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -128,5 +127,3 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
BMVert *bmesh_kernel_unglue_region_make_vert(BMesh *bm, BMLoop *l_sep);
BMVert *bmesh_kernel_unglue_region_make_vert_multi(BMesh *bm, BMLoop **larr, int larr_len);
BMVert *bmesh_kernel_unglue_region_make_vert_multi_isolated(BMesh *bm, BMLoop *l_sep);
-
-#endif /* __BMESH_CORE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_delete.h b/source/blender/bmesh/intern/bmesh_delete.h
index d41f26baddd..fcbcb8a90fc 100644
--- a/source/blender/bmesh/intern/bmesh_delete.h
+++ b/source/blender/bmesh/intern/bmesh_delete.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_DELETE_H__
-#define __BMESH_DELETE_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -26,5 +25,3 @@ void BM_mesh_delete_hflag_tagged(BMesh *bm, const char hflag, const char htype);
void BMO_mesh_delete_oflag_context(BMesh *bm, const short oflag, const int type);
void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type);
-
-#endif /* __BMESH_DELETE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.h b/source/blender/bmesh/intern/bmesh_edgeloop.h
index 4c76ea4f9cf..2e5c4d0193e 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.h
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BMESH_EDGELOOP_H__
-#define __BMESH_EDGELOOP_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -84,5 +83,3 @@ bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a,
#define BM_EDGELOOP_NEXT(el_store) \
(CHECK_TYPE_INLINE(el_store, struct BMEdgeLoopStore *), \
(struct BMEdgeLoopStore *)((LinkData *)el_store)->next)
-
-#endif /* __BMESH_EDGELOOP_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_error.h b/source/blender/bmesh/intern/bmesh_error.h
index 289b603d134..2307377fd71 100644
--- a/source/blender/bmesh/intern/bmesh_error.h
+++ b/source/blender/bmesh/intern/bmesh_error.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_ERROR_H__
-#define __BMESH_ERROR_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -84,5 +83,3 @@ enum {
_BMESH_DUMMY_ABORT(), \
NULL)) : \
NULL)
-
-#endif /* __BMESH_ERROR_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_inline.h b/source/blender/bmesh/intern/bmesh_inline.h
index 13691776a27..203f44a540d 100644
--- a/source/blender/bmesh/intern/bmesh_inline.h
+++ b/source/blender/bmesh/intern/bmesh_inline.h
@@ -20,8 +20,7 @@
* BM Inline functions.
*/
-#ifndef __BMESH_INLINE_H__
-#define __BMESH_INLINE_H__
+#pragma once
/* stuff for dealing with header flags */
#define BM_elem_flag_test(ele, hflag) _bm_elem_flag_test(&(ele)->head, hflag)
@@ -135,5 +134,3 @@ BLI_INLINE int _bm_elem_index_get(const BMHeader *head)
{
return head->index;
}
-
-#endif /* __BMESH_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h
index bd3824ed3fd..0399b796cfd 100644
--- a/source/blender/bmesh/intern/bmesh_interp.h
+++ b/source/blender/bmesh/intern/bmesh_interp.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_INTERP_H__
-#define __BMESH_INTERP_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -82,5 +81,3 @@ void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm,
struct LinkNode *groups,
const int layer_n,
const float *loop_weights);
-
-#endif /* __BMESH_INTERP_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h
index a809c9a3d32..9314e23b21f 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.h
+++ b/source/blender/bmesh/intern/bmesh_iterators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_ITERATORS_H__
-#define __BMESH_ITERATORS_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -252,5 +251,3 @@ BMITER_CB_DEF(loop_of_face);
(BM_ITER_CHECK_TYPE_DATA(data), BM_iter_new(iter, bm, itype, data))
#define BM_iter_init(iter, bm, itype, data) \
(BM_ITER_CHECK_TYPE_DATA(data), BM_iter_init(iter, bm, itype, data))
-
-#endif /* __BMESH_ITERATORS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_iterators_inline.h b/source/blender/bmesh/intern/bmesh_iterators_inline.h
index 4b9fbf52630..c384fb03cd9 100644
--- a/source/blender/bmesh/intern/bmesh_iterators_inline.h
+++ b/source/blender/bmesh/intern/bmesh_iterators_inline.h
@@ -20,8 +20,7 @@
* BMesh inline iterator functions.
*/
-#ifndef __BMESH_ITERATORS_INLINE_H__
-#define __BMESH_ITERATORS_INLINE_H__
+#pragma once
/* inline here optimizes out the switch statement when called with
* constant values (which is very common), nicer for loop-in-loop situations */
@@ -210,5 +209,3 @@ BLI_INLINE void BM_iter_parallel(BMesh *bm,
}
#endif /* __BLI_TASK_H__ */
-
-#endif /* __BMESH_ITERATORS_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h
index 25c58132802..5c0ca78bddf 100644
--- a/source/blender/bmesh/intern/bmesh_log.h
+++ b/source/blender/bmesh/intern/bmesh_log.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_LOG_H__
-#define __BMESH_LOG_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -98,5 +97,3 @@ void BM_log_original_vert_data(BMLog *log, BMVert *v, const float **r_co, const
/* For internal use only (unit testing) */
BMLogEntry *BM_log_current_entry(BMLog *log);
struct RangeTreeUInt *BM_log_unused_ids(BMLog *log);
-
-#endif
diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h
index 06314a7a388..958980bdc23 100644
--- a/source/blender/bmesh/intern/bmesh_marking.h
+++ b/source/blender/bmesh/intern/bmesh_marking.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_MARKING_H__
-#define __BMESH_MARKING_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -137,5 +136,3 @@ void BM_select_history_merge_from_targetmap(
(bm)->selected = _bm_prev_selected; \
} \
(void)0
-
-#endif /* __BMESH_MARKING_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index ffe84f93679..8eed3141c7f 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -2377,6 +2377,27 @@ BMFace *BM_face_at_index_find(BMesh *bm, const int index)
return BLI_mempool_findelem(bm->fpool, index);
}
+BMLoop *BM_loop_at_index_find(BMesh *bm, const int index)
+{
+ BMIter iter;
+ BMFace *f;
+ int i = index;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (i < f->len) {
+ BMLoop *l_first, *l_iter;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (i == 0) {
+ return l_iter;
+ }
+ i -= 1;
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ i -= f->len;
+ }
+ return NULL;
+}
+
/**
* Use lookup table when available, else use slower find functions.
*
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 4ba0d948499..a6b8b629ddf 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_MESH_H__
-#define __BMESH_MESH_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -118,6 +117,7 @@ BLI_INLINE BMFace *BM_face_at_index(BMesh *bm, const int index)
BMVert *BM_vert_at_index_find(BMesh *bm, const int index);
BMEdge *BM_edge_at_index_find(BMesh *bm, const int index);
BMFace *BM_face_at_index_find(BMesh *bm, const int index);
+BMLoop *BM_loop_at_index_find(BMesh *bm, const int index);
BMVert *BM_vert_at_index_find_or_table(BMesh *bm, const int index);
BMEdge *BM_edge_at_index_find_or_table(BMesh *bm, const int index);
@@ -170,5 +170,3 @@ void BM_mesh_vert_coords_apply(BMesh *bm, const float (*orco)[3]);
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
const float (*vert_coords)[3],
const float mat[4][4]);
-
-#endif /* __BMESH_MESH_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.h b/source/blender/bmesh/intern/bmesh_mesh_convert.h
index 1ad43558c60..1b5d001d35d 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BMESH_MESH_CONV_H__
-#define __BMESH_MESH_CONV_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -71,5 +70,3 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm,
struct Mesh *me,
const struct CustomData_MeshMasks *cd_mask_extra)
ATTR_NONNULL(1, 2);
-
-#endif /* __BMESH_MESH_CONV_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_duplicate.h b/source/blender/bmesh/intern/bmesh_mesh_duplicate.h
index 17d4071b69f..8ace555d61f 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_duplicate.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_duplicate.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_MESH_DUPLICATE_H__
-#define __BMESH_MESH_DUPLICATE_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -29,5 +28,3 @@ void BM_mesh_copy_arrays(BMesh *bm_src,
uint edges_src_len,
BMFace **faces_src,
uint faces_src_len);
-
-#endif /* __BMESH_MESH_DUPLICATE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_validate.h b/source/blender/bmesh/intern/bmesh_mesh_validate.h
index 32bb4fb023b..2112e1f3200 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_validate.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_validate.h
@@ -17,13 +17,10 @@
* All rights reserved.
*/
-#ifndef __BMESH_MESH_VALIDATE_H__
-#define __BMESH_MESH_VALIDATE_H__
+#pragma once
/** \file
* \ingroup bmesh
*/
bool BM_mesh_validate(BMesh *bm);
-
-#endif /* __BMESH_MESH_VALIDATE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h
index 36cb85bc9bc..8099d1dd603 100644
--- a/source/blender/bmesh/intern/bmesh_mods.h
+++ b/source/blender/bmesh/intern/bmesh_mods.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_MODS_H__
-#define __BMESH_MODS_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -94,5 +93,3 @@ enum {
BMVert *BM_face_loop_separate(BMesh *bm, BMLoop *l_sep);
BMVert *BM_face_loop_separate_multi_isolated(BMesh *bm, BMLoop *l_sep);
BMVert *BM_face_loop_separate_multi(BMesh *bm, BMLoop **larr, int larr_len);
-
-#endif /* __BMESH_MODS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 67c0fdba12b..4117ad67dd3 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -1755,6 +1755,12 @@ static BMO_FlagSet bmo_enum_bevel_vmesh_method[] = {
{0, NULL},
};
+static BMO_FlagSet bmo_enum_bevel_affect_type[] = {
+ {BEVEL_AFFECT_VERTICES, "VERTICES"},
+ {BEVEL_AFFECT_EDGES, "EDGES"},
+ {0, NULL},
+};
+
/*
* Bevel.
*
@@ -1768,10 +1774,11 @@ static BMOpDefine bmo_bevel_def = {
{"offset_type", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
bmo_enum_bevel_offset_type}, /* how to measure the offset */
{"profile_type", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
- bmo_enum_bevel_profile_type}, /* The profile type to use for bevel. */
+ bmo_enum_bevel_profile_type}, /* The profile type to use for bevel. */
{"segments", BMO_OP_SLOT_INT}, /* number of segments in bevel */
{"profile", BMO_OP_SLOT_FLT}, /* profile shape, 0->1 (.5=>round) */
- {"vertex_only", BMO_OP_SLOT_BOOL}, /* only bevel vertices, not edges */
+ {"affect", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
+ bmo_enum_bevel_affect_type}, /* Whether to bevel vertices or edges. */
{"clamp_overlap", BMO_OP_SLOT_BOOL}, /* do not allow beveled edges/vertices to overlap each other */
{"material", BMO_OP_SLOT_INT}, /* material for bevel faces, -1 means get from adjacent faces */
{"loop_slide", BMO_OP_SLOT_BOOL}, /* prefer to slide along edges to having even widths */
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 5af812d1b1d..a9282b8e5d0 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_OPERATOR_API_H__
-#define __BMESH_OPERATOR_API_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -668,5 +667,3 @@ int BMO_opcode_from_opname(const char *opname);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BMESH_OPERATOR_API_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
index 2bda2d121c2..43628f01bc8 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
@@ -20,8 +20,7 @@
* BMesh inline operator functions.
*/
-#ifndef __BMESH_OPERATOR_API_INLINE_H__
-#define __BMESH_OPERATOR_API_INLINE_H__
+#pragma once
/* tool flag API. never, ever ever should tool code put junk in
* header flags (element->head.flag), nor should they use
@@ -236,5 +235,3 @@ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
return NULL;
}
-
-#endif /* __BMESH_OPERATOR_API_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 29fcf7ca0ca..2f7d91c78c4 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_OPERATORS_H__
-#define __BMESH_OPERATORS_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -139,6 +138,12 @@ enum {
BEVEL_VMESH_CUTOFF,
};
+/* Bevel affect option. */
+enum {
+ BEVEL_AFFECT_VERTICES = 0,
+ BEVEL_AFFECT_EDGES = 1,
+};
+
/* Normal Face Strength values */
enum {
FACE_STRENGTH_WEAK = -16384,
@@ -187,5 +192,3 @@ void BM_mesh_calc_uvs_cone(BMesh *bm,
void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag);
#include "intern/bmesh_operator_api_inline.h"
-
-#endif /* __BMESH_OPERATORS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 137c5aa338e..1c53c3d5c89 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_OPERATORS_PRIVATE_H__
-#define __BMESH_OPERATORS_PRIVATE_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -103,5 +102,3 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op);
void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op);
void bmo_weld_verts_exec(BMesh *bm, BMOperator *op);
void bmo_wireframe_exec(BMesh *bm, BMOperator *op);
-
-#endif /* __BMESH_OPERATORS_PRIVATE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 0b93db6a91e..06bab8c8cc1 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -163,7 +163,7 @@ void BM_face_calc_tessellation(const BMFace *f,
float(*projverts)[2] = BLI_array_alloca(projverts, f->len);
int j;
- axis_dominant_v3_to_m3(axis_mat, f->no);
+ axis_dominant_v3_to_m3_negate(axis_mat, f->no);
j = 0;
l_iter = l_first;
@@ -174,7 +174,7 @@ void BM_face_calc_tessellation(const BMFace *f,
} while ((l_iter = l_iter->next) != l_first);
/* complete the loop */
- BLI_polyfill_calc(projverts, f->len, -1, r_index);
+ BLI_polyfill_calc(projverts, f->len, 1, r_index);
}
}
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index 1611bc0b893..d9413e303e3 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_POLYGON_H__
-#define __BMESH_POLYGON_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -114,5 +113,3 @@ void BM_face_as_array_loop_quad(BMFace *f, BMLoop *r_loops[4]) ATTR_NONNULL();
void BM_vert_tri_calc_tangent_edge(BMVert *verts[3], float r_tangent[3]);
void BM_vert_tri_calc_tangent_edge_pair(BMVert *verts[3], float r_tangent[3]);
-
-#endif /* __BMESH_POLYGON_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.h b/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
index 38af944d0cd..6833f067421 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_POLYGON_EDGENET_H__
-#define __BMESH_POLYGON_EDGENET_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -37,5 +36,3 @@ bool BM_face_split_edgenet_connect_islands(BMesh *bm,
BMEdge ***r_edge_net_new,
uint *r_edge_net_new_len) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1, 2, 3, 6, 7, 8);
-
-#endif /* __BMESH_POLYGON_EDGENET_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h
index 8b4a59d5b9b..2c3bac6df33 100644
--- a/source/blender/bmesh/intern/bmesh_private.h
+++ b/source/blender/bmesh/intern/bmesh_private.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BMESH_PRIVATE_H__
-#define __BMESH_PRIVATE_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -90,5 +89,3 @@ void poly_rotate_plane(const float normal[3], float (*verts)[3], const uint nver
/* include the rest of our private declarations */
#include "bmesh_structure.h"
-
-#endif /* __BMESH_PRIVATE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_query.c b/source/blender/bmesh/intern/bmesh_query.c
index fe67abf6aa5..80634618f6f 100644
--- a/source/blender/bmesh/intern/bmesh_query.c
+++ b/source/blender/bmesh/intern/bmesh_query.c
@@ -158,6 +158,37 @@ BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v)
}
/**
+ * Return the other loop that uses this edge.
+ *
+ * In this case the loop defines the vertex,
+ * the edge passed in defines the direction to step.
+ *
+ * <pre>
+ * +----------+ <-- Return the face-loop of this vertex.
+ * | |
+ * | e | <-- This edge defines the direction.
+ * | |
+ * +----------+ <-- This loop defines the face and vertex..
+ * l
+ * </pre>
+ *
+ */
+BMLoop *BM_loop_other_vert_loop_by_edge(BMLoop *l, BMEdge *e)
+{
+ BLI_assert(BM_vert_in_edge(e, l->v));
+ if (l->e == e) {
+ return l->next;
+ }
+ else if (l->prev->e == e) {
+ return l->prev;
+ }
+ else {
+ BLI_assert(0);
+ return NULL;
+ }
+}
+
+/**
* Check if verts share a face.
*/
bool BM_vert_pair_share_face_check(BMVert *v_a, BMVert *v_b)
diff --git a/source/blender/bmesh/intern/bmesh_query.h b/source/blender/bmesh/intern/bmesh_query.h
index 7e07059d4d8..4ec6b0e50d1 100644
--- a/source/blender/bmesh/intern/bmesh_query.h
+++ b/source/blender/bmesh/intern/bmesh_query.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_QUERY_H__
-#define __BMESH_QUERY_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -48,6 +47,8 @@ BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v) ATTR_WARN_UNUSE
BMLoop *BM_loop_other_edge_loop(BMLoop *l, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
+BMLoop *BM_loop_other_vert_loop_by_edge(BMLoop *l, BMEdge *e) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -171,7 +172,6 @@ float BM_edge_calc_face_angle_with_imat3(const BMEdge *e,
float BM_edge_calc_face_angle_signed(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3])
ATTR_NONNULL();
-
float BM_vert_calc_edge_angle(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
float BM_vert_calc_edge_angle_ex(const BMVert *v, const float fallback) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
@@ -272,5 +272,3 @@ int BM_mesh_calc_edge_groups_as_arrays(BMesh *bm,
float bmesh_subd_falloff_calc(const int falloff, float val) ATTR_WARN_UNUSED_RESULT;
#include "bmesh_query_inline.h"
-
-#endif /* __BMESH_QUERY_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_query_inline.h b/source/blender/bmesh/intern/bmesh_query_inline.h
index 90919cc361b..8b12ccace20 100644
--- a/source/blender/bmesh/intern/bmesh_query_inline.h
+++ b/source/blender/bmesh/intern/bmesh_query_inline.h
@@ -18,8 +18,7 @@
* \ingroup bmesh
*/
-#ifndef __BMESH_QUERY_INLINE_H__
-#define __BMESH_QUERY_INLINE_H__
+#pragma once
/**
* Returns whether or not a given vertex is
@@ -152,5 +151,3 @@ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE bool BM_vert_is_wire_endpoint
}
return false;
}
-
-#endif /* __BMESH_QUERY_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_query_uv.c b/source/blender/bmesh/intern/bmesh_query_uv.c
new file mode 100644
index 00000000000..b9ea51f0c4d
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_query_uv.c
@@ -0,0 +1,169 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bmesh
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_alloca.h"
+#include "BLI_linklist.h"
+#include "BLI_math.h"
+#include "BLI_utildefines_stack.h"
+
+#include "BKE_customdata.h"
+
+#include "DNA_meshdata_types.h"
+
+#include "bmesh.h"
+#include "intern/bmesh_private.h"
+
+static void uv_aspect(const BMLoop *l,
+ const float aspect[2],
+ const int cd_loop_uv_offset,
+ float r_uv[2])
+{
+ const float *uv = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv;
+ r_uv[0] = uv[0] * aspect[0];
+ r_uv[1] = uv[1] * aspect[1];
+}
+
+/**
+ * Typically we avoid hiding arguments,
+ * make this an exception since it reads poorly with so many repeated arguments.
+ */
+#define UV_ASPECT(l, r_uv) uv_aspect(l, aspect, cd_loop_uv_offset, r_uv)
+
+/**
+ * Computes the UV center of a face, using the mean average weighted by edge length.
+ *
+ * See #BM_face_calc_center_median_weighted for matching spatial functionality.
+ *
+ * \param aspect: Calculate the center scaling by these values, and finally dividing.
+ * Since correct weighting depends on having the correct aspect.
+ */
+void BM_face_uv_calc_center_median_weighted(const BMFace *f,
+ const float aspect[2],
+ const int cd_loop_uv_offset,
+ float r_cent[2])
+{
+ const BMLoop *l_iter;
+ const BMLoop *l_first;
+ float totw = 0.0f;
+ float w_prev;
+
+ zero_v2(r_cent);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+
+ float uv_prev[2], uv_curr[2];
+ UV_ASPECT(l_iter->prev, uv_prev);
+ UV_ASPECT(l_iter, uv_curr);
+ w_prev = len_v2v2(uv_prev, uv_curr);
+ do {
+ float uv_next[2];
+ UV_ASPECT(l_iter->next, uv_next);
+ const float w_curr = len_v2v2(uv_curr, uv_next);
+ const float w = (w_curr + w_prev);
+ madd_v2_v2fl(r_cent, uv_curr, w);
+ totw += w;
+ w_prev = w_curr;
+ copy_v2_v2(uv_curr, uv_next);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (totw != 0.0f) {
+ mul_v2_fl(r_cent, 1.0f / (float)totw);
+ }
+ /* Reverse aspect. */
+ r_cent[0] /= aspect[0];
+ r_cent[1] /= aspect[1];
+}
+
+#undef UV_ASPECT
+
+/**
+ * Calculate the UV cross product (use the sign to check the winding).
+ */
+float BM_face_uv_calc_cross(const BMFace *f, const int cd_loop_uv_offset)
+{
+ float(*uvs)[2] = BLI_array_alloca(uvs, f->len);
+ const BMLoop *l_iter;
+ const BMLoop *l_first;
+ int i = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
+ copy_v2_v2(uvs[i++], luv->uv);
+ } while ((l_iter = l_iter->next) != l_first);
+ return cross_poly_v2(uvs, f->len);
+}
+
+/**
+ * Check if two loops that share an edge also have the same UV coordinates.
+ */
+bool BM_loop_uv_share_edge_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset)
+{
+ BLI_assert(l_a->e == l_b->e);
+ MLoopUV *luv_a_curr = BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset);
+ MLoopUV *luv_a_next = BM_ELEM_CD_GET_VOID_P(l_a->next, cd_loop_uv_offset);
+ MLoopUV *luv_b_curr = BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset);
+ MLoopUV *luv_b_next = BM_ELEM_CD_GET_VOID_P(l_b->next, cd_loop_uv_offset);
+ if (l_a->v != l_b->v) {
+ SWAP(MLoopUV *, luv_b_curr, luv_b_next);
+ }
+ return (equals_v2v2(luv_a_curr->uv, luv_b_curr->uv) &&
+ equals_v2v2(luv_a_next->uv, luv_b_next->uv));
+}
+
+/**
+ * Check if two loops that share a vertex also have the same UV coordinates.
+ */
+bool BM_loop_uv_share_vert_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset)
+{
+ BLI_assert(l_a->v == l_b->v);
+ const MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset);
+ const MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset);
+ if (!equals_v2v2(luv_a->uv, luv_b->uv)) {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Check if two loops that share a vertex also have the same UV coordinates.
+ */
+bool BM_edge_uv_share_vert_check(BMEdge *e, BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset)
+{
+ BLI_assert(l_a->v == l_b->v);
+ if (!BM_loop_uv_share_vert_check(l_a, l_b, cd_loop_uv_offset)) {
+ return false;
+ }
+
+ /* No need for NULL checks, these will always succeed. */
+ const BMLoop *l_other_a = BM_loop_other_vert_loop_by_edge(l_a, e);
+ const BMLoop *l_other_b = BM_loop_other_vert_loop_by_edge(l_b, e);
+
+ {
+ const MLoopUV *luv_other_a = BM_ELEM_CD_GET_VOID_P(l_other_a, cd_loop_uv_offset);
+ const MLoopUV *luv_other_b = BM_ELEM_CD_GET_VOID_P(l_other_b, cd_loop_uv_offset);
+ if (!equals_v2v2(luv_other_a->uv, luv_other_b->uv)) {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/source/blender/bmesh/intern/bmesh_query_uv.h b/source/blender/bmesh/intern/bmesh_query_uv.h
new file mode 100644
index 00000000000..3465a831bea
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_query_uv.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bmesh
+ */
+
+float BM_loop_uv_calc_edge_length_squared(const BMLoop *l,
+ const int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+float BM_loop_uv_calc_edge_length(const BMLoop *l,
+ const int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+
+void BM_face_uv_calc_center_median_weighted(const BMFace *f,
+ const float aspect[2],
+ const int cd_loop_uv_offset,
+ float r_cent[2]) ATTR_NONNULL();
+
+float BM_face_uv_calc_cross(const BMFace *f, const int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+
+bool BM_loop_uv_share_edge_check_with_limit(BMLoop *l_a,
+ BMLoop *l_b,
+ const float limit[2],
+ const int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+
+bool BM_loop_uv_share_edge_check(BMLoop *l_a,
+ BMLoop *l_b,
+ const int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+
+bool BM_edge_uv_share_vert_check(BMEdge *e, BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset)
+ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+
+bool BM_loop_uv_share_vert_check(BMLoop *l_a,
+ BMLoop *l_b,
+ const int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h
index 38c75dec354..b3b9536618c 100644
--- a/source/blender/bmesh/intern/bmesh_structure.h
+++ b/source/blender/bmesh/intern/bmesh_structure.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BMESH_STRUCTURE_H__
-#define __BMESH_STRUCTURE_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -93,5 +92,3 @@ BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2) ATTR_WARN_UNU
bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
#include "intern/bmesh_structure_inline.h"
-
-#endif /* __BMESH_STRUCTURE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_structure_inline.h b/source/blender/bmesh/intern/bmesh_structure_inline.h
index 26d161693af..85a84dde4ad 100644
--- a/source/blender/bmesh/intern/bmesh_structure_inline.h
+++ b/source/blender/bmesh/intern/bmesh_structure_inline.h
@@ -20,8 +20,7 @@
* BMesh inline operator functions.
*/
-#ifndef __BMESH_STRUCTURE_INLINE_H__
-#define __BMESH_STRUCTURE_INLINE_H__
+#pragma once
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
BLI_INLINE BMDiskLink *bmesh_disk_edge_link_from_vert(const BMEdge *e, const BMVert *v)
@@ -72,5 +71,3 @@ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE BMEdge *bmesh_disk_edge_pr
{
return BM_DISK_EDGE_PREV(e, v);
}
-
-#endif /* __BMESH_STRUCTURE_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_walkers.h b/source/blender/bmesh/intern/bmesh_walkers.h
index 0b862a5e9a1..a973e12a4c7 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.h
+++ b/source/blender/bmesh/intern/bmesh_walkers.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_WALKERS_H__
-#define __BMESH_WALKERS_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -130,5 +129,3 @@ enum {
/* use with BMW_init, so as not to confuse with restrict flags */
#define BMW_NIL_LAY 0
-
-#endif /* __BMESH_WALKERS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_walkers_private.h b/source/blender/bmesh/intern/bmesh_walkers_private.h
index 3457a2b9187..721f3c2c65b 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_private.h
+++ b/source/blender/bmesh/intern/bmesh_walkers_private.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_WALKERS_PRIVATE_H__
-#define __BMESH_WALKERS_PRIVATE_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -94,5 +93,3 @@ typedef struct BMwConnectedVertexWalker {
BMwGenericWalker header;
BMVert *curvert;
} BMwConnectedVertexWalker;
-
-#endif /* __BMESH_WALKERS_PRIVATE_H__ */
diff --git a/source/blender/bmesh/operators/bmo_beautify.c b/source/blender/bmesh/operators/bmo_beautify.c
index 36122e06e9b..de26ca5ebd2 100644
--- a/source/blender/bmesh/operators/bmo_beautify.c
+++ b/source/blender/bmesh/operators/bmo_beautify.c
@@ -39,7 +39,10 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
BMFace *f;
BMEdge *e;
const bool use_restrict_tag = BMO_slot_bool_get(op->slots_in, "use_restrict_tag");
- const short flag = (use_restrict_tag ? VERT_RESTRICT_TAG : 0);
+ const short flag =
+ ((use_restrict_tag ? VERT_RESTRICT_TAG : 0) |
+ /* Enable to avoid iterative edge rotation to cause the direction of faces to flip. */
+ EDGE_RESTRICT_DEGENERATE);
const short method = (short)BMO_slot_int_get(op->slots_in, "method");
BMEdge **edge_array;
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c
index 67f875ac262..4e708b595e0 100644
--- a/source/blender/bmesh/operators/bmo_bevel.c
+++ b/source/blender/bmesh/operators/bmo_bevel.c
@@ -35,7 +35,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
const int offset_type = BMO_slot_int_get(op->slots_in, "offset_type");
const int profile_type = BMO_slot_int_get(op->slots_in, "profile_type");
const int seg = BMO_slot_int_get(op->slots_in, "segments");
- const bool vonly = BMO_slot_bool_get(op->slots_in, "vertex_only");
+ const int affect_type = BMO_slot_int_get(op->slots_in, "affect");
const float profile = BMO_slot_float_get(op->slots_in, "profile");
const bool clamp_overlap = BMO_slot_bool_get(op->slots_in, "clamp_overlap");
const int material = BMO_slot_int_get(op->slots_in, "material");
@@ -79,7 +79,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
profile_type,
seg,
profile,
- vonly,
+ affect_type,
false,
clamp_overlap,
NULL,
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index c6813a864a8..0789000969e 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -280,7 +280,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
* last resort when all else fails.
*/
if (totv > 2) {
- /* TODO, some of these vertes may be connected by edges,
+ /* TODO, some of these vertices may be connected by edges,
* this connectivity could be used rather than treating
* them as a bunch of isolated verts. */
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 3c63f4a60d6..eee31969971 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -572,6 +572,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
f = BM_face_create_verts(bm, f_verts, 4, NULL, BM_CREATE_NOP, true);
#endif
+ bm_extrude_copy_face_loop_attributes(bm, f);
if (join_face) {
BMVert *v1 = e->v1;
BMVert *v2 = e->v2;
@@ -583,11 +584,11 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, v2, EXT_TAG);
dissolve_verts[dissolve_verts_len++] = v2;
}
+ /* Tag the edges that can collapse. */
+ BMO_elem_flag_enable(bm, f_edges[0], EXT_TAG);
+ BMO_elem_flag_enable(bm, f_edges[1], EXT_TAG);
bmesh_kernel_join_face_kill_edge(bm, join_face, f, e);
}
- else {
- bm_extrude_copy_face_loop_attributes(bm, f);
- }
}
/* link isolated vert */
@@ -613,7 +614,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMEdge *e_other = BM_DISK_EDGE_NEXT(e, v);
if ((e_other == e) || (BM_DISK_EDGE_NEXT(e_other, v) == e)) {
/* Lose edge or BMVert is edge pair. */
- BM_edge_collapse(bm, e, v, true, false);
+ BM_edge_collapse(bm, BMO_elem_flag_test(bm, e, EXT_TAG) ? e : e_other, v, true, false);
}
else {
BLI_assert(!BM_vert_is_edge_pair(v));
diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c
index c877c534376..a25e4666a22 100644
--- a/source/blender/bmesh/tools/bmesh_beautify.c
+++ b/source/blender/bmesh/tools/bmesh_beautify.c
@@ -141,7 +141,8 @@ static void erot_state_alternate(const BMEdge *e, EdRotState *e_state)
static float bm_edge_calc_rotate_beauty__area(const float v1[3],
const float v2[3],
const float v3[3],
- const float v4[3])
+ const float v4[3],
+ const bool lock_degenerate)
{
/* not a loop (only to be able to break out) */
do {
@@ -199,7 +200,8 @@ static float bm_edge_calc_rotate_beauty__area(const float v1[3],
* Allowing to rotate out of a degenerate state can flip the faces
* (when performed iteratively).
*/
- return BLI_polyfill_beautify_quad_rotate_calc_ex(v1_xy, v2_xy, v3_xy, v4_xy, true, NULL);
+ return BLI_polyfill_beautify_quad_rotate_calc_ex(
+ v1_xy, v2_xy, v3_xy, v4_xy, lock_degenerate, NULL);
} while (false);
return FLT_MAX;
@@ -262,7 +264,8 @@ float BM_verts_calc_rotate_beauty(const BMVert *v1,
switch (method) {
case 0:
- return bm_edge_calc_rotate_beauty__area(v1->co, v2->co, v3->co, v4->co);
+ return bm_edge_calc_rotate_beauty__area(
+ v1->co, v2->co, v3->co, v4->co, flag & EDGE_RESTRICT_DEGENERATE);
default:
return bm_edge_calc_rotate_beauty__angle(v1->co, v2->co, v3->co, v4->co);
}
diff --git a/source/blender/bmesh/tools/bmesh_beautify.h b/source/blender/bmesh/tools/bmesh_beautify.h
index f957f0d3560..d0fef828e7c 100644
--- a/source/blender/bmesh/tools/bmesh_beautify.h
+++ b/source/blender/bmesh/tools/bmesh_beautify.h
@@ -14,15 +14,17 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_BEAUTIFY_H__
-#define __BMESH_BEAUTIFY_H__
+#pragma once
/** \file
* \ingroup bmesh
*/
enum {
+ /** Vertices tags must match (special case). */
VERT_RESTRICT_TAG = (1 << 0),
+ /** Don't rotate out of degenerate state (needed for iterative rotation). */
+ EDGE_RESTRICT_DEGENERATE = (1 << 1),
};
void BM_mesh_beautify_fill(BMesh *bm,
@@ -39,5 +41,3 @@ float BM_verts_calc_rotate_beauty(const BMVert *v1,
const BMVert *v4,
const short flag,
const short method);
-
-#endif /* __BMESH_BEAUTIFY_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index b29d471d262..f263392bdd2 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -45,6 +45,11 @@
#include "./intern/bmesh_private.h"
+// #define BEVEL_DEBUG_TIME
+#ifdef BEVEL_DEBUG_TIME
+# include "PIL_time.h"
+#endif
+
#define BEVEL_EPSILON_D 1e-6
#define BEVEL_EPSILON 1e-6f
#define BEVEL_EPSILON_SQ 1e-12f
@@ -266,7 +271,7 @@ typedef struct BevVert {
int selcount;
/** Count of wire edges. */
int wirecount;
- /** Offset for this vertex, if vertex_only bevel. */
+ /** Offset for this vertex, if vertex only bevel. */
float offset;
/** Any seams on attached edges? */
bool any_seam;
@@ -325,14 +330,14 @@ typedef struct BevelParams {
int offset_type;
/** Profile type: radius, superellipse, or custom */
int profile_type;
+ /** Bevel vertices only or edges. */
+ int affect_type;
/** Number of segments in beveled edge profile. */
int seg;
/** User profile setting. */
float profile;
/** Superellipse parameter for edge profile. */
float pro_super_r;
- /** Bevel vertices only. */
- bool vertex_only;
/** Bevel amount affected by weights on edges or verts. */
bool use_weights;
/** Should bevel prefer to slide along edges rather than keep widths spec? */
@@ -350,9 +355,9 @@ typedef struct BevelParams {
char _pad[1];
/** The struct used to store the custom profile input. */
const struct CurveProfile *custom_profile;
- /** Vertex group array, maybe set if vertex_only. */
+ /** Vertex group array, maybe set if vertex only. */
const struct MDeformVert *dvert;
- /** Vertex group index, maybe set if vertex_only. */
+ /** Vertex group index, maybe set if vertex only. */
int vertex_group;
/** If >= 0, material number for bevel; else material comes from adjacent faces. */
int mat_nr;
@@ -782,6 +787,7 @@ static bool contig_ldata_across_edge(BMesh *bm, BMEdge *e, BMFace *f1, BMFace *f
BMLoop *lef1, *lef2;
BMLoop *lv1f1, *lv1f2, *lv2f1, *lv2f2;
BMVert *v1, *v2;
+ UNUSED_VARS_NDEBUG(v1, v2);
int i;
if (bm->ldata.totlayer == 0) {
@@ -834,6 +840,7 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm)
BMFace *bmf, *bmf_other;
BMEdge *bme;
BMFace **stack;
+ bool *in_stack;
BMIter eiter, fiter;
bp->math_layer_info.has_math_layers = false;
@@ -854,24 +861,29 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm)
face_component = BLI_memarena_alloc(bp->mem_arena, totface * sizeof(int));
bp->math_layer_info.face_component = face_component;
+ /* Use an array as a stack. Stack size can't exceed total faces if keep track of what is in
+ * stack. */
+ stack = MEM_malloc_arrayN(totface, sizeof(BMFace *), __func__);
+ in_stack = MEM_malloc_arrayN(totface, sizeof(bool), __func__);
+
/* Set all component ids by DFS from faces with unassigned components. */
for (f = 0; f < totface; f++) {
face_component[f] = -1;
+ in_stack[f] = false;
}
current_component = -1;
-
- /* Use an array as a stack. Stack size can't exceed double total faces. */
- stack = MEM_malloc_arrayN(2 * totface, sizeof(BMFace *), __func__);
for (f = 0; f < totface; f++) {
- if (face_component[f] == -1) {
+ if (face_component[f] == -1 && !in_stack[f]) {
stack_top = 0;
current_component++;
- BLI_assert(stack_top < 2 * totface);
+ BLI_assert(stack_top < totface);
stack[stack_top] = BM_face_at_index(bm, f);
+ in_stack[f] = true;
while (stack_top >= 0) {
bmf = stack[stack_top];
stack_top--;
bmf_index = BM_elem_index_get(bmf);
+ in_stack[bmf_index] = false;
if (face_component[bmf_index] != -1) {
continue;
}
@@ -884,13 +896,14 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm)
BM_ITER_ELEM (bmf_other, &fiter, bme, BM_FACES_OF_EDGE) {
if (bmf_other != bmf) {
bmf_other_index = BM_elem_index_get(bmf_other);
- if (face_component[bmf_other_index] != -1) {
+ if (face_component[bmf_other_index] != -1 || in_stack[bmf_other_index]) {
continue;
}
if (contig_ldata_across_edge(bm, bme, bmf, bmf_other)) {
stack_top++;
- BLI_assert(stack_top < 2 * totface);
+ BLI_assert(stack_top < totface);
stack[stack_top] = bmf_other;
+ in_stack[bmf_other_index] = true;
}
}
}
@@ -899,6 +912,7 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm)
}
}
MEM_freeN(stack);
+ MEM_freeN(in_stack);
}
/**
@@ -908,7 +922,7 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm)
* segment (and its continuation into vmesh) can usually arbitrarily be
* the previous face or the next face.
* Or, for the center polygon of a corner, all of the faces around
- * the vertex are possible choices.
+ * the vertex are possibleface_component choices.
* If we just choose randomly, the resulting UV maps or material
* assignment can look ugly/inconsistent.
* Allow for the case when arguments are null.
@@ -1352,8 +1366,9 @@ static void offset_meet(EdgeHalf *e1,
/**
* Calculate the meeting point between e1 and e2 (one of which should have zero offsets),
- * where e1 precedes e2 in CCW order around their common vertex v (viewed from normal side).
- * If r_angle is provided, return the angle between e and emeet in *r_angle.
+ * where \a e1 precedes \a e2 in CCW order around their common vertex \a v
+ * (viewed from normal side).
+ * If \a r_angle is provided, return the angle between \a e and \a meetco in `*r_angle`.
* If the angle is 0, or it is 180 degrees or larger, there will be no meeting point;
* return false in that case, else true.
*/
@@ -1602,7 +1617,7 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
zero_v3(pro->proj_dir);
do_linear_interp = false;
}
- else if (bp->vertex_only) {
+ else if (bp->affect_type == BEVEL_AFFECT_VERTICES) {
copy_v3_v3(pro->start, start);
copy_v3_v3(pro->middle, bv->v->co);
copy_v3_v3(pro->end, end);
@@ -1881,6 +1896,57 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int ns
}
/**
+ * Helper for #calculate_profile that builds the 3D locations for the segments
+ * and the higher power of 2 segments.
+ */
+static void calculate_profile_segments(const Profile *profile,
+ const float map[4][4],
+ const bool use_map,
+ const bool reversed,
+ const int ns,
+ const double *xvals,
+ const double *yvals,
+ float *r_prof_co)
+{
+ /* Iterate over the vertices along the boundary arc. */
+ for (int k = 0; k <= ns; k++) {
+ float co[3];
+ if (k == 0) {
+ copy_v3_v3(co, profile->start);
+ }
+ else if (k == ns) {
+ copy_v3_v3(co, profile->end);
+ }
+ else {
+ if (use_map) {
+ float p[3] = {reversed ? (float)yvals[ns - k] : (float)xvals[k],
+ reversed ? (float)xvals[ns - k] : (float)yvals[k],
+ 0.0f};
+ /* Do the 2D->3D transformation of the profile coordinates. */
+ mul_v3_m4v3(co, map, p);
+ }
+ else {
+ interp_v3_v3v3(co, profile->start, profile->end, (float)k / (float)ns);
+ }
+ }
+ /* Finish the 2D->3D transformation by projecting onto the final profile plane. */
+ float *prof_co_k = r_prof_co + 3 * k;
+ if (!is_zero_v3(profile->proj_dir)) {
+ float co2[3];
+ add_v3_v3v3(co2, co, profile->proj_dir);
+ /* pro->plane_co and pro->plane_no are filled in #set_profile_params. */
+ if (!isect_line_plane_v3(prof_co_k, co, co2, profile->plane_co, profile->plane_no)) {
+ /* Shouldn't happen. */
+ copy_v3_v3(prof_co_k, co);
+ }
+ }
+ else {
+ copy_v3_v3(prof_co_k, co);
+ }
+ }
+}
+
+/**
* Calculate the actual coordinate values for bndv's profile.
* This is only needed if bp->seg > 1.
* Allocate the space for them if that hasn't been done already.
@@ -1890,12 +1956,6 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int ns
*/
static void calculate_profile(BevelParams *bp, BoundVert *bndv, bool reversed, bool miter)
{
- int i, k, ns;
- const double *xvals, *yvals;
- float co[3], co2[3], p[3], map[4][4], bottom_corner[3], top_corner[3];
- float *prof_co, *prof_co_k;
- float r;
- bool need_2, map_ok;
Profile *pro = &bndv->profile;
ProfileSpacing *pro_spacing = (miter) ? &bp->pro_spacing_miter : &bp->pro_spacing;
@@ -1903,89 +1963,51 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv, bool reversed, b
return;
}
- need_2 = bp->seg != bp->pro_spacing.seg_2;
- if (!pro->prof_co) {
- pro->prof_co = (float *)BLI_memarena_alloc(bp->mem_arena,
- ((size_t)bp->seg + 1) * 3 * sizeof(float));
+ bool need_2 = bp->seg != bp->pro_spacing.seg_2;
+ if (pro->prof_co == NULL) {
+ pro->prof_co = (float *)BLI_memarena_alloc(bp->mem_arena, sizeof(float) * 3 * (bp->seg + 1));
if (need_2) {
pro->prof_co_2 = (float *)BLI_memarena_alloc(
- bp->mem_arena, ((size_t)bp->pro_spacing.seg_2 + 1) * 3 * sizeof(float));
+ bp->mem_arena, sizeof(float) * 3 * (bp->pro_spacing.seg_2 + 1));
}
else {
pro->prof_co_2 = pro->prof_co;
}
}
- r = pro->super_r;
- if (bp->profile_type == BEVEL_PROFILE_SUPERELLIPSE && r == PRO_LINE_R) {
- map_ok = false;
+
+ bool use_map;
+ float map[4][4];
+ if (bp->profile_type == BEVEL_PROFILE_SUPERELLIPSE && pro->super_r == PRO_LINE_R) {
+ use_map = false;
}
else {
- map_ok = make_unit_square_map(pro->start, pro->middle, pro->end, map);
+ use_map = make_unit_square_map(pro->start, pro->middle, pro->end, map);
}
- if (bp->vmesh_method == BEVEL_VMESH_CUTOFF && map_ok) {
+ if (bp->vmesh_method == BEVEL_VMESH_CUTOFF && use_map) {
/* Calculate the "height" of the profile by putting the (0,0) and (1,1) corners of the
* un-transformed profile through the 2D->3D map and calculating the distance between them. */
- zero_v3(p);
- mul_v3_m4v3(bottom_corner, map, p);
- p[0] = 1.0f;
- p[1] = 1.0f;
- mul_v3_m4v3(top_corner, map, p);
+ float bottom_corner[3] = {0.0f, 0.0f, 0.0f};
+ mul_v3_m4v3(bottom_corner, map, bottom_corner);
+ float top_corner[3] = {1.0f, 1.0f, 0.0f};
+ mul_v3_m4v3(top_corner, map, top_corner);
+
pro->height = len_v3v3(bottom_corner, top_corner);
}
- /* The first iteration is the nseg case, the second is the seg_2 case (if it's needed) .*/
- for (i = 0; i < 2; i++) {
- if (i == 0) {
- ns = bp->seg;
- xvals = pro_spacing->xvals;
- yvals = pro_spacing->yvals;
- prof_co = pro->prof_co;
- }
- else {
- if (!need_2) {
- break; /* Shares coords with pro->prof_co. */
- }
- ns = bp->pro_spacing.seg_2;
- xvals = pro_spacing->xvals_2;
- yvals = pro_spacing->yvals_2;
- prof_co = pro->prof_co_2;
- }
-
- /* Iterate over the vertices along the boundary arc. */
- for (k = 0; k <= ns; k++) {
- if (k == 0) {
- copy_v3_v3(co, pro->start);
- }
- else if (k == ns) {
- copy_v3_v3(co, pro->end);
- }
- else {
- if (map_ok) {
- p[0] = reversed ? (float)yvals[ns - k] : (float)xvals[k];
- p[1] = reversed ? (float)xvals[ns - k] : (float)yvals[k];
- p[2] = 0.0f;
- /* Do the 2D->3D transformation of the profile coordinates. */
- mul_v3_m4v3(co, map, p);
- }
- else {
- interp_v3_v3v3(co, pro->start, pro->end, (float)k / (float)ns);
- }
- }
- /* Finish the 2D->3D transformation by projecting onto the final profile plane. */
- prof_co_k = prof_co + 3 * k; /* Each coord takes up 3 spaces. */
- if (!is_zero_v3(pro->proj_dir)) {
- add_v3_v3v3(co2, co, pro->proj_dir);
- /* pro->plane_co and pro->plane_no are filled in "set_profile_params". */
- if (!isect_line_plane_v3(prof_co_k, co, co2, pro->plane_co, pro->plane_no)) {
- /* Shouldn't happen. */
- copy_v3_v3(prof_co_k, co);
- }
- }
- else {
- copy_v3_v3(prof_co_k, co);
- }
- }
+ /* Calculate the 3D locations for the profile points */
+ calculate_profile_segments(
+ pro, map, use_map, reversed, bp->seg, pro_spacing->xvals, pro_spacing->yvals, pro->prof_co);
+ /* Also calcualte for the is the seg_2 case if it's needed .*/
+ if (need_2) {
+ calculate_profile_segments(pro,
+ map,
+ use_map,
+ reversed,
+ bp->pro_spacing.seg_2,
+ pro_spacing->xvals_2,
+ pro_spacing->yvals_2,
+ pro->prof_co_2);
}
}
@@ -2524,7 +2546,7 @@ static void build_boundary_vertex_only(BevelParams *bp, BevVert *bv, bool constr
BoundVert *v;
float co[3];
- BLI_assert(bp->vertex_only);
+ BLI_assert(bp->affect_type == BEVEL_AFFECT_VERTICES);
e = efirst = &bv->edges[0];
do {
@@ -2797,7 +2819,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
return;
}
- if (bp->vertex_only) {
+ if (bp->affect_type == BEVEL_AFFECT_VERTICES) {
build_boundary_vertex_only(bp, bv, construct);
return;
}
@@ -4330,7 +4352,7 @@ static int tri_corner_test(BevelParams *bp, BevVert *bv)
int in_plane_e = 0;
/* The superellipse snapping of this case isn't helpful with custom profiles enabled. */
- if (bp->vertex_only || bp->profile_type == BEVEL_PROFILE_CUSTOM) {
+ if (bp->affect_type == BEVEL_AFFECT_VERTICES || bp->profile_type == BEVEL_PROFILE_CUSTOM) {
return -1;
}
if (bv->vmesh->count != 3) {
@@ -5154,7 +5176,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert
else {
fc = NULL;
}
- if (bp->vertex_only) {
+ if (bp->affect_type == BEVEL_AFFECT_VERTICES) {
e = bndv->efirst;
}
else {
@@ -5175,7 +5197,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert
bmv3 = mesh_vert(vm, i, j + 1, k + 1)->v;
bmv4 = mesh_vert(vm, i, j + 1, k)->v;
BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
- if (bp->vertex_only) {
+ if (bp->affect_type == BEVEL_AFFECT_VERTICES) {
if (j < k) {
if (k == ns2 && j == ns2 - 1) {
r_f = bev_create_quad_ex(bm,
@@ -5202,7 +5224,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert
r_f = bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, mat_nr);
}
else { /* j == k */
- /* Only one edge attached to v, since vertex_only. */
+ /* Only one edge attached to v, since vertex only. */
if (e->is_seam) {
r_f = bev_create_quad_ex(
bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, bme, NULL, bme, NULL, f2, mat_nr);
@@ -5260,7 +5282,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert
}
} while ((bndv = bndv->next) != vm->boundstart);
bmv1 = mesh_vert(vm, 0, ns2, ns2)->v;
- if (bp->vertex_only || count_bound_vert_seams(bv) <= 1) {
+ if (bp->affect_type == BEVEL_AFFECT_VERTICES || count_bound_vert_seams(bv) <= 1) {
bev_merge_uvs(bm, bmv1);
}
}
@@ -5570,7 +5592,7 @@ static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv)
BoundVert *bndv;
int ns, k;
- BLI_assert(vm->count == 2 && bp->vertex_only);
+ BLI_assert(vm->count == 2 && bp->affect_type == BEVEL_AFFECT_VERTICES);
v1 = mesh_vert(vm, 0, 0, 0)->v;
v2 = mesh_vert(vm, 1, 0, 0)->v;
@@ -5731,7 +5753,7 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
switch (vm->mesh_kind) {
case M_NONE:
- if (n == 2 && bp->vertex_only) {
+ if (n == 2 && bp->affect_type == BEVEL_AFFECT_VERTICES) {
bevel_vert_two_edges(bp, bm, bv);
}
break;
@@ -6032,7 +6054,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) {
int face_count = BM_edge_face_count(bme);
BM_BEVEL_EDGE_TAG_DISABLE(bme);
- if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
+ if (BM_elem_flag_test(bme, BM_ELEM_TAG) && bp->affect_type != BEVEL_AFFECT_VERTICES) {
BLI_assert(face_count == 2);
nsel++;
if (!first_bme) {
@@ -6043,14 +6065,14 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
/* Good to start face chain from this edge. */
first_bme = bme;
}
- if (face_count > 0 || bp->vertex_only) {
+ if (face_count > 0 || bp->affect_type == BEVEL_AFFECT_VERTICES) {
tot_edges++;
}
if (BM_edge_is_wire(bme)) {
tot_wire++;
/* If edge beveling, exclude wire edges from edges array.
* Mark this edge as "chosen" so loop below won't choose it. */
- if (!bp->vertex_only) {
+ if (bp->affect_type != BEVEL_AFFECT_VERTICES) {
BM_BEVEL_EDGE_TAG_ENABLE(bme);
}
}
@@ -6059,7 +6081,8 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
first_bme = v->e;
}
- if ((nsel == 0 && !bp->vertex_only) || (tot_edges < 2 && bp->vertex_only)) {
+ if ((nsel == 0 && bp->affect_type != BEVEL_AFFECT_VERTICES) ||
+ (tot_edges < 2 && bp->affect_type == BEVEL_AFFECT_VERTICES)) {
/* Signal this vert isn't being beveled. */
BM_elem_flag_disable(v, BM_ELEM_TAG);
return NULL;
@@ -6089,7 +6112,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
for (i = 0; i < tot_edges; i++) {
e = &bv->edges[i];
bme = e->e;
- if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
+ if (BM_elem_flag_test(bme, BM_ELEM_TAG) && bp->affect_type != BEVEL_AFFECT_VERTICES) {
e->is_bev = true;
e->seg = bp->seg;
}
@@ -6128,7 +6151,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
}
}
- if (bp->vertex_only) {
+ if (bp->affect_type == BEVEL_AFFECT_VERTICES) {
/* Modify the offset by the vertex group or bevel weight if they are specified. */
if (bp->dvert != NULL && bp->vertex_group != -1) {
weight = BKE_defvert_find_weight(bp->dvert + BM_elem_index_get(v), bp->vertex_group);
@@ -6218,7 +6241,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
e->offset_r_spec *= weight;
}
}
- else if (bp->vertex_only) {
+ else if (bp->affect_type == BEVEL_AFFECT_VERTICES) {
/* Weight has already been applied to bv->offset, if present.
* Transfer to e->offset_[lr]_spec according to offset_type. */
float edge_dir[3];
@@ -6728,11 +6751,19 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
verts[2] = mesh_vert(vm2, i2, 0, nseg - k)->v;
if (odd && k == mid + 1) {
BMFace *fchoices[2] = {f1, f2};
- edges[0] = edges[1] = NULL;
- edges[2] = edges[3] = bme;
f_choice = choose_rep_face(bp, fchoices, 2);
if (e1->is_seam) {
- /* Straddles a seam: choose to interpolate in f_choice and snap right edge to bme. */
+ /* Straddles a seam: choose to interpolate in f_choice and snap the loops whose verts
+ * are in the non-chosen face to bme for interpolation purposes.
+ */
+ if (f_choice == f1) {
+ edges[0] = edges[1] = NULL;
+ edges[2] = edges[3] = bme;
+ }
+ else {
+ edges[0] = edges[1] = bme;
+ edges[2] = edges[3] = NULL;
+ }
r_f = bev_create_ngon(bm, verts, 4, NULL, f_choice, edges, mat_nr, true);
}
else {
@@ -7124,68 +7155,64 @@ static float find_profile_fullness(BevelParams *bp)
*/
static void set_profile_spacing(BevelParams *bp, ProfileSpacing *pro_spacing, bool custom)
{
- int seg, seg_2;
-
- seg = bp->seg;
- seg_2 = power_of_2_max_i(bp->seg);
- if (seg > 1) {
- /* Sample the input number of segments. */
- pro_spacing->xvals = (double *)BLI_memarena_alloc(bp->mem_arena,
- (size_t)(seg + 1) * sizeof(double));
- pro_spacing->yvals = (double *)BLI_memarena_alloc(bp->mem_arena,
- (size_t)(seg + 1) * sizeof(double));
+ int seg = bp->seg;
+
+ if (seg <= 1) {
+ /* Only 1 segment, we don't need any profile information. */
+ pro_spacing->xvals = NULL;
+ pro_spacing->yvals = NULL;
+ pro_spacing->xvals_2 = NULL;
+ pro_spacing->yvals_2 = NULL;
+ pro_spacing->seg_2 = 0;
+ return;
+ }
+
+ int seg_2 = max_ii(power_of_2_max_i(bp->seg), 4);
+
+ /* Sample the seg_2 segments used during vertex mesh subdivision. */
+ bp->pro_spacing.seg_2 = seg_2;
+ if (seg_2 == seg) {
+ pro_spacing->xvals_2 = pro_spacing->xvals;
+ pro_spacing->yvals_2 = pro_spacing->yvals;
+ }
+ else {
+ pro_spacing->xvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena,
+ sizeof(double) * (seg_2 + 1));
+ pro_spacing->yvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena,
+ sizeof(double) * (seg_2 + 1));
if (custom) {
- /* Make sure the curve profile's sample table is full. */
- if (bp->custom_profile->segments_len != seg || !bp->custom_profile->segments) {
- BKE_curveprofile_initialize((CurveProfile *)bp->custom_profile, (short)seg);
- }
+ /* Make sure the curve profile widget's sample table is full of the seg_2 samples. */
+ BKE_curveprofile_init((CurveProfile *)bp->custom_profile, (short)seg_2);
/* Copy segment locations into the profile spacing struct. */
- for (int i = 0; i < seg + 1; i++) {
- pro_spacing->xvals[i] = (double)bp->custom_profile->segments[i].y;
- pro_spacing->yvals[i] = (double)bp->custom_profile->segments[i].x;
+ for (int i = 0; i < seg_2 + 1; i++) {
+ pro_spacing->xvals_2[i] = (double)bp->custom_profile->segments[i].y;
+ pro_spacing->yvals_2[i] = (double)bp->custom_profile->segments[i].x;
}
}
else {
- find_even_superellipse_chords(seg, bp->pro_super_r, pro_spacing->xvals, pro_spacing->yvals);
+ find_even_superellipse_chords(
+ seg_2, bp->pro_super_r, pro_spacing->xvals_2, pro_spacing->yvals_2);
}
+ }
- /* Sample the seg_2 segments used for subdividing the vertex meshes. */
- if (seg_2 == 2) {
- seg_2 = 4;
+ /* Sample the input number of segments. */
+ pro_spacing->xvals = (double *)BLI_memarena_alloc(bp->mem_arena, sizeof(double) * (seg + 1));
+ pro_spacing->yvals = (double *)BLI_memarena_alloc(bp->mem_arena, sizeof(double) * (seg + 1));
+ if (custom) {
+ /* Make sure the curve profile's sample table is full. */
+ if (bp->custom_profile->segments_len != seg || !bp->custom_profile->segments) {
+ BKE_curveprofile_init((CurveProfile *)bp->custom_profile, (short)seg);
}
- bp->pro_spacing.seg_2 = seg_2;
- if (seg_2 == seg) {
- pro_spacing->xvals_2 = pro_spacing->xvals;
- pro_spacing->yvals_2 = pro_spacing->yvals;
- }
- else {
- pro_spacing->xvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena,
- (size_t)(seg_2 + 1) * sizeof(double));
- pro_spacing->yvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena,
- (size_t)(seg_2 + 1) * sizeof(double));
- if (custom) {
- /* Make sure the curve profile widget's sample table is full of the seg_2 samples. */
- BKE_curveprofile_initialize((CurveProfile *)bp->custom_profile, (short)seg_2);
-
- /* Copy segment locations into the profile spacing struct. */
- for (int i = 0; i < seg_2 + 1; i++) {
- pro_spacing->xvals_2[i] = (double)bp->custom_profile->segments[i].y;
- pro_spacing->yvals_2[i] = (double)bp->custom_profile->segments[i].x;
- }
- }
- else {
- find_even_superellipse_chords(
- seg_2, bp->pro_super_r, pro_spacing->xvals_2, pro_spacing->yvals_2);
- }
+
+ /* Copy segment locations into the profile spacing struct. */
+ for (int i = 0; i < seg + 1; i++) {
+ pro_spacing->xvals[i] = (double)bp->custom_profile->segments[i].y;
+ pro_spacing->yvals[i] = (double)bp->custom_profile->segments[i].x;
}
}
- else { /* Only 1 segment, we don't need any profile information. */
- pro_spacing->xvals = NULL;
- pro_spacing->yvals = NULL;
- pro_spacing->xvals_2 = NULL;
- pro_spacing->yvals_2 = NULL;
- pro_spacing->seg_2 = 0;
+ else {
+ find_even_superellipse_chords(seg, bp->pro_super_r, pro_spacing->xvals, pro_spacing->yvals);
}
}
@@ -7361,7 +7388,7 @@ static void bevel_limit_offset(BevelParams *bp, BMesh *bm)
}
for (i = 0; i < bv->edgecount; i++) {
eh = &bv->edges[i];
- if (bp->vertex_only) {
+ if (bp->affect_type == BEVEL_AFFECT_VERTICES) {
collision_offset = vertex_collide_offset(bp, eh);
if (collision_offset < limited_offset) {
limited_offset = collision_offset;
@@ -7421,7 +7448,7 @@ void BM_mesh_bevel(BMesh *bm,
const int profile_type,
const int segments,
const float profile,
- const bool vertex_only,
+ const bool affect_type,
const bool use_weights,
const bool limit_offset,
const struct MDeformVert *dvert,
@@ -7452,11 +7479,12 @@ void BM_mesh_bevel(BMesh *bm,
bp.seg = segments;
bp.profile = profile;
bp.pro_super_r = -logf(2.0) / logf(sqrtf(profile)); /* Convert to superellipse exponent. */
- bp.vertex_only = vertex_only;
+ bp.affect_type = affect_type;
bp.use_weights = use_weights;
bp.loop_slide = loop_slide;
bp.limit_offset = limit_offset;
- bp.offset_adjust = !vertex_only && !ELEM(offset_type, BEVEL_AMT_PERCENT, BEVEL_AMT_ABSOLUTE);
+ bp.offset_adjust = bp.affect_type != BEVEL_AFFECT_VERTICES &&
+ !ELEM(offset_type, BEVEL_AMT_PERCENT, BEVEL_AMT_ABSOLUTE);
bp.dvert = dvert;
bp.vertex_group = vertex_group;
bp.mat_nr = mat;
@@ -7473,6 +7501,10 @@ void BM_mesh_bevel(BMesh *bm,
bp.custom_profile = custom_profile;
bp.vmesh_method = vmesh_method;
+#ifdef BEVEL_DEBUG_TIME
+ double start_time = PIL_check_seconds_timer();
+#endif
+
/* Disable the miters with the cutoff vertex mesh method, the combination isn't useful anyway. */
if (bp.vmesh_method == BEVEL_VMESH_CUTOFF) {
bp.miter_outer = BEVEL_MITER_SHARP;
@@ -7571,7 +7603,7 @@ void BM_mesh_bevel(BMesh *bm,
}
/* Build polygons for edges. */
- if (!bp.vertex_only) {
+ if (bp.affect_type != BEVEL_AFFECT_VERTICES) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
bevel_build_edge_polygons(bm, &bp, e);
@@ -7641,4 +7673,8 @@ void BM_mesh_bevel(BMesh *bm,
BLI_ghash_free(bp.face_hash, NULL, NULL);
BLI_memarena_free(bp.mem_arena);
}
+#ifdef BEVEL_DEBUG_TIME
+ double end_time = PIL_check_seconds_timer();
+ printf("BMESH BEVEL TIME = %.3f\n", end_time - start_time);
+#endif
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h
index 667482960d3..de57e1c62a9 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.h
+++ b/source/blender/bmesh/tools/bmesh_bevel.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_BEVEL_H__
-#define __BMESH_BEVEL_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -30,7 +29,7 @@ void BM_mesh_bevel(BMesh *bm,
const int profile_type,
const int segments,
const float profile,
- const bool vertex_only,
+ const bool affect_type,
const bool use_weights,
const bool limit_offset,
const struct MDeformVert *dvert,
@@ -47,5 +46,3 @@ void BM_mesh_bevel(BMesh *bm,
const float smoothresh,
const struct CurveProfile *custom_profile,
const int vmesh_method);
-
-#endif /* __BMESH_BEVEL_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.h b/source/blender/bmesh/tools/bmesh_bisect_plane.h
index ca6281be99f..f64b5d8097c 100644
--- a/source/blender/bmesh/tools/bmesh_bisect_plane.h
+++ b/source/blender/bmesh/tools/bmesh_bisect_plane.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_BISECT_PLANE_H__
-#define __BMESH_BISECT_PLANE_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -28,5 +27,3 @@ void BM_mesh_bisect_plane(BMesh *bm,
const short oflag_center,
const short oflag_new,
const float eps);
-
-#endif /* __BMESH_BISECT_PLANE_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h
index 669eb629e70..c62288c269a 100644
--- a/source/blender/bmesh/tools/bmesh_decimate.h
+++ b/source/blender/bmesh/tools/bmesh_decimate.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_DECIMATE_H__
-#define __BMESH_DECIMATE_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -45,5 +44,3 @@ void BM_mesh_decimate_dissolve(BMesh *bm,
const float angle_limit,
const bool do_dissolve_boundaries,
const BMO_Delimit delimit);
-
-#endif /* __BMESH_DECIMATE_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_edgenet.h b/source/blender/bmesh/tools/bmesh_edgenet.h
index 5db0e1170f3..7855b2e2886 100644
--- a/source/blender/bmesh/tools/bmesh_edgenet.h
+++ b/source/blender/bmesh/tools/bmesh_edgenet.h
@@ -14,13 +14,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_EDGENET_H__
-#define __BMESH_EDGENET_H__
+#pragma once
/** \file
* \ingroup bmesh
*/
void BM_mesh_edgenet(BMesh *bm, const bool use_edge_tag, const bool use_new_face_tag);
-
-#endif /* __BMESH_EDGENET_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.h b/source/blender/bmesh/tools/bmesh_edgesplit.h
index 0b3884ec888..4b8c07fc992 100644
--- a/source/blender/bmesh/tools/bmesh_edgesplit.h
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_EDGESPLIT_H__
-#define __BMESH_EDGESPLIT_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -25,5 +24,3 @@ void BM_mesh_edgesplit(BMesh *bm,
const bool use_verts,
const bool tag_only,
const bool copy_select);
-
-#endif /* __BMESH_EDGESPLIT_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_intersect.h b/source/blender/bmesh/tools/bmesh_intersect.h
index cbbc74d3f82..adb88f2fd76 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.h
+++ b/source/blender/bmesh/tools/bmesh_intersect.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_INTERSECT_H__
-#define __BMESH_INTERSECT_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -42,5 +41,3 @@ enum {
BMESH_ISECT_BOOLEAN_UNION = 1,
BMESH_ISECT_BOOLEAN_DIFFERENCE = 2,
};
-
-#endif /* __BMESH_INTERSECT_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_intersect_edges.c b/source/blender/bmesh/tools/bmesh_intersect_edges.c
index 99a5a9edb57..52231033fd3 100644
--- a/source/blender/bmesh/tools/bmesh_intersect_edges.c
+++ b/source/blender/bmesh/tools/bmesh_intersect_edges.c
@@ -833,15 +833,37 @@ bool BM_mesh_intersect_edges(
}
if (pair_array) {
+ BMVert *v_key, *v_val;
pair_iter = &pair_array[0];
for (i = 0; i < pair_len; i++, pair_iter++) {
BLI_assert((*pair_iter)[0].elem->head.htype == BM_VERT);
BLI_assert((*pair_iter)[1].elem->head.htype == BM_VERT);
BLI_assert((*pair_iter)[0].elem != (*pair_iter)[1].elem);
- BMVert *v_key, *v_val;
v_key = (*pair_iter)[0].vert;
v_val = (*pair_iter)[1].vert;
BLI_ghash_insert(r_targetmap, v_key, v_val);
+ }
+
+ /**
+ * The weld_verts operator works best when all keys in the same group of
+ * collapsed vertices point to the same vertex.
+ * That is, if the pairs of vertices are:
+ * [1, 2], [2, 3] and [3, 4],
+ * They are better adjusted to:
+ * [1, 4], [2, 4] and [3, 4].
+ */
+ pair_iter = &pair_array[0];
+ for (i = 0; i < pair_len; i++, pair_iter++) {
+ v_key = (*pair_iter)[0].vert;
+ v_val = (*pair_iter)[1].vert;
+ BMVert *v_target;
+ while ((v_target = BLI_ghash_lookup(r_targetmap, v_val))) {
+ v_val = v_target;
+ }
+ if (v_val != (*pair_iter)[1].vert) {
+ BMVert **v_val_p = (BMVert **)BLI_ghash_lookup_p(r_targetmap, v_key);
+ *v_val_p = (*pair_iter)[1].vert = v_val;
+ }
if (split_faces) {
/* The vertex index indicates its position in the pair_array flat. */
BM_elem_index_set(v_key, i * 2);
diff --git a/source/blender/bmesh/tools/bmesh_intersect_edges.h b/source/blender/bmesh/tools/bmesh_intersect_edges.h
index 7e2252250d6..2736b7a52f9 100644
--- a/source/blender/bmesh/tools/bmesh_intersect_edges.h
+++ b/source/blender/bmesh/tools/bmesh_intersect_edges.h
@@ -18,10 +18,7 @@
* \ingroup bmesh
*/
-#ifndef __BMESH_INTERSECT_EDGES_H__
-#define __BMESH_INTERSECT_EDGES_H__
+#pragma once
bool BM_mesh_intersect_edges(
BMesh *bm, const char hflag, const float dist, const bool split_faces, GHash *r_targetmap);
-
-#endif /* __BMESH_INTERSECT_EDGES_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c
index 713a68969e5..cb75f47acf3 100644
--- a/source/blender/bmesh/tools/bmesh_path.c
+++ b/source/blender/bmesh/tools/bmesh_path.c
@@ -18,6 +18,8 @@
* \ingroup bmesh
*
* Find a path between 2 elements.
+ *
+ * \note All 3 functions are similar, changes to one most likely apply to another.
*/
#include "MEM_guardedalloc.h"
@@ -29,8 +31,11 @@
#include "bmesh.h"
#include "bmesh_path.h" /* own include */
+#define COST_INIT_MAX FLT_MAX
+
/* -------------------------------------------------------------------- */
-/* Generic Helpers */
+/** \name Generic Helpers
+ * \{ */
/**
* Use skip options when we want to start measuring from a boundary.
@@ -40,16 +45,15 @@ static float step_cost_3_v3_ex(
{
float d1[3], d2[3];
- /* The cost is based on the simple sum of the length of the two edgees... */
+ /* The cost is based on the simple sum of the length of the two edges. */
sub_v3_v3v3(d1, v2, v1);
sub_v3_v3v3(d2, v3, v2);
const float cost_12 = normalize_v3(d1);
const float cost_23 = normalize_v3(d2);
const float cost = ((skip_12 ? 0.0f : cost_12) + (skip_23 ? 0.0f : cost_23));
- /* but is biased to give higher values to sharp turns, so that it will take
- * paths with fewer "turns" when selecting between equal-weighted paths between
- * the two edges */
+ /* But is biased to give higher values to sharp turns, so that it will take paths with
+ * fewer "turns" when selecting between equal-weighted paths between the two edges. */
return cost * (1.0f + 0.5f * (2.0f - sqrtf(fabsf(dot_v3v3(d1, d2)))));
}
@@ -58,8 +62,11 @@ static float step_cost_3_v3(const float v1[3], const float v2[3], const float v3
return step_cost_3_v3_ex(v1, v2, v3, false, false);
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* BM_mesh_calc_path_vert */
+/** \name BM_mesh_calc_path_vert
+ * \{ */
static void verttag_add_adjacent(HeapSimple *heap,
BMVert *v_a,
@@ -72,11 +79,11 @@ static void verttag_add_adjacent(HeapSimple *heap,
{
BMIter eiter;
BMEdge *e;
- /* loop over faces of face, but do so by first looping over loops */
+ /* Loop over faces of face, but do so by first looping over loops. */
BM_ITER_ELEM (e, &eiter, v_a, BM_EDGES_OF_VERT) {
BMVert *v_b = BM_edge_other_vert(e, v_a);
if (!BM_elem_flag_test(v_b, BM_ELEM_TAG)) {
- /* we know 'v_b' is not visited, check it out! */
+ /* We know 'v_b' is not visited, check it out! */
const int v_b_index = BM_elem_index_get(v_b);
const float cost_cut = params->use_topology_distance ? 1.0f : len_v3v3(v_a->co, v_b->co);
const float cost_new = cost[v_a_index] + cost_cut;
@@ -93,15 +100,15 @@ static void verttag_add_adjacent(HeapSimple *heap,
if (params->use_step_face) {
BMIter liter;
BMLoop *l;
- /* loop over faces of face, but do so by first looping over loops */
+ /* Loop over faces of face, but do so by first looping over loops. */
BM_ITER_ELEM (l, &liter, v_a, BM_LOOPS_OF_VERT) {
if (l->f->len > 3) {
- /* skip loops on adjacent edges */
+ /* Skip loops on adjacent edges. */
BMLoop *l_iter = l->next->next;
do {
BMVert *v_b = l_iter->v;
if (!BM_elem_flag_test(v_b, BM_ELEM_TAG)) {
- /* we know 'v_b' is not visited, check it out! */
+ /* We know 'v_b' is not visited, check it out! */
const int v_b_index = BM_elem_index_get(v_b);
const float cost_cut = params->use_topology_distance ? 1.0f :
len_v3v3(v_a->co, v_b->co);
@@ -127,7 +134,7 @@ LinkNode *BM_mesh_calc_path_vert(BMesh *bm,
void *user_data)
{
LinkNode *path = NULL;
- /* BM_ELEM_TAG flag is used to store visited edges */
+ /* #BM_ELEM_TAG flag is used to store visited edges. */
BMVert *v;
BMIter viter;
HeapSimple *heap;
@@ -135,7 +142,7 @@ LinkNode *BM_mesh_calc_path_vert(BMesh *bm,
BMVert **verts_prev;
int i, totvert;
- /* note, would pass BM_EDGE except we are looping over all faces anyway */
+ /* Note, would pass #BM_EDGE except we are looping over all faces anyway. */
// BM_mesh_elem_index_ensure(bm, BM_VERT /* | BM_EDGE */); // NOT NEEDED FOR FACETAG
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
@@ -144,25 +151,25 @@ LinkNode *BM_mesh_calc_path_vert(BMesh *bm,
}
bm->elem_index_dirty &= ~BM_VERT;
- /* alloc */
+ /* Allocate. */
totvert = bm->totvert;
verts_prev = MEM_callocN(sizeof(*verts_prev) * totvert, __func__);
cost = MEM_mallocN(sizeof(*cost) * totvert, __func__);
- copy_vn_fl(cost, totvert, 1e20f);
+ copy_vn_fl(cost, totvert, COST_INIT_MAX);
/*
* Arrays are now filled as follows:
*
- * As the search continues, verts_prev[n] will be the previous verts on the shortest
- * path found so far to face n. BM_ELEM_TAG is used to tag elements we have visited,
- * cost[n] will contain the length of the shortest
+ * As the search continues, `verts_prev[n]` will be the previous verts on the shortest
+ * path found so far to face `n`. #BM_ELEM_TAG is used to tag elements we have visited,
+ * `cost[n]` will contain the length of the shortest
* path to face n found so far, Finally, heap is a priority heap which is built on the
- * the same data as the cost array, but inverted: it is a worklist of faces prioritized
+ * the same data as the cost array, but inverted: it is a work-list of faces prioritized
* by the shortest path found so far to the face.
*/
- /* regular dijkstra shortest path, but over faces instead of vertices */
+ /* Regular dijkstra shortest path, but over faces instead of vertices. */
heap = BLI_heapsimple_new();
BLI_heapsimple_insert(heap, 0.0f, v_src);
cost[BM_elem_index_get(v_src)] = 0.0f;
@@ -193,8 +200,11 @@ LinkNode *BM_mesh_calc_path_vert(BMesh *bm,
return path;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* BM_mesh_calc_path_edge */
+/** \name BM_mesh_calc_path_edge
+ * \{ */
static float edgetag_cut_cost_vert(BMEdge *e_a, BMEdge *e_b, BMVert *v)
{
@@ -223,8 +233,8 @@ static void edgetag_add_adjacent(HeapSimple *heap,
{
const int e_a_index = BM_elem_index_get(e_a);
- /* unlike vert/face, stepping faces disables scanning connected edges
- * and only steps over faces (selecting a ring of edges instead of a loop) */
+ /* Unlike vert/face, stepping faces disables scanning connected edges
+ * and only steps over faces (selecting a ring of edges instead of a loop). */
if (params->use_step_face == false || e_a->l == NULL) {
BMIter viter;
BMVert *v;
@@ -234,14 +244,14 @@ static void edgetag_add_adjacent(HeapSimple *heap,
BM_ITER_ELEM (v, &viter, e_a, BM_VERTS_OF_EDGE) {
- /* don't walk over previous vertex */
+ /* Don't walk over previous vertex. */
if ((edges_prev[e_a_index]) && (BM_vert_in_edge(edges_prev[e_a_index], v))) {
continue;
}
BM_ITER_ELEM (e_b, &eiter, v, BM_EDGES_OF_VERT) {
if (!BM_elem_flag_test(e_b, BM_ELEM_TAG)) {
- /* we know 'e_b' is not visited, check it out! */
+ /* We know 'e_b' is not visited, check it out! */
const int e_b_index = BM_elem_index_get(e_b);
const float cost_cut = params->use_topology_distance ?
1.0f :
@@ -267,7 +277,7 @@ static void edgetag_add_adjacent(HeapSimple *heap,
l_cycle_iter = l_iter->next;
l_cycle_end = l_iter;
- /* good, but we need to allow this otherwise paths may fail to connect at all */
+ /* Good, but we need to allow this otherwise paths may fail to connect at all. */
#if 0
if (l_iter->f->len > 3) {
l_cycle_iter = l_cycle_iter->next;
@@ -278,7 +288,7 @@ static void edgetag_add_adjacent(HeapSimple *heap,
do {
BMEdge *e_b = l_cycle_iter->e;
if (!BM_elem_flag_test(e_b, BM_ELEM_TAG)) {
- /* we know 'e_b' is not visited, check it out! */
+ /* We know 'e_b' is not visited, check it out! */
const int e_b_index = BM_elem_index_get(e_b);
const float cost_cut = params->use_topology_distance ?
1.0f :
@@ -304,7 +314,7 @@ LinkNode *BM_mesh_calc_path_edge(BMesh *bm,
void *user_data)
{
LinkNode *path = NULL;
- /* BM_ELEM_TAG flag is used to store visited edges */
+ /* #BM_ELEM_TAG flag is used to store visited edges. */
BMEdge *e;
BMIter eiter;
HeapSimple *heap;
@@ -312,7 +322,7 @@ LinkNode *BM_mesh_calc_path_edge(BMesh *bm,
BMEdge **edges_prev;
int i, totedge;
- /* note, would pass BM_EDGE except we are looping over all edges anyway */
+ /* Note, would pass #BM_EDGE except we are looping over all edges anyway. */
BM_mesh_elem_index_ensure(bm, BM_VERT /* | BM_EDGE */);
BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) {
@@ -321,25 +331,25 @@ LinkNode *BM_mesh_calc_path_edge(BMesh *bm,
}
bm->elem_index_dirty &= ~BM_EDGE;
- /* alloc */
+ /* Allocate. */
totedge = bm->totedge;
- edges_prev = MEM_callocN(sizeof(*edges_prev) * totedge, "SeamPathPrevious");
- cost = MEM_mallocN(sizeof(*cost) * totedge, "SeamPathCost");
+ edges_prev = MEM_callocN(sizeof(*edges_prev) * totedge, __func__);
+ cost = MEM_mallocN(sizeof(*cost) * totedge, __func__);
- copy_vn_fl(cost, totedge, 1e20f);
+ copy_vn_fl(cost, totedge, COST_INIT_MAX);
/*
* Arrays are now filled as follows:
*
- * As the search continues, prevedge[n] will be the previous edge on the shortest
- * path found so far to edge n. BM_ELEM_TAG is used to tag elements we have visited,
- * cost[n] will contain the length of the shortest
+ * As the search continues, `edges_prev[n]` will be the previous edge on the shortest
+ * path found so far to edge `n`. #BM_ELEM_TAG is used to tag elements we have visited,
+ * `cost[n]` will contain the length of the shortest
* path to edge n found so far, Finally, heap is a priority heap which is built on the
- * the same data as the cost array, but inverted: it is a worklist of edges prioritized
+ * the same data as the cost array, but inverted: it is a work-list of edges prioritized
* by the shortest path found so far to the edge.
*/
- /* regular dijkstra shortest path, but over edges instead of vertices */
+ /* Regular dijkstra shortest path, but over edges instead of vertices. */
heap = BLI_heapsimple_new();
BLI_heapsimple_insert(heap, 0.0f, e_src);
cost[BM_elem_index_get(e_src)] = 0.0f;
@@ -370,8 +380,11 @@ LinkNode *BM_mesh_calc_path_edge(BMesh *bm,
return path;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* BM_mesh_calc_path_face */
+/** \name BM_mesh_calc_path_face
+ * \{ */
static float facetag_cut_cost_edge(BMFace *f_a,
BMFace *f_b,
@@ -387,15 +400,15 @@ static float facetag_cut_cost_edge(BMFace *f_a,
#if 0
mid_v3_v3v3(e_cent, e->v1->co, e->v2->co);
#else
- /* for triangle fans it gives better results to pick a point on the edge */
+ /* For triangle fans it gives better results to pick a point on the edge. */
{
- float ix_e[3], ix_f[3], f;
+ float ix_e[3], ix_f[3];
isect_line_line_v3(e->v1->co, e->v2->co, f_a_cent, f_b_cent, ix_e, ix_f);
- f = line_point_factor_v3(ix_e, e->v1->co, e->v2->co);
- if (f < 0.0f) {
+ const float factor = line_point_factor_v3(ix_e, e->v1->co, e->v2->co);
+ if (factor < 0.0f) {
copy_v3_v3(e_cent, e->v1->co);
}
- else if (f > 1.0f) {
+ else if (factor > 1.0f) {
copy_v3_v3(e_cent, e->v2->co);
}
else {
@@ -432,7 +445,7 @@ static void facetag_add_adjacent(HeapSimple *heap,
{
const int f_a_index = BM_elem_index_get(f_a);
- /* loop over faces of face, but do so by first looping over loops */
+ /* Loop over faces of face, but do so by first looping over loops. */
{
BMIter liter;
BMLoop *l_a;
@@ -444,7 +457,7 @@ static void facetag_add_adjacent(HeapSimple *heap,
do {
BMFace *f_b = l_iter->f;
if (!BM_elem_flag_test(f_b, BM_ELEM_TAG)) {
- /* we know 'f_b' is not visited, check it out! */
+ /* We know 'f_b' is not visited, check it out! */
const int f_b_index = BM_elem_index_get(f_b);
const float cost_cut = params->use_topology_distance ?
1.0f :
@@ -472,7 +485,7 @@ static void facetag_add_adjacent(HeapSimple *heap,
if ((l_a != l_b) && !BM_loop_share_edge_check(l_a, l_b)) {
BMFace *f_b = l_b->f;
if (!BM_elem_flag_test(f_b, BM_ELEM_TAG)) {
- /* we know 'f_b' is not visited, check it out! */
+ /* We know 'f_b' is not visited, check it out! */
const int f_b_index = BM_elem_index_get(f_b);
const float cost_cut = params->use_topology_distance ?
1.0f :
@@ -499,7 +512,7 @@ LinkNode *BM_mesh_calc_path_face(BMesh *bm,
void *user_data)
{
LinkNode *path = NULL;
- /* BM_ELEM_TAG flag is used to store visited edges */
+ /* #BM_ELEM_TAG flag is used to store visited edges. */
BMFace *f;
BMIter fiter;
HeapSimple *heap;
@@ -510,7 +523,7 @@ LinkNode *BM_mesh_calc_path_face(BMesh *bm,
/* Start measuring face path at the face edges, ignoring their centers. */
const void *const f_endpoints[2] = {f_src, f_dst};
- /* note, would pass BM_EDGE except we are looping over all faces anyway */
+ /* Note, would pass #BM_EDGE except we are looping over all faces anyway. */
// BM_mesh_elem_index_ensure(bm, BM_VERT /* | BM_EDGE */); // NOT NEEDED FOR FACETAG
BM_ITER_MESH_INDEX (f, &fiter, bm, BM_FACES_OF_MESH, i) {
@@ -519,25 +532,25 @@ LinkNode *BM_mesh_calc_path_face(BMesh *bm,
}
bm->elem_index_dirty &= ~BM_FACE;
- /* alloc */
+ /* Allocate. */
totface = bm->totface;
faces_prev = MEM_callocN(sizeof(*faces_prev) * totface, __func__);
cost = MEM_mallocN(sizeof(*cost) * totface, __func__);
- copy_vn_fl(cost, totface, 1e20f);
+ copy_vn_fl(cost, totface, COST_INIT_MAX);
/*
* Arrays are now filled as follows:
*
- * As the search continues, faces_prev[n] will be the previous face on the shortest
- * path found so far to face n. BM_ELEM_TAG is used to tag elements we have visited,
- * cost[n] will contain the length of the shortest
+ * As the search continues, `faces_prev[n]` will be the previous face on the shortest
+ * path found so far to face `n`. #BM_ELEM_TAG is used to tag elements we have visited,
+ * `cost[n]` will contain the length of the shortest
* path to face n found so far, Finally, heap is a priority heap which is built on the
- * the same data as the cost array, but inverted: it is a worklist of faces prioritized
+ * the same data as the cost array, but inverted: it is a work-list of faces prioritized
* by the shortest path found so far to the face.
*/
- /* regular dijkstra shortest path, but over faces instead of vertices */
+ /* Regular dijkstra shortest path, but over faces instead of vertices. */
heap = BLI_heapsimple_new();
BLI_heapsimple_insert(heap, 0.0f, f_src);
cost[BM_elem_index_get(f_src)] = 0.0f;
@@ -567,3 +580,4 @@ LinkNode *BM_mesh_calc_path_face(BMesh *bm,
return path;
}
+/** \} */
diff --git a/source/blender/bmesh/tools/bmesh_path.h b/source/blender/bmesh/tools/bmesh_path.h
index 6d22a7e7e07..79c3d3a5d63 100644
--- a/source/blender/bmesh/tools/bmesh_path.h
+++ b/source/blender/bmesh/tools/bmesh_path.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_PATH_H__
-#define __BMESH_PATH_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -49,5 +48,3 @@ struct LinkNode *BM_mesh_calc_path_face(BMesh *bm,
bool (*filter_fn)(BMFace *, void *),
void *user_data) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1, 2, 3, 5);
-
-#endif /* __BMESH_PATH_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_path_region.h b/source/blender/bmesh/tools/bmesh_path_region.h
index 5204aa45da2..99a5b4a0960 100644
--- a/source/blender/bmesh/tools/bmesh_path_region.h
+++ b/source/blender/bmesh/tools/bmesh_path_region.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_PATH_REGION_H__
-#define __BMESH_PATH_REGION_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -41,5 +40,3 @@ struct LinkNode *BM_mesh_calc_path_region_face(BMesh *bm,
bool (*test_fn)(BMFace *, void *user_data),
void *user_data) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1, 2, 3);
-
-#endif /* __BMESH_PATH_REGION_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_path_region_uv.c b/source/blender/bmesh/tools/bmesh_path_region_uv.c
new file mode 100644
index 00000000000..d036c20d0e4
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_path_region_uv.c
@@ -0,0 +1,502 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bmesh
+ *
+ * Find the region defined by the path(s) between 2 UV elements.
+ * (path isn't ordered).
+ *
+ * \note This uses the same behavior as bmesh_path_region.c
+ * however walking UV's causes enough differences that it's
+ * impractical to share the code.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_alloca.h"
+#include "BLI_linklist.h"
+#include "BLI_math.h"
+#include "BLI_utildefines_stack.h"
+
+#include "bmesh.h"
+#include "bmesh_path_region_uv.h" /* own include */
+
+/**
+ * Special handling of vertices with 2 edges
+ * (act as if the edge-chain is a single edge).
+ *
+ * \note Regarding manifold edge stepping: #BM_vert_is_edge_pair_manifold usage.
+ * Logic to skip a chain of vertices is not applied at boundaries because it gives
+ * strange behavior from a user perspective especially with boundary quads, see: T52701
+ *
+ * Restrict walking over a vertex chain to cases where the edges share the same faces.
+ * This is more typical of what a user would consider a vertex chain.
+ */
+#define USE_EDGE_CHAIN
+
+#ifdef USE_EDGE_CHAIN
+/**
+ * Takes a vertex with 2 edge users and assigns the vertices at each end-point,
+ *
+ * \return Success when \a l_end_pair values are set or false if the edges loop back on themselves.
+ */
+static bool bm_loop_pair_ends(BMLoop *l_pivot, BMLoop *l_end_pair[2])
+{
+ int j;
+ for (j = 0; j < 2; j++) {
+ BMLoop *l_other = j ? l_pivot->next : l_pivot->prev;
+ while (BM_vert_is_edge_pair_manifold(l_other->v)) {
+ l_other = j ? l_other->next : l_other->prev;
+ if (l_other == l_pivot) {
+ return false;
+ }
+ }
+ l_end_pair[j] = l_other;
+ }
+ BLI_assert(j == 2);
+ return true;
+}
+#endif /* USE_EDGE_CHAIN */
+
+/** \name Loop Vertex in Region Checks
+ * \{ */
+
+static bool bm_loop_region_test(BMLoop *l, int *const depths[2], const int pass)
+{
+ const int index = BM_elem_index_get(l);
+ return (((depths[0][index] != -1) && (depths[1][index] != -1)) &&
+ ((depths[0][index] + depths[1][index]) < pass));
+}
+
+#ifdef USE_EDGE_CHAIN
+static bool bm_loop_region_test_chain(BMLoop *l, int *const depths[2], const int pass)
+{
+ BMLoop *l_end_pair[2];
+ if (bm_loop_region_test(l, depths, pass)) {
+ return true;
+ }
+ if (BM_vert_is_edge_pair_manifold(l->v) && bm_loop_pair_ends(l, l_end_pair) &&
+ bm_loop_region_test(l_end_pair[0], depths, pass) &&
+ bm_loop_region_test(l_end_pair[1], depths, pass)) {
+ return true;
+ }
+
+ return false;
+}
+#else
+static bool bm_loop_region_test_chain(BMLoop *l, int *const depths[2], const int pass)
+{
+ return bm_loop_region_test(l, depths, pass);
+}
+#endif
+
+/** \} */
+
+/**
+ * Main logic for calculating region between 2 elements.
+ *
+ * This method works walking (breadth first) over all vertices,
+ * keeping track of topological distance from the source.
+ *
+ * This is done in both directions, after that each vertices 'depth' is added to check
+ * if its less than the number of passes needed to complete the search.
+ * When it is, we know the path is one of possible paths
+ * that have the minimum topological distance.
+ *
+ * \note Only verts without BM_ELEM_TAG will be walked over.
+ */
+static LinkNode *mesh_calc_path_region_elem(BMesh *bm,
+ BMElem *ele_src,
+ BMElem *ele_dst,
+ const uint cd_loop_uv_offset,
+ const char path_htype)
+{
+ int ele_loops_len[2];
+ BMLoop **ele_loops[2];
+
+ /* Get vertices from any `ele_src/ele_dst` elements. */
+ for (int side = 0; side < 2; side++) {
+ BMElem *ele = side ? ele_dst : ele_src;
+ int j = 0;
+
+ if (ele->head.htype == BM_FACE) {
+ BMFace *f = (BMFace *)ele;
+ ele_loops[side] = BLI_array_alloca(ele_loops[side], f->len);
+
+ BMLoop *l_first, *l_iter;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ ele_loops[side][j++] = l_iter;
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else if (ele->head.htype == BM_LOOP) {
+ if (path_htype == BM_EDGE) {
+ BMLoop *l = (BMLoop *)ele;
+ ele_loops[side] = BLI_array_alloca(ele_loops[side], 2);
+ ele_loops[side][j++] = l;
+ ele_loops[side][j++] = l->next;
+ }
+ else if (path_htype == BM_VERT) {
+ BMLoop *l = (BMLoop *)ele;
+ ele_loops[side] = BLI_array_alloca(ele_loops[side], 1);
+
+ ele_loops[side][j++] = l;
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+ ele_loops_len[side] = j;
+ }
+
+ int *depths[2] = {NULL};
+ int pass = 0;
+
+ BMLoop **stack = MEM_mallocN(sizeof(*stack) * bm->totloop, __func__);
+ BMLoop **stack_other = MEM_mallocN(sizeof(*stack_other) * bm->totloop, __func__);
+
+ STACK_DECLARE(stack);
+ STACK_INIT(stack, bm->totloop);
+
+ STACK_DECLARE(stack_other);
+ STACK_INIT(stack_other, bm->totloop);
+
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+
+ /* After exhausting all possible elements, we should have found all elements on the 'side_other'.
+ * otherwise, exit early. */
+ bool found_all = false;
+
+ for (int side = 0; side < 2; side++) {
+ const int side_other = !side;
+
+ /* initialize depths to -1 (un-touched), fill in with the depth as we walk over the edges. */
+ depths[side] = MEM_mallocN(sizeof(*depths[side]) * bm->totloop, __func__);
+ copy_vn_i(depths[side], bm->totloop, -1);
+
+ /* needed for second side */
+ STACK_CLEAR(stack);
+ STACK_CLEAR(stack_other);
+
+ for (int i = 0; i < ele_loops_len[side]; i++) {
+ BMLoop *l = ele_loops[side][i];
+ depths[side][BM_elem_index_get(l)] = 0;
+ if (!BM_elem_flag_test(l, BM_ELEM_TAG)) {
+ STACK_PUSH(stack, l);
+ }
+ }
+
+#ifdef USE_EDGE_CHAIN
+ /* Expand initial state to end-point vertices when they only have 2x edges,
+ * this prevents odd behavior when source or destination are in the middle
+ * of a long chain of edges. */
+ if (ELEM(path_htype, BM_VERT, BM_EDGE)) {
+ for (int i = 0; i < ele_loops_len[side]; i++) {
+ BMLoop *l = ele_loops[side][i];
+ BMLoop *l_end_pair[2];
+ if (BM_vert_is_edge_pair_manifold(l->v) && bm_loop_pair_ends(l, l_end_pair)) {
+ for (int j = 0; j < 2; j++) {
+ const int l_end_index = BM_elem_index_get(l_end_pair[j]);
+ if (depths[side][l_end_index] == -1) {
+ depths[side][l_end_index] = 0;
+ if (!BM_elem_flag_test(l_end_pair[j], BM_ELEM_TAG)) {
+ STACK_PUSH(stack, l_end_pair[j]);
+ }
+ }
+ }
+ }
+ }
+ }
+#endif /* USE_EDGE_CHAIN */
+
+ /* Keep walking over connected geometry until we find all the vertices in
+ * `ele_loops[side_other]`, or exit the loop when there's no connection. */
+ found_all = false;
+ for (pass = 1; (STACK_SIZE(stack) != 0); pass++) {
+ while (STACK_SIZE(stack) != 0) {
+ BMLoop *l_a = STACK_POP(stack);
+ const int l_a_index = BM_elem_index_get(l_a);
+
+ BMIter iter;
+ BMLoop *l_iter;
+
+ BM_ITER_ELEM (l_iter, &iter, l_a->v, BM_LOOPS_OF_VERT) {
+ if (BM_elem_flag_test(l_iter, BM_ELEM_TAG)) {
+ continue;
+ }
+ if (!BM_loop_uv_share_vert_check(l_a, l_iter, cd_loop_uv_offset)) {
+ continue;
+ }
+
+ /* Flush the depth to connected loops (only needed for UV's). */
+ if (depths[side][BM_elem_index_get(l_iter)] == -1) {
+ depths[side][BM_elem_index_get(l_iter)] = depths[side][l_a_index];
+ }
+
+ for (int j = 0; j < 2; j++) {
+ BMLoop *l_b = j ? l_iter->next : l_iter->prev;
+ int l_b_index = BM_elem_index_get(l_b);
+ if (depths[side][l_b_index] == -1) {
+
+#ifdef USE_EDGE_CHAIN
+ /* Walk along the chain, fill in values until we reach a vertex with 3+ edges. */
+ {
+ while (BM_vert_is_edge_pair_manifold(l_b->v) &&
+ ((depths[side][l_b_index] == -1) &&
+ /* Don't walk back to the beginning */
+ (l_b != (j ? l_iter->prev : l_iter->next)))) {
+ depths[side][l_b_index] = pass;
+
+ l_b = j ? l_b->next : l_b->prev;
+ l_b_index = BM_elem_index_get(l_b);
+ }
+ }
+#endif /* USE_EDGE_CHAIN */
+
+ /* Add the other vertex to the stack, to be traversed in the next pass. */
+ if (depths[side][l_b_index] == -1) {
+#ifdef USE_EDGE_CHAIN
+ BLI_assert(!BM_vert_is_edge_pair_manifold(l_b->v));
+#endif
+ BLI_assert(pass == depths[side][BM_elem_index_get(l_a)] + 1);
+ depths[side][l_b_index] = pass;
+ if (!BM_elem_flag_test(l_b, BM_ELEM_TAG)) {
+ STACK_PUSH(stack_other, l_b);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Stop searching once there's none left.
+ * Note that this looks in-efficient, however until the target elements reached,
+ * it will exit immediately.
+ * After that, it takes as many passes as the element has edges to finish off. */
+ found_all = true;
+ for (int i = 0; i < ele_loops_len[side_other]; i++) {
+ if (depths[side][BM_elem_index_get(ele_loops[side_other][i])] == -1) {
+ found_all = false;
+ break;
+ }
+ }
+ if (found_all == true) {
+ pass++;
+ break;
+ }
+
+ STACK_SWAP(stack, stack_other);
+ }
+
+ /* if we have nothing left, and didn't find all elements on the other side,
+ * exit early and don't continue */
+ if (found_all == false) {
+ break;
+ }
+ }
+
+ MEM_freeN(stack);
+ MEM_freeN(stack_other);
+
+ /* Now we have depths recorded from both sides,
+ * select elements that use tagged verts. */
+ LinkNode *path = NULL;
+
+ if (found_all == false) {
+ /* fail! (do nothing) */
+ }
+ else if (path_htype == BM_FACE) {
+ BMIter fiter;
+ BMFace *f;
+
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
+ /* check all verts in face are tagged */
+ BMLoop *l_first, *l_iter;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ bool ok = true;
+#if 0
+ do {
+ if (!bm_loop_region_test_chain(l_iter->v, depths, pass)) {
+ ok = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+#else
+ /* Allowing a single failure on a face gives fewer 'gaps'.
+ * While correct, in practice they're often part of what
+ * a user would consider the 'region'. */
+ int ok_tests = f->len > 3 ? 1 : 0; /* how many times we may fail */
+ do {
+ if (!bm_loop_region_test_chain(l_iter, depths, pass)) {
+ if (ok_tests == 0) {
+ ok = false;
+ break;
+ }
+ ok_tests--;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+#endif
+
+ if (ok) {
+ BLI_linklist_prepend(&path, f);
+ }
+ }
+ }
+ }
+ else if (path_htype == BM_EDGE) {
+ BMIter fiter;
+ BMFace *f;
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ BMIter liter;
+ BMLoop *l;
+ /* Check the current and next loop vertices are in the region. */
+ bool l_in_chain_next = bm_loop_region_test_chain(BM_FACE_FIRST_LOOP(f), depths, pass);
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ const bool l_in_chain = l_in_chain_next;
+ l_in_chain_next = bm_loop_region_test_chain(l->next, depths, pass);
+ if (l_in_chain && l_in_chain_next) {
+ BLI_linklist_prepend(&path, l);
+ }
+ }
+ }
+ }
+ else if (path_htype == BM_VERT) {
+ BMIter fiter;
+ BMFace *f;
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ BMIter liter;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ if (bm_loop_region_test_chain(l, depths, pass)) {
+ BLI_linklist_prepend(&path, l);
+ }
+ }
+ }
+ }
+
+ for (int side = 0; side < 2; side++) {
+ if (depths[side]) {
+ MEM_freeN(depths[side]);
+ }
+ }
+
+ return path;
+}
+
+#undef USE_EDGE_CHAIN
+
+/** \name Main Functions (exposed externally).
+ * \{ */
+
+LinkNode *BM_mesh_calc_path_uv_region_vert(BMesh *bm,
+ BMElem *ele_src,
+ BMElem *ele_dst,
+ const uint cd_loop_uv_offset,
+ bool (*filter_fn)(BMLoop *, void *user_data),
+ void *user_data)
+{
+ LinkNode *path = NULL;
+ /* BM_ELEM_TAG flag is used to store visited verts */
+ BMFace *f;
+ BMIter fiter;
+ int i = 0;
+
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ BMIter liter;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ BM_elem_flag_set(l, BM_ELEM_TAG, !filter_fn(l, user_data));
+ BM_elem_index_set(l, i); /* set_inline */
+ i += 1;
+ }
+ }
+ bm->elem_index_dirty &= ~BM_LOOP;
+
+ path = mesh_calc_path_region_elem(bm, ele_src, ele_dst, cd_loop_uv_offset, BM_VERT);
+
+ return path;
+}
+
+LinkNode *BM_mesh_calc_path_uv_region_edge(BMesh *bm,
+ BMElem *ele_src,
+ BMElem *ele_dst,
+ const uint cd_loop_uv_offset,
+ bool (*filter_fn)(BMLoop *, void *user_data),
+ void *user_data)
+{
+ LinkNode *path = NULL;
+ /* BM_ELEM_TAG flag is used to store visited verts */
+ BMFace *f;
+ BMIter fiter;
+ int i = 0;
+
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ BMIter liter;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ BM_elem_flag_set(l, BM_ELEM_TAG, !filter_fn(l, user_data));
+ BM_elem_index_set(l, i); /* set_inline */
+ i += 1;
+ }
+ }
+ bm->elem_index_dirty &= ~BM_LOOP;
+
+ path = mesh_calc_path_region_elem(bm, ele_src, ele_dst, cd_loop_uv_offset, BM_EDGE);
+
+ return path;
+}
+
+LinkNode *BM_mesh_calc_path_uv_region_face(BMesh *bm,
+ BMElem *ele_src,
+ BMElem *ele_dst,
+ const uint cd_loop_uv_offset,
+ bool (*filter_fn)(BMFace *, void *user_data),
+ void *user_data)
+{
+ LinkNode *path = NULL;
+ /* BM_ELEM_TAG flag is used to store visited verts */
+ BMFace *f;
+ BMIter fiter;
+ int i;
+
+ /* flush flag to verts */
+ BM_mesh_elem_hflag_enable_all(bm, BM_VERT, BM_ELEM_TAG, false);
+
+ BM_ITER_MESH_INDEX (f, &fiter, bm, BM_FACES_OF_MESH, i) {
+ bool test;
+ BM_elem_flag_set(f, BM_ELEM_TAG, test = !filter_fn(f, user_data));
+
+ /* flush tag to verts */
+ if (test == false) {
+ BMLoop *l_first, *l_iter;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_elem_flag_disable(l_iter->v, BM_ELEM_TAG);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+
+ path = mesh_calc_path_region_elem(bm, ele_src, ele_dst, cd_loop_uv_offset, BM_FACE);
+
+ return path;
+}
+
+/** \} */
diff --git a/source/blender/bmesh/tools/bmesh_path_region_uv.h b/source/blender/bmesh/tools/bmesh_path_region_uv.h
new file mode 100644
index 00000000000..18fe977c9fa
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_path_region_uv.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bmesh
+ */
+
+struct LinkNode *BM_mesh_calc_path_uv_region_vert(BMesh *bm,
+ BMElem *ele_src,
+ BMElem *ele_dst,
+ const uint cd_loop_uv_offset,
+ bool (*test_fn)(BMLoop *, void *user_data),
+ void *user_data) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1, 2, 3);
+
+struct LinkNode *BM_mesh_calc_path_uv_region_edge(BMesh *bm,
+ BMElem *ele_src,
+ BMElem *ele_dst,
+ const uint cd_loop_uv_offset,
+ bool (*test_fn)(BMLoop *, void *user_data),
+ void *user_data) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1, 2, 3);
+
+struct LinkNode *BM_mesh_calc_path_uv_region_face(BMesh *bm,
+ BMElem *ele_src,
+ BMElem *ele_dst,
+ const uint cd_loop_uv_offset,
+ bool (*test_fn)(BMFace *, void *user_data),
+ void *user_data) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1, 2, 3);
diff --git a/source/blender/bmesh/tools/bmesh_path_uv.c b/source/blender/bmesh/tools/bmesh_path_uv.c
new file mode 100644
index 00000000000..57a70645187
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_path_uv.c
@@ -0,0 +1,433 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bmesh
+ *
+ * Find a path between 2 elements in UV space.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_heap_simple.h"
+#include "BLI_linklist.h"
+#include "BLI_math.h"
+
+#include "DNA_meshdata_types.h"
+
+#include "bmesh.h"
+#include "bmesh_path_uv.h" /* own include */
+#include "intern/bmesh_query.h"
+#include "intern/bmesh_query_uv.h"
+
+#define COST_INIT_MAX FLT_MAX
+
+/* -------------------------------------------------------------------- */
+/** \name Generic Helpers
+ * \{ */
+
+/**
+ * Use skip options when we want to start measuring from a boundary.
+ *
+ * See #step_cost_3_v3_ex in bmesh_path.c which follows the same logic.
+ */
+static float step_cost_3_v2_ex(
+ const float v1[2], const float v2[2], const float v3[2], bool skip_12, bool skip_23)
+{
+ float d1[2], d2[2];
+
+ /* The cost is based on the simple sum of the length of the two edges. */
+ sub_v2_v2v2(d1, v2, v1);
+ sub_v2_v2v2(d2, v3, v2);
+ const float cost_12 = normalize_v2(d1);
+ const float cost_23 = normalize_v2(d2);
+ const float cost = ((skip_12 ? 0.0f : cost_12) + (skip_23 ? 0.0f : cost_23));
+
+ /* But is biased to give higher values to sharp turns, so that it will take paths with
+ * fewer "turns" when selecting between equal-weighted paths between the two edges. */
+ return cost * (1.0f + 0.5f * (2.0f - sqrtf(fabsf(dot_v2v2(d1, d2)))));
+}
+
+static float UNUSED_FUNCTION(step_cost_3_v2)(const float v1[2],
+ const float v2[2],
+ const float v3[2])
+{
+ return step_cost_3_v2_ex(v1, v2, v3, false, false);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name BM_mesh_calc_path_uv_vert
+ * \{ */
+
+static void looptag_add_adjacent_uv(HeapSimple *heap,
+ BMLoop *l_a,
+ BMLoop **loops_prev,
+ float *cost,
+ const struct BMCalcPathUVParams *params)
+{
+ BLI_assert(params->aspect_y != 0.0f);
+ const uint cd_loop_uv_offset = params->cd_loop_uv_offset;
+ const int l_a_index = BM_elem_index_get(l_a);
+ const MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset);
+ const float uv_a[2] = {luv_a->uv[0], luv_a->uv[1] / params->aspect_y};
+
+ {
+ BMIter liter;
+ BMLoop *l;
+ /* Loop over faces of face, but do so by first looping over loops. */
+ BM_ITER_ELEM (l, &liter, l_a->v, BM_LOOPS_OF_VERT) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_a->uv, luv->uv)) {
+ /* 'l_a' is already tagged, tag all adjacent. */
+ BM_elem_flag_enable(l, BM_ELEM_TAG);
+ BMLoop *l_b = l->next;
+ do {
+ if (!BM_elem_flag_test(l_b, BM_ELEM_TAG)) {
+ const MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset);
+ const float uv_b[2] = {luv_b->uv[0], luv_b->uv[1] / params->aspect_y};
+ /* We know 'l_b' is not visited, check it out! */
+ const int l_b_index = BM_elem_index_get(l_b);
+ const float cost_cut = params->use_topology_distance ? 1.0f : len_v2v2(uv_a, uv_b);
+ const float cost_new = cost[l_a_index] + cost_cut;
+
+ if (cost[l_b_index] > cost_new) {
+ cost[l_b_index] = cost_new;
+ loops_prev[l_b_index] = l_a;
+ BLI_heapsimple_insert(heap, cost_new, l_b);
+ }
+ }
+ /* This means we only step onto `l->prev` & `l->next`. */
+ if (params->use_step_face == false) {
+ if (l_b == l->next) {
+ l_b = l->prev->prev;
+ }
+ }
+ } while ((l_b = l_b->next) != l);
+ }
+ }
+ }
+}
+
+struct LinkNode *BM_mesh_calc_path_uv_vert(BMesh *bm,
+ BMLoop *l_src,
+ BMLoop *l_dst,
+ const struct BMCalcPathUVParams *params,
+ bool (*filter_fn)(BMLoop *, void *),
+ void *user_data)
+{
+ LinkNode *path = NULL;
+ /* BM_ELEM_TAG flag is used to store visited edges */
+ BMIter viter;
+ HeapSimple *heap;
+ float *cost;
+ BMLoop **loops_prev;
+ int i = 0, totloop;
+ BMFace *f;
+
+ /* Note, would pass BM_EDGE except we are looping over all faces anyway. */
+ // BM_mesh_elem_index_ensure(bm, BM_LOOP); // NOT NEEDED FOR FACETAG
+
+ BM_ITER_MESH (f, &viter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter = l_first;
+ do {
+ BM_elem_flag_set(l_iter, BM_ELEM_TAG, !filter_fn(l_iter, user_data));
+ BM_elem_index_set(l_iter, i); /* set_inline */
+ i += 1;
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ bm->elem_index_dirty &= ~BM_LOOP;
+
+ /* Allocate. */
+ totloop = bm->totloop;
+ loops_prev = MEM_callocN(sizeof(*loops_prev) * totloop, __func__);
+ cost = MEM_mallocN(sizeof(*cost) * totloop, __func__);
+
+ copy_vn_fl(cost, totloop, COST_INIT_MAX);
+
+ /* Regular dijkstra shortest path, but over UV loops instead of vertices. */
+ heap = BLI_heapsimple_new();
+ BLI_heapsimple_insert(heap, 0.0f, l_src);
+ cost[BM_elem_index_get(l_src)] = 0.0f;
+
+ BMLoop *l = NULL;
+ while (!BLI_heapsimple_is_empty(heap)) {
+ l = BLI_heapsimple_pop_min(heap);
+
+ if ((l->v == l_dst->v) && BM_loop_uv_share_vert_check(l, l_dst, params->cd_loop_uv_offset)) {
+ break;
+ }
+
+ if (!BM_elem_flag_test(l, BM_ELEM_TAG)) {
+ /* Adjacent loops are tagged while stepping to avoid 2x loops. */
+ BM_elem_flag_enable(l, BM_ELEM_TAG);
+ looptag_add_adjacent_uv(heap, l, loops_prev, cost, params);
+ }
+ }
+
+ if ((l->v == l_dst->v) && BM_loop_uv_share_vert_check(l, l_dst, params->cd_loop_uv_offset)) {
+ do {
+ BLI_linklist_prepend(&path, l);
+ } while ((l = loops_prev[BM_elem_index_get(l)]));
+ }
+
+ MEM_freeN(loops_prev);
+ MEM_freeN(cost);
+ BLI_heapsimple_free(heap, NULL);
+
+ return path;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name BM_mesh_calc_path_uv_edge
+ * \{ */
+/* TODO(campbell): not very urgent, since the operator fakes this using vertex path. */
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name BM_mesh_calc_path_uv_face
+ * \{ */
+
+static float facetag_cut_cost_edge_uv(BMFace *f_a,
+ BMFace *f_b,
+ BMLoop *l_edge,
+ const void *const f_endpoints[2],
+ const float aspect_v2[2],
+ const int cd_loop_uv_offset)
+{
+ float f_a_cent[2];
+ float f_b_cent[2];
+ float e_cent[2];
+
+ BM_face_uv_calc_center_median_weighted(f_a, aspect_v2, cd_loop_uv_offset, f_a_cent);
+ BM_face_uv_calc_center_median_weighted(f_b, aspect_v2, cd_loop_uv_offset, f_b_cent);
+
+ const float *co_v1 = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_edge, cd_loop_uv_offset))->uv;
+ const float *co_v2 =
+ ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_edge->next, cd_loop_uv_offset))->uv;
+
+#if 0
+ mid_v2_v2v2(e_cent, co_v1, co_v2);
+#else
+ /* For triangle fans it gives better results to pick a point on the edge. */
+ {
+ float ix_e[2];
+ isect_line_line_v2_point(co_v1, co_v2, f_a_cent, f_b_cent, ix_e);
+ const float factor = line_point_factor_v2(ix_e, co_v1, co_v2);
+ if (factor < 0.0f) {
+ copy_v2_v2(e_cent, co_v1);
+ }
+ else if (factor > 1.0f) {
+ copy_v2_v2(e_cent, co_v2);
+ }
+ else {
+ copy_v2_v2(e_cent, ix_e);
+ }
+ }
+#endif
+
+ /* Apply aspect before calculating cost. */
+ mul_v2_v2(f_a_cent, aspect_v2);
+ mul_v2_v2(f_b_cent, aspect_v2);
+ mul_v2_v2(e_cent, aspect_v2);
+
+ return step_cost_3_v2_ex(
+ f_a_cent, e_cent, f_b_cent, (f_a == f_endpoints[0]), (f_b == f_endpoints[1]));
+}
+
+static float facetag_cut_cost_vert_uv(BMFace *f_a,
+ BMFace *f_b,
+ BMLoop *l_vert,
+ const void *const f_endpoints[2],
+ const float aspect_v2[2],
+ const int cd_loop_uv_offset)
+{
+ float f_a_cent[2];
+ float f_b_cent[2];
+ float v_cent[2];
+
+ BM_face_uv_calc_center_median_weighted(f_a, aspect_v2, cd_loop_uv_offset, f_a_cent);
+ BM_face_uv_calc_center_median_weighted(f_b, aspect_v2, cd_loop_uv_offset, f_b_cent);
+
+ copy_v2_v2(v_cent, ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_vert, cd_loop_uv_offset))->uv);
+
+ mul_v2_v2(f_a_cent, aspect_v2);
+ mul_v2_v2(f_b_cent, aspect_v2);
+ mul_v2_v2(v_cent, aspect_v2);
+
+ return step_cost_3_v2_ex(
+ f_a_cent, v_cent, f_b_cent, (f_a == f_endpoints[0]), (f_b == f_endpoints[1]));
+}
+
+static void facetag_add_adjacent_uv(HeapSimple *heap,
+ BMFace *f_a,
+ BMFace **faces_prev,
+ float *cost,
+ const void *const f_endpoints[2],
+ const float aspect_v2[2],
+ const struct BMCalcPathUVParams *params)
+{
+ const uint cd_loop_uv_offset = params->cd_loop_uv_offset;
+ const int f_a_index = BM_elem_index_get(f_a);
+
+ /* Loop over faces of face, but do so by first looping over loops. */
+ {
+ BMIter liter;
+ BMLoop *l_a;
+
+ BM_ITER_ELEM (l_a, &liter, f_a, BM_LOOPS_OF_FACE) {
+ BMLoop *l_first, *l_iter;
+
+ /* Check there is an adjacent face to loop over. */
+ if (l_a != l_a->radial_next) {
+ l_iter = l_first = l_a->radial_next;
+ do {
+ BMFace *f_b = l_iter->f;
+ if (!BM_elem_flag_test(f_b, BM_ELEM_TAG)) {
+ if (BM_loop_uv_share_edge_check(l_a, l_iter, cd_loop_uv_offset)) {
+ /* We know 'f_b' is not visited, check it out! */
+ const int f_b_index = BM_elem_index_get(f_b);
+ const float cost_cut =
+ params->use_topology_distance ?
+ 1.0f :
+ facetag_cut_cost_edge_uv(
+ f_a, f_b, l_iter, f_endpoints, aspect_v2, cd_loop_uv_offset);
+ const float cost_new = cost[f_a_index] + cost_cut;
+
+ if (cost[f_b_index] > cost_new) {
+ cost[f_b_index] = cost_new;
+ faces_prev[f_b_index] = f_a;
+ BLI_heapsimple_insert(heap, cost_new, f_b);
+ }
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ }
+ }
+
+ if (params->use_step_face) {
+ BMIter liter;
+ BMLoop *l_a;
+
+ BM_ITER_ELEM (l_a, &liter, f_a, BM_LOOPS_OF_FACE) {
+ BMIter litersub;
+ BMLoop *l_b;
+ BM_ITER_ELEM (l_b, &litersub, l_a->v, BM_LOOPS_OF_VERT) {
+ if ((l_a != l_b) && !BM_loop_share_edge_check(l_a, l_b)) {
+ BMFace *f_b = l_b->f;
+ if (!BM_elem_flag_test(f_b, BM_ELEM_TAG)) {
+ if (BM_loop_uv_share_vert_check(l_a, l_b, cd_loop_uv_offset)) {
+ /* We know 'f_b' is not visited, check it out! */
+ const int f_b_index = BM_elem_index_get(f_b);
+ const float cost_cut =
+ params->use_topology_distance ?
+ 1.0f :
+ facetag_cut_cost_vert_uv(
+ f_a, f_b, l_a, f_endpoints, aspect_v2, cd_loop_uv_offset);
+ const float cost_new = cost[f_a_index] + cost_cut;
+
+ if (cost[f_b_index] > cost_new) {
+ cost[f_b_index] = cost_new;
+ faces_prev[f_b_index] = f_a;
+ BLI_heapsimple_insert(heap, cost_new, f_b);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+struct LinkNode *BM_mesh_calc_path_uv_face(BMesh *bm,
+ BMFace *f_src,
+ BMFace *f_dst,
+ const struct BMCalcPathUVParams *params,
+ bool (*filter_fn)(BMFace *, void *),
+ void *user_data)
+{
+ const float aspect_v2[2] = {1.0f, 1.0f / params->aspect_y};
+ LinkNode *path = NULL;
+ /* BM_ELEM_TAG flag is used to store visited edges */
+ BMIter fiter;
+ HeapSimple *heap;
+ float *cost;
+ BMFace **faces_prev;
+ int i = 0, totface;
+
+ /* Start measuring face path at the face edges, ignoring their centers. */
+ const void *const f_endpoints[2] = {f_src, f_dst};
+
+ /* Note, would pass BM_EDGE except we are looping over all faces anyway. */
+ // BM_mesh_elem_index_ensure(bm, BM_LOOP); // NOT NEEDED FOR FACETAG
+
+ {
+ BMFace *f;
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(f, BM_ELEM_TAG, !filter_fn(f, user_data));
+ BM_elem_index_set(f, i); /* set_inline */
+ i += 1;
+ }
+ bm->elem_index_dirty &= ~BM_FACE;
+ }
+
+ /* Allocate. */
+ totface = bm->totface;
+ faces_prev = MEM_callocN(sizeof(*faces_prev) * totface, __func__);
+ cost = MEM_mallocN(sizeof(*cost) * totface, __func__);
+
+ copy_vn_fl(cost, totface, COST_INIT_MAX);
+
+ /* Regular dijkstra shortest path, but over UV faces instead of vertices. */
+ heap = BLI_heapsimple_new();
+ BLI_heapsimple_insert(heap, 0.0f, f_src);
+ cost[BM_elem_index_get(f_src)] = 0.0f;
+
+ BMFace *f = NULL;
+ while (!BLI_heapsimple_is_empty(heap)) {
+ f = BLI_heapsimple_pop_min(heap);
+
+ if (f == f_dst) {
+ break;
+ }
+
+ if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
+ /* Adjacent loops are tagged while stepping to avoid 2x loops. */
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ facetag_add_adjacent_uv(heap, f, faces_prev, cost, f_endpoints, aspect_v2, params);
+ }
+ }
+
+ if (f == f_dst) {
+ do {
+ BLI_linklist_prepend(&path, f);
+ } while ((f = faces_prev[BM_elem_index_get(f)]));
+ }
+
+ MEM_freeN(faces_prev);
+ MEM_freeN(cost);
+ BLI_heapsimple_free(heap, NULL);
+
+ return path;
+}
+
+/** \} */
diff --git a/source/blender/bmesh/tools/bmesh_path_uv.h b/source/blender/bmesh/tools/bmesh_path_uv.h
new file mode 100644
index 00000000000..5f35d2c1594
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_path_uv.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bmesh
+ */
+
+struct BMCalcPathUVParams {
+ uint use_topology_distance : 1;
+ uint use_step_face : 1;
+ uint cd_loop_uv_offset;
+ float aspect_y;
+};
+
+struct LinkNode *BM_mesh_calc_path_uv_vert(BMesh *bm,
+ BMLoop *l_src,
+ BMLoop *l_dst,
+ const struct BMCalcPathUVParams *params,
+ bool (*filter_fn)(BMLoop *, void *),
+ void *user_data) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1, 2, 3, 5);
+
+struct LinkNode *BM_mesh_calc_path_uv_face(BMesh *bm,
+ BMFace *f_src,
+ BMFace *f_dst,
+ const struct BMCalcPathUVParams *params,
+ bool (*filter_fn)(BMFace *, void *),
+ void *user_data) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1, 2, 3, 5);
diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c
index 8de23b696bf..d222ea214c4 100644
--- a/source/blender/bmesh/tools/bmesh_region_match.c
+++ b/source/blender/bmesh/tools/bmesh_region_match.c
@@ -1299,7 +1299,9 @@ static UUIDFashMatch *bm_vert_fasthash_create(BMesh *bm, const uint depth)
return id_curr;
}
-static void bm_vert_fasthash_edge_order(UUIDFashMatch *fm, const BMEdge *e, UUIDFashMatch e_fm[2])
+static void bm_vert_fasthash_edge_order(const UUIDFashMatch *fm,
+ const BMEdge *e,
+ UUIDFashMatch e_fm[2])
{
e_fm[0] = fm[BM_elem_index_get(e->v1)];
e_fm[1] = fm[BM_elem_index_get(e->v2)];
diff --git a/source/blender/bmesh/tools/bmesh_region_match.h b/source/blender/bmesh/tools/bmesh_region_match.h
index a0625543c51..799af938c31 100644
--- a/source/blender/bmesh/tools/bmesh_region_match.h
+++ b/source/blender/bmesh/tools/bmesh_region_match.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_REGION_MATCH_H__
-#define __BMESH_REGION_MATCH_H__
+#pragma once
/** \file
* \ingroup bmesh
@@ -25,5 +24,3 @@ int BM_mesh_region_match(BMesh *bm,
BMFace **faces_region,
uint faces_region_len,
ListBase *r_face_regions);
-
-#endif /* __BMESH_REGION_MATCH_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_separate.h b/source/blender/bmesh/tools/bmesh_separate.h
index 13293b155fd..9260903a8fa 100644
--- a/source/blender/bmesh/tools/bmesh_separate.h
+++ b/source/blender/bmesh/tools/bmesh_separate.h
@@ -14,13 +14,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BMESH_SEPARATE_H__
-#define __BMESH_SEPARATE_H__
+#pragma once
/** \file
* \ingroup bmesh
*/
void BM_mesh_separate_faces(BMesh *bm, BMFaceFilterFunc filter_fn, void *user_data);
-
-#endif /* __BMESH_SEPARATE_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_triangulate.h b/source/blender/bmesh/tools/bmesh_triangulate.h
index ababd78f9a1..5353b315a38 100644
--- a/source/blender/bmesh/tools/bmesh_triangulate.h
+++ b/source/blender/bmesh/tools/bmesh_triangulate.h
@@ -20,8 +20,7 @@
* Triangulate.
*/
-#ifndef __BMESH_TRIANGULATE_H__
-#define __BMESH_TRIANGULATE_H__
+#pragma once
void BM_mesh_triangulate(BMesh *bm,
const int quad_method,
@@ -31,5 +30,3 @@ void BM_mesh_triangulate(BMesh *bm,
BMOperator *op,
BMOpSlot *slot_facemap_out,
BMOpSlot *slot_doubles_out);
-
-#endif /* __BMESH_TRIANGULATE_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_wireframe.h b/source/blender/bmesh/tools/bmesh_wireframe.h
index 3be43b2e9f5..b2c2f5f5523 100644
--- a/source/blender/bmesh/tools/bmesh_wireframe.h
+++ b/source/blender/bmesh/tools/bmesh_wireframe.h
@@ -20,8 +20,7 @@
* Wire Frame.
*/
-#ifndef __BMESH_WIREFRAME_H__
-#define __BMESH_WIREFRAME_H__
+#pragma once
void BM_mesh_wireframe(BMesh *bm,
const float offset,
@@ -38,5 +37,3 @@ void BM_mesh_wireframe(BMesh *bm,
const short mat_offset,
const short mat_max,
const bool use_tag);
-
-#endif /* __BMESH_WIREFRAME_H__ */
diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h
index a24904551c6..b200fa8d266 100644
--- a/source/blender/compositor/COM_compositor.h
+++ b/source/blender/compositor/COM_compositor.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COMPOSITOR_H__
-#define __COM_COMPOSITOR_H__
+#pragma once
#include "DNA_color_types.h"
#include "DNA_node_types.h"
@@ -364,4 +363,3 @@ void COM_deinitialize(void);
}
#endif
-#endif /* __COM_COMPOSITOR_H__ */
diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h
index 3707845ef9b..a42719aaf09 100644
--- a/source/blender/compositor/COM_defines.h
+++ b/source/blender/compositor/COM_defines.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DEFINES_H__
-#define __COM_DEFINES_H__
+#pragma once
/**
* \brief possible data types for sockets
@@ -108,5 +107,3 @@ typedef enum OrderOfChunks {
#define COM_NUM_CHANNELS_COLOR 4
#define COM_BLUR_BOKEH_PIXELS 512
-
-#endif /* __COM_DEFINES_H__ */
diff --git a/source/blender/compositor/intern/COM_CPUDevice.h b/source/blender/compositor/intern/COM_CPUDevice.h
index 1d411569146..962380d7bc8 100644
--- a/source/blender/compositor/intern/COM_CPUDevice.h
+++ b/source/blender/compositor/intern/COM_CPUDevice.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CPUDEVICE_H__
-#define __COM_CPUDEVICE_H__
+#pragma once
#include "COM_Device.h"
@@ -44,5 +43,3 @@ class CPUDevice : public Device {
protected:
int m_thread_id;
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_ChunkOrder.h b/source/blender/compositor/intern/COM_ChunkOrder.h
index e75c07136b4..32d8c07de83 100644
--- a/source/blender/compositor/intern/COM_ChunkOrder.h
+++ b/source/blender/compositor/intern/COM_ChunkOrder.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CHUNKORDER_H__
-#define __COM_CHUNKORDER_H__
+#pragma once
#include "COM_ChunkOrderHotspot.h"
class ChunkOrder {
@@ -53,5 +52,3 @@ class ChunkOrder {
return this->m_distance;
}
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_ChunkOrderHotspot.h b/source/blender/compositor/intern/COM_ChunkOrderHotspot.h
index f0bc92ad6d6..afacf5fc672 100644
--- a/source/blender/compositor/intern/COM_ChunkOrderHotspot.h
+++ b/source/blender/compositor/intern/COM_ChunkOrderHotspot.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CHUNKORDERHOTSPOT_H__
-#define __COM_CHUNKORDERHOTSPOT_H__
+#pragma once
#ifdef WITH_CXX_GUARDEDALLOC
# include "MEM_guardedalloc.h"
@@ -37,5 +36,3 @@ class ChunkOrderHotspot {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ChunkOrderHotspot")
#endif
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h
index 7e775b7beaf..e29a8f67187 100644
--- a/source/blender/compositor/intern/COM_CompositorContext.h
+++ b/source/blender/compositor/intern/COM_CompositorContext.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COMPOSITORCONTEXT_H__
-#define __COM_COMPOSITORCONTEXT_H__
+#pragma once
#include "BLI_rect.h"
#include "COM_defines.h"
@@ -269,5 +268,3 @@ class CompositorContext {
return (this->getbNodeTree()->flag & NTREE_COM_GROUPNODE_BUFFER) != 0;
}
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_Converter.h b/source/blender/compositor/intern/COM_Converter.h
index 1213246b9c9..fe3b8b75ccc 100644
--- a/source/blender/compositor/intern/COM_Converter.h
+++ b/source/blender/compositor/intern/COM_Converter.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CONVERTER_H__
-#define __COM_CONVERTER_H__
+#pragma once
#ifdef WITH_CXX_GUARDEDALLOC
# include "MEM_guardedalloc.h"
@@ -85,4 +84,3 @@ class Converter {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:Converter")
#endif
};
-#endif
diff --git a/source/blender/compositor/intern/COM_Debug.h b/source/blender/compositor/intern/COM_Debug.h
index 250f360fa35..35e44506ef2 100644
--- a/source/blender/compositor/intern/COM_Debug.h
+++ b/source/blender/compositor/intern/COM_Debug.h
@@ -16,8 +16,7 @@
* Copyright 2013, Blender Foundation.
*/
-#ifndef __COM_DEBUG_H__
-#define __COM_DEBUG_H__
+#pragma once
#include <map>
#include <string>
@@ -77,5 +76,3 @@ class DebugInfo {
static GroupStateMap m_group_states; /**< for visualizing group states */
#endif
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_Device.h b/source/blender/compositor/intern/COM_Device.h
index 8573f69658e..bb95f1e953c 100644
--- a/source/blender/compositor/intern/COM_Device.h
+++ b/source/blender/compositor/intern/COM_Device.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DEVICE_H__
-#define __COM_DEVICE_H__
+#pragma once
#include "COM_WorkPackage.h"
@@ -62,5 +61,3 @@ class Device {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:Device")
#endif
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h
index 0299dad2ee8..f0dca4e9b34 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.h
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_EXECUTIONGROUP_H__
-#define __COM_EXECUTIONGROUP_H__
+#pragma once
#ifdef WITH_CXX_GUARDEDALLOC
# include "MEM_guardedalloc.h"
@@ -447,5 +446,3 @@ class ExecutionGroup {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionGroup")
#endif
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h
index bf65594fc4f..44b47787b06 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.h
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.h
@@ -18,8 +18,7 @@
class ExecutionGroup;
-#ifndef __COM_EXECUTIONSYSTEM_H__
-#define __COM_EXECUTIONSYSTEM_H__
+#pragma once
#include "BKE_text.h"
#include "COM_ExecutionGroup.h"
@@ -196,5 +195,3 @@ class ExecutionSystem {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionSystem")
#endif
};
-
-#endif /* __COM_EXECUTIONSYSTEM_H__ */
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index 6ba8f144482..fce1310f6ef 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -18,8 +18,7 @@
class MemoryBuffer;
-#ifndef __COM_MEMORYBUFFER_H__
-#define __COM_MEMORYBUFFER_H__
+#pragma once
#include "COM_ExecutionGroup.h"
#include "COM_MemoryProxy.h"
@@ -357,5 +356,3 @@ class MemoryBuffer {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBuffer")
#endif
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_MemoryProxy.h b/source/blender/compositor/intern/COM_MemoryProxy.h
index afbe0e3c166..a40e6f95dce 100644
--- a/source/blender/compositor/intern/COM_MemoryProxy.h
+++ b/source/blender/compositor/intern/COM_MemoryProxy.h
@@ -18,8 +18,8 @@
class MemoryProxy;
-#ifndef __COM_MEMORYPROXY_H__
-#define __COM_MEMORYPROXY_H__
+#pragma once
+
#include "COM_ExecutionGroup.h"
#include "COM_MemoryBuffer.h"
@@ -129,5 +129,3 @@ class MemoryProxy {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryProxy")
#endif
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h
index a2ab1996a19..0a34eff3492 100644
--- a/source/blender/compositor/intern/COM_Node.h
+++ b/source/blender/compositor/intern/COM_Node.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_NODE_H__
-#define __COM_NODE_H__
+#pragma once
#include "DNA_node_types.h"
#include <algorithm>
@@ -329,5 +328,3 @@ class NodeOutput {
void getEditorValueColor(float *value);
void getEditorValueVector(float *value);
};
-
-#endif /* __COM_NODE_H__ */
diff --git a/source/blender/compositor/intern/COM_NodeConverter.h b/source/blender/compositor/intern/COM_NodeConverter.h
index 56e9aa85010..e9b05184857 100644
--- a/source/blender/compositor/intern/COM_NodeConverter.h
+++ b/source/blender/compositor/intern/COM_NodeConverter.h
@@ -16,8 +16,7 @@
* Copyright 2013, Blender Foundation.
*/
-#ifndef __COM_NODECONVERTER_H__
-#define __COM_NODECONVERTER_H__
+#pragma once
#ifdef WITH_CXX_GUARDEDALLOC
# include "MEM_guardedalloc.h"
@@ -121,5 +120,3 @@ class NodeConverter {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeCompiler")
#endif
};
-
-#endif /* __COM_NODECONVERTER_H__ */
diff --git a/source/blender/compositor/intern/COM_NodeGraph.h b/source/blender/compositor/intern/COM_NodeGraph.h
index 531832c2c65..7cbd45bd0b5 100644
--- a/source/blender/compositor/intern/COM_NodeGraph.h
+++ b/source/blender/compositor/intern/COM_NodeGraph.h
@@ -16,8 +16,7 @@
* Copyright 2013, Blender Foundation.
*/
-#ifndef __COM_NODEGRAPH_H__
-#define __COM_NODEGRAPH_H__
+#pragma once
#include <map>
#include <set>
@@ -135,5 +134,3 @@ class NodeGraph {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeGraph")
#endif
};
-
-#endif /* __COM_NODEGRAPH_H__ */
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index d2c896a2e56..d9324729560 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_NODEOPERATION_H__
-#define __COM_NODEOPERATION_H__
+#pragma once
#include <list>
#include <sstream>
@@ -521,5 +520,3 @@ class NodeOperationOutput {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
#endif
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.h b/source/blender/compositor/intern/COM_NodeOperationBuilder.h
index 917fa2888fd..5dd4022b127 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.h
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.h
@@ -16,8 +16,7 @@
* Copyright 2013, Blender Foundation.
*/
-#ifndef __COM_NODEOPERATIONBUILDER_H__
-#define __COM_NODEOPERATIONBUILDER_H__
+#pragma once
#include <map>
#include <set>
@@ -176,5 +175,3 @@ class NodeOperationBuilder {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeCompilerImpl")
#endif
};
-
-#endif /* __COM_NODEOPERATIONBUILDER_H__ */
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h
index 3f6e0fb55ef..d502f5aa34b 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.h
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.h
@@ -18,8 +18,7 @@
class OpenCLDevice;
-#ifndef __COM_OPENCLDEVICE_H__
-#define __COM_OPENCLDEVICE_H__
+#pragma once
#include "COM_Device.h"
#include "COM_ReadBufferOperation.h"
@@ -133,5 +132,3 @@ class OpenCLDevice : public Device {
NodeOperation *operation);
cl_kernel COM_clCreateKernel(const char *kernelname, list<cl_kernel> *clKernelsToCleanUp);
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_SingleThreadedOperation.h b/source/blender/compositor/intern/COM_SingleThreadedOperation.h
index 68c7f05a6c2..7a97d790afe 100644
--- a/source/blender/compositor/intern/COM_SingleThreadedOperation.h
+++ b/source/blender/compositor/intern/COM_SingleThreadedOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SINGLETHREADEDOPERATION_H__
-#define __COM_SINGLETHREADEDOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class SingleThreadedOperation : public NodeOperation {
@@ -57,4 +57,3 @@ class SingleThreadedOperation : public NodeOperation {
return true;
}
};
-#endif
diff --git a/source/blender/compositor/intern/COM_SocketReader.h b/source/blender/compositor/intern/COM_SocketReader.h
index 82bebd5e7b9..ee2a6e0e1bf 100644
--- a/source/blender/compositor/intern/COM_SocketReader.h
+++ b/source/blender/compositor/intern/COM_SocketReader.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SOCKETREADER_H__
-#define __COM_SOCKETREADER_H__
+#pragma once
+
#include "BLI_rect.h"
#include "COM_defines.h"
@@ -138,5 +138,3 @@ class SocketReader {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:SocketReader")
#endif
};
-
-#endif /* __COM_SOCKETREADER_H__ */
diff --git a/source/blender/compositor/intern/COM_WorkPackage.h b/source/blender/compositor/intern/COM_WorkPackage.h
index 2a0e47301f5..f4370aa41be 100644
--- a/source/blender/compositor/intern/COM_WorkPackage.h
+++ b/source/blender/compositor/intern/COM_WorkPackage.h
@@ -18,8 +18,8 @@
class WorkPackage;
-#ifndef __COM_WORKPACKAGE_H__
-#define __COM_WORKPACKAGE_H__
+#pragma once
+
class ExecutionGroup;
#include "COM_ExecutionGroup.h"
@@ -67,5 +67,3 @@ class WorkPackage {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:WorkPackage")
#endif
};
-
-#endif
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.h b/source/blender/compositor/intern/COM_WorkScheduler.h
index 3a1b4c533bd..2424d1bdb72 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.h
+++ b/source/blender/compositor/intern/COM_WorkScheduler.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_WORKSCHEDULER_H__
-#define __COM_WORKSCHEDULER_H__
+#pragma once
#include "COM_ExecutionGroup.h"
@@ -116,5 +115,3 @@ class WorkScheduler {
MEM_CXX_CLASS_ALLOC_FUNCS("COM:WorkScheduler")
#endif
};
-
-#endif /* __COM_WORKSCHEDULER_H__ */
diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.h b/source/blender/compositor/nodes/COM_AlphaOverNode.h
index 27e868e6f25..32cd2e20204 100644
--- a/source/blender/compositor/nodes/COM_AlphaOverNode.h
+++ b/source/blender/compositor/nodes/COM_AlphaOverNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ALPHAOVERNODE_H__
-#define __COM_ALPHAOVERNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -32,5 +31,3 @@ class AlphaOverNode : public Node {
}
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.h b/source/blender/compositor/nodes/COM_BilateralBlurNode.h
index abed491c891..39308c7d1b6 100644
--- a/source/blender/compositor/nodes/COM_BilateralBlurNode.h
+++ b/source/blender/compositor/nodes/COM_BilateralBlurNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BILATERALBLURNODE_H__
-#define __COM_BILATERALBLURNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class BilateralBlurNode : public Node {
BilateralBlurNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_BlurNode.h b/source/blender/compositor/nodes/COM_BlurNode.h
index f0d6cad320e..3c832c93ca2 100644
--- a/source/blender/compositor/nodes/COM_BlurNode.h
+++ b/source/blender/compositor/nodes/COM_BlurNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BLURNODE_H__
-#define __COM_BLURNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class BlurNode : public Node {
BlurNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.h b/source/blender/compositor/nodes/COM_BokehBlurNode.h
index e2f728fb30b..87aca9af1f6 100644
--- a/source/blender/compositor/nodes/COM_BokehBlurNode.h
+++ b/source/blender/compositor/nodes/COM_BokehBlurNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BOKEHBLURNODE_H__
-#define __COM_BOKEHBLURNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class BokehBlurNode : public Node {
BokehBlurNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.h b/source/blender/compositor/nodes/COM_BokehImageNode.h
index 3e78e8d5185..b9d957cd6df 100644
--- a/source/blender/compositor/nodes/COM_BokehImageNode.h
+++ b/source/blender/compositor/nodes/COM_BokehImageNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BOKEHIMAGENODE_H__
-#define __COM_BOKEHIMAGENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class BokehImageNode : public Node {
BokehImageNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.h b/source/blender/compositor/nodes/COM_BoxMaskNode.h
index 0d39014bbd0..b815fd75284 100644
--- a/source/blender/compositor/nodes/COM_BoxMaskNode.h
+++ b/source/blender/compositor/nodes/COM_BoxMaskNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BOXMASKNODE_H__
-#define __COM_BOXMASKNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class BoxMaskNode : public Node {
BoxMaskNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.h b/source/blender/compositor/nodes/COM_BrightnessNode.h
index 8529fc17d9c..b64b622dd71 100644
--- a/source/blender/compositor/nodes/COM_BrightnessNode.h
+++ b/source/blender/compositor/nodes/COM_BrightnessNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BRIGHTNESSNODE_H__
-#define __COM_BRIGHTNESSNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class BrightnessNode : public Node {
BrightnessNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.h b/source/blender/compositor/nodes/COM_ChannelMatteNode.h
index e6cd8bf6f0d..bca821fa60c 100644
--- a/source/blender/compositor/nodes/COM_ChannelMatteNode.h
+++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_CHANNELMATTENODE_H__
-#define __COM_CHANNELMATTENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ChannelMatteNode : public Node {
ChannelMatteNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* COM_ChannelMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.h b/source/blender/compositor/nodes/COM_ChromaMatteNode.h
index cfb6f23ebcb..d8febdde36f 100644
--- a/source/blender/compositor/nodes/COM_ChromaMatteNode.h
+++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CHROMAMATTENODE_H__
-#define __COM_CHROMAMATTENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ChromaMatteNode : public Node {
ChromaMatteNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* COM_ChromaMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.h b/source/blender/compositor/nodes/COM_ColorBalanceNode.h
index 482b34e7809..302b66863ca 100644
--- a/source/blender/compositor/nodes/COM_ColorBalanceNode.h
+++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORBALANCENODE_H__
-#define __COM_COLORBALANCENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ColorBalanceNode : public Node {
ColorBalanceNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* COM_ColorBalanceNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h
index 0275106095e..be6545f0cfa 100644
--- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h
+++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORCORRECTIONNODE_H__
-#define __COM_COLORCORRECTIONNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ColorCorrectionNode : public Node {
ColorCorrectionNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.h b/source/blender/compositor/nodes/COM_ColorCurveNode.h
index 2a529e5713e..6eaf1db6fbb 100644
--- a/source/blender/compositor/nodes/COM_ColorCurveNode.h
+++ b/source/blender/compositor/nodes/COM_ColorCurveNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORCURVENODE_H__
-#define __COM_COLORCURVENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ColorCurveNode : public Node {
ColorCurveNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.h b/source/blender/compositor/nodes/COM_ColorMatteNode.h
index 1f02a091307..e84bdfc836f 100644
--- a/source/blender/compositor/nodes/COM_ColorMatteNode.h
+++ b/source/blender/compositor/nodes/COM_ColorMatteNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORMATTENODE_H__
-#define __COM_COLORMATTENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ColorMatteNode : public Node {
ColorMatteNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* COM_ColorMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorNode.h b/source/blender/compositor/nodes/COM_ColorNode.h
index 5c7580a9ec9..9b50e9ab7d4 100644
--- a/source/blender/compositor/nodes/COM_ColorNode.h
+++ b/source/blender/compositor/nodes/COM_ColorNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORNODE_H__
-#define __COM_COLORNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ColorNode : public Node {
ColorNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.h b/source/blender/compositor/nodes/COM_ColorRampNode.h
index 3f7a188e549..b53edf14dbd 100644
--- a/source/blender/compositor/nodes/COM_ColorRampNode.h
+++ b/source/blender/compositor/nodes/COM_ColorRampNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORRAMPNODE_H__
-#define __COM_COLORRAMPNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ColorRampNode : public Node {
ColorRampNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* COM_ColorRampNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.h b/source/blender/compositor/nodes/COM_ColorSpillNode.h
index 4678d1dd7b1..3cf8072c7b7 100644
--- a/source/blender/compositor/nodes/COM_ColorSpillNode.h
+++ b/source/blender/compositor/nodes/COM_ColorSpillNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORSPILLNODE_H__
-#define __COM_COLORSPILLNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ColorSpillNode : public Node {
ColorSpillNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* COM_ColorSpillNODE_H */
diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.h b/source/blender/compositor/nodes/COM_ColorToBWNode.h
index d811cab8019..6e7025de496 100644
--- a/source/blender/compositor/nodes/COM_ColorToBWNode.h
+++ b/source/blender/compositor/nodes/COM_ColorToBWNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORTOBWNODE_H__
-#define __COM_COLORTOBWNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -30,4 +29,3 @@ class ColorToBWNode : public Node {
ColorToBWNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.h b/source/blender/compositor/nodes/COM_CombineColorNode.h
index 203a8e84306..378a4855abf 100644
--- a/source/blender/compositor/nodes/COM_CombineColorNode.h
+++ b/source/blender/compositor/nodes/COM_CombineColorNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COMBINECOLORNODE_H__
-#define __COM_COMBINECOLORNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -65,5 +64,3 @@ class CombineYUVANode : public CombineColorNode {
NodeOperation *getColorConverter(const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_CompositorNode.h b/source/blender/compositor/nodes/COM_CompositorNode.h
index 8fb2a5a5cf5..a75355dfc14 100644
--- a/source/blender/compositor/nodes/COM_CompositorNode.h
+++ b/source/blender/compositor/nodes/COM_CompositorNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COMPOSITORNODE_H__
-#define __COM_COMPOSITORNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -30,4 +29,3 @@ class CompositorNode : public Node {
CompositorNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h
index 8fdeae39ada..372f34a576f 100644
--- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h
+++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_CONVERTALPHANODE_H__
-#define __COM_CONVERTALPHANODE_H__
+#pragma once
#include "COM_Node.h"
@@ -32,5 +31,3 @@ class ConvertAlphaNode : public Node {
}
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_CornerPinNode.h b/source/blender/compositor/nodes/COM_CornerPinNode.h
index a8e88a0ef4f..ba845a614fb 100644
--- a/source/blender/compositor/nodes/COM_CornerPinNode.h
+++ b/source/blender/compositor/nodes/COM_CornerPinNode.h
@@ -15,8 +15,7 @@
* Copyright 2014, Blender Foundation.
*/
-#ifndef __COM_CORNERPINNODE_H__
-#define __COM_CORNERPINNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -31,5 +30,3 @@ class CornerPinNode : public Node {
CornerPinNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_CORNERPINNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_CropNode.h b/source/blender/compositor/nodes/COM_CropNode.h
index 295d4fb77e1..f643ebbabcc 100644
--- a/source/blender/compositor/nodes/COM_CropNode.h
+++ b/source/blender/compositor/nodes/COM_CropNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CROPNODE_H__
-#define __COM_CROPNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class CropNode : public Node {
CropNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.h b/source/blender/compositor/nodes/COM_CryptomatteNode.h
index 91f8051f125..1fb8893efa0 100644
--- a/source/blender/compositor/nodes/COM_CryptomatteNode.h
+++ b/source/blender/compositor/nodes/COM_CryptomatteNode.h
@@ -16,8 +16,7 @@
* Copyright 2018, Blender Foundation.
*/
-#ifndef __COM_CRYPTOMATTENODE_H__
-#define __COM_CRYPTOMATTENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class CryptomatteNode : public Node {
CryptomatteNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_DefocusNode.h b/source/blender/compositor/nodes/COM_DefocusNode.h
index f2589c7ae1a..c042e98c515 100644
--- a/source/blender/compositor/nodes/COM_DefocusNode.h
+++ b/source/blender/compositor/nodes/COM_DefocusNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DEFOCUSNODE_H__
-#define __COM_DEFOCUSNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class DefocusNode : public Node {
DefocusNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_DenoiseNode.h b/source/blender/compositor/nodes/COM_DenoiseNode.h
index 6cbe598f7d2..99f59c89fdb 100644
--- a/source/blender/compositor/nodes/COM_DenoiseNode.h
+++ b/source/blender/compositor/nodes/COM_DenoiseNode.h
@@ -16,8 +16,7 @@
* Copyright 2019, Blender Foundation.
*/
-#ifndef __COM_DENOISENODE_H__
-#define __COM_DENOISENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class DenoiseNode : public Node {
DenoiseNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_DespeckleNode.h b/source/blender/compositor/nodes/COM_DespeckleNode.h
index ee510a0568c..6b39dd94ac7 100644
--- a/source/blender/compositor/nodes/COM_DespeckleNode.h
+++ b/source/blender/compositor/nodes/COM_DespeckleNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DESPECKLENODE_H__
-#define __COM_DESPECKLENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class DespeckleNode : public Node {
DespeckleNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h
index 3a86a0bbf85..26be5fe1e80 100644
--- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h
+++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DIFFERENCEMATTENODE_H__
-#define __COM_DIFFERENCEMATTENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class DifferenceMatteNode : public Node {
DifferenceMatteNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* COM_DifferenceMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.h b/source/blender/compositor/nodes/COM_DilateErodeNode.h
index d5b2863a4bb..090095df447 100644
--- a/source/blender/compositor/nodes/COM_DilateErodeNode.h
+++ b/source/blender/compositor/nodes/COM_DilateErodeNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DILATEERODENODE_H__
-#define __COM_DILATEERODENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -33,5 +32,3 @@ class DilateErodeNode : public Node {
DilateErodeNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h
index 0f9249a83a5..dfb705cbe64 100644
--- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h
+++ b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DIRECTIONALBLURNODE_H__
-#define __COM_DIRECTIONALBLURNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class DirectionalBlurNode : public Node {
DirectionalBlurNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_DisplaceNode.h b/source/blender/compositor/nodes/COM_DisplaceNode.h
index e6a13e06772..a9e8a5ad657 100644
--- a/source/blender/compositor/nodes/COM_DisplaceNode.h
+++ b/source/blender/compositor/nodes/COM_DisplaceNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DISPLACENODE_H__
-#define __COM_DISPLACENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,4 +29,3 @@ class DisplaceNode : public Node {
DisplaceNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.h b/source/blender/compositor/nodes/COM_DistanceMatteNode.h
index baba9bb8c97..6ae71ef715f 100644
--- a/source/blender/compositor/nodes/COM_DistanceMatteNode.h
+++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DISTANCEMATTENODE_H__
-#define __COM_DISTANCEMATTENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class DistanceMatteNode : public Node {
DistanceMatteNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* COM_DistanceMatteNODE_H */
diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h
index c45d42675f3..6d26cbbf528 100644
--- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h
+++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DOUBLEEDGEMASKNODE_H__
-#define __COM_DOUBLEEDGEMASKNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class DoubleEdgeMaskNode : public Node {
DoubleEdgeMaskNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.h b/source/blender/compositor/nodes/COM_EllipseMaskNode.h
index b7093bf68fa..d7376cad52e 100644
--- a/source/blender/compositor/nodes/COM_EllipseMaskNode.h
+++ b/source/blender/compositor/nodes/COM_EllipseMaskNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ELLIPSEMASKNODE_H__
-#define __COM_ELLIPSEMASKNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class EllipseMaskNode : public Node {
EllipseMaskNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_FilterNode.h b/source/blender/compositor/nodes/COM_FilterNode.h
index d0e824051bb..735d8925b48 100644
--- a/source/blender/compositor/nodes/COM_FilterNode.h
+++ b/source/blender/compositor/nodes/COM_FilterNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_FILTERNODE_H__
-#define __COM_FILTERNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class FilterNode : public Node {
FilterNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_FILTERNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_FlipNode.h b/source/blender/compositor/nodes/COM_FlipNode.h
index 2122961dac9..e819c003430 100644
--- a/source/blender/compositor/nodes/COM_FlipNode.h
+++ b/source/blender/compositor/nodes/COM_FlipNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_FLIPNODE_H__
-#define __COM_FLIPNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class FlipNode : public Node {
FlipNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_GammaNode.h b/source/blender/compositor/nodes/COM_GammaNode.h
index 46573fc4b3f..1a4d02af160 100644
--- a/source/blender/compositor/nodes/COM_GammaNode.h
+++ b/source/blender/compositor/nodes/COM_GammaNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GAMMANODE_H__
-#define __COM_GAMMANODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class GammaNode : public Node {
GammaNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_GlareNode.h b/source/blender/compositor/nodes/COM_GlareNode.h
index 051ae1d1dc3..7463af97306 100644
--- a/source/blender/compositor/nodes/COM_GlareNode.h
+++ b/source/blender/compositor/nodes/COM_GlareNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GLARENODE_H__
-#define __COM_GLARENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class GlareNode : public Node {
GlareNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h
index 270d29cc41b..01790c1a5fb 100644
--- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h
+++ b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_HUESATURATIONVALUECORRECTNODE_H__
-#define __COM_HUESATURATIONVALUECORRECTNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,4 +29,3 @@ class HueSaturationValueCorrectNode : public Node {
HueSaturationValueCorrectNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h
index 5e023a0762d..7ef7abe4188 100644
--- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h
+++ b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_HUESATURATIONVALUENODE_H__
-#define __COM_HUESATURATIONVALUENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,4 +29,3 @@ class HueSaturationValueNode : public Node {
HueSaturationValueNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.h b/source/blender/compositor/nodes/COM_IDMaskNode.h
index 3f4019bf5b7..51076619951 100644
--- a/source/blender/compositor/nodes/COM_IDMaskNode.h
+++ b/source/blender/compositor/nodes/COM_IDMaskNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_IDMASKNODE_H__
-#define __COM_IDMASKNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class IDMaskNode : public Node {
IDMaskNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_ImageNode.h b/source/blender/compositor/nodes/COM_ImageNode.h
index 7883f4d7ab3..9481ef4f7b1 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.h
+++ b/source/blender/compositor/nodes/COM_ImageNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_IMAGENODE_H__
-#define __COM_IMAGENODE_H__
+#pragma once
#include "COM_Node.h"
#include "COM_defines.h"
@@ -46,5 +45,3 @@ class ImageNode : public Node {
ImageNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_IMAGENODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_InpaintNode.h b/source/blender/compositor/nodes/COM_InpaintNode.h
index 61a7ac63146..3f778c8ba5c 100644
--- a/source/blender/compositor/nodes/COM_InpaintNode.h
+++ b/source/blender/compositor/nodes/COM_InpaintNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_INPAINTNODE_H__
-#define __COM_INPAINTNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class InpaintNode : public Node {
InpaintNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_InvertNode.h b/source/blender/compositor/nodes/COM_InvertNode.h
index 02e2eb38dc9..d90d6e48713 100644
--- a/source/blender/compositor/nodes/COM_InvertNode.h
+++ b/source/blender/compositor/nodes/COM_InvertNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_INVERTNODE_H__
-#define __COM_INVERTNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class InvertNode : public Node {
InvertNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h
index fc5f55e33ae..cfb1f2e6ddf 100644
--- a/source/blender/compositor/nodes/COM_KeyingNode.h
+++ b/source/blender/compositor/nodes/COM_KeyingNode.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_KEYINGNODE_H__
-#define __COM_KEYINGNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -58,5 +57,3 @@ class KeyingNode : public Node {
KeyingNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_KEYINGNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.h b/source/blender/compositor/nodes/COM_KeyingScreenNode.h
index 12db2ed8889..ce9ef54543d 100644
--- a/source/blender/compositor/nodes/COM_KeyingScreenNode.h
+++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_KEYINGSCREENNODE_H__
-#define __COM_KEYINGSCREENNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -31,5 +30,3 @@ class KeyingScreenNode : public Node {
KeyingScreenNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_KEYINGSCREENNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.h b/source/blender/compositor/nodes/COM_LensDistortionNode.h
index f4d9e127558..8df0e3f7df1 100644
--- a/source/blender/compositor/nodes/COM_LensDistortionNode.h
+++ b/source/blender/compositor/nodes/COM_LensDistortionNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_LENSDISTORTIONNODE_H__
-#define __COM_LENSDISTORTIONNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class LensDistortionNode : public Node {
LensDistortionNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h
index 57a8f25602a..7f2d9dfbe95 100644
--- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h
+++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_LUMINANCEMATTENODE_H__
-#define __COM_LUMINANCEMATTENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class LuminanceMatteNode : public Node {
LuminanceMatteNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_LUMINANCEMATTENODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.h b/source/blender/compositor/nodes/COM_MapRangeNode.h
index b63524291c1..b838ea858ee 100644
--- a/source/blender/compositor/nodes/COM_MapRangeNode.h
+++ b/source/blender/compositor/nodes/COM_MapRangeNode.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_MAPRANGENODE_H__
-#define __COM_MAPRANGENODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -30,5 +29,3 @@ class MapRangeNode : public Node {
MapRangeNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_MAPRANGENODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MapUVNode.h b/source/blender/compositor/nodes/COM_MapUVNode.h
index 46892453b92..f9fc413dbe5 100644
--- a/source/blender/compositor/nodes/COM_MapUVNode.h
+++ b/source/blender/compositor/nodes/COM_MapUVNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MAPUVNODE_H__
-#define __COM_MAPUVNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,4 +29,3 @@ class MapUVNode : public Node {
MapUVNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_MapValueNode.h b/source/blender/compositor/nodes/COM_MapValueNode.h
index 289b4f24138..60ee262d447 100644
--- a/source/blender/compositor/nodes/COM_MapValueNode.h
+++ b/source/blender/compositor/nodes/COM_MapValueNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MAPVALUENODE_H__
-#define __COM_MAPVALUENODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -30,5 +29,3 @@ class MapValueNode : public Node {
MapValueNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_MAPVALUENODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h
index 6c8006a8de6..4a03916b3c2 100644
--- a/source/blender/compositor/nodes/COM_MaskNode.h
+++ b/source/blender/compositor/nodes/COM_MaskNode.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_MASKNODE_H__
-#define __COM_MASKNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -31,5 +30,3 @@ class MaskNode : public Node {
MaskNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_MASKNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MathNode.h b/source/blender/compositor/nodes/COM_MathNode.h
index e53d84a221f..41b144679ac 100644
--- a/source/blender/compositor/nodes/COM_MathNode.h
+++ b/source/blender/compositor/nodes/COM_MathNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MATHNODE_H__
-#define __COM_MATHNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -32,5 +31,3 @@ class MathNode : public Node {
}
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_MixNode.h b/source/blender/compositor/nodes/COM_MixNode.h
index 511e1ffa7a8..91ce29fdbf2 100644
--- a/source/blender/compositor/nodes/COM_MixNode.h
+++ b/source/blender/compositor/nodes/COM_MixNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MIXNODE_H__
-#define __COM_MIXNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -30,4 +29,3 @@ class MixNode : public Node {
MixNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.h b/source/blender/compositor/nodes/COM_MovieClipNode.h
index 2c3f29772d5..58262592dca 100644
--- a/source/blender/compositor/nodes/COM_MovieClipNode.h
+++ b/source/blender/compositor/nodes/COM_MovieClipNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MOVIECLIPNODE_H__
-#define __COM_MOVIECLIPNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -31,5 +30,3 @@ class MovieClipNode : public Node {
MovieClipNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_MOVIECLIPNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_MovieDistortionNode.h b/source/blender/compositor/nodes/COM_MovieDistortionNode.h
index da687080691..f4df48dac13 100644
--- a/source/blender/compositor/nodes/COM_MovieDistortionNode.h
+++ b/source/blender/compositor/nodes/COM_MovieDistortionNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MOVIEDISTORTIONNODE_H__
-#define __COM_MOVIEDISTORTIONNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class MovieDistortionNode : public Node {
MovieDistortionNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_NormalNode.h b/source/blender/compositor/nodes/COM_NormalNode.h
index 4151960c506..c23e83fb023 100644
--- a/source/blender/compositor/nodes/COM_NormalNode.h
+++ b/source/blender/compositor/nodes/COM_NormalNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_NORMALNODE_H__
-#define __COM_NORMALNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class NormalNode : public Node {
NormalNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* COM_NormalNODE_H */
diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.h b/source/blender/compositor/nodes/COM_NormalizeNode.h
index 593c98f2ce2..7e53ac7e9a0 100644
--- a/source/blender/compositor/nodes/COM_NormalizeNode.h
+++ b/source/blender/compositor/nodes/COM_NormalizeNode.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_NORMALIZENODE_H__
-#define __COM_NORMALIZENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class NormalizeNode : public Node {
NormalizeNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.h b/source/blender/compositor/nodes/COM_OutputFileNode.h
index 932fa375a3a..037a345fa50 100644
--- a/source/blender/compositor/nodes/COM_OutputFileNode.h
+++ b/source/blender/compositor/nodes/COM_OutputFileNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_OUTPUTFILENODE_H__
-#define __COM_OUTPUTFILENODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -31,5 +30,3 @@ class OutputFileNode : public Node {
OutputFileNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_PixelateNode.h b/source/blender/compositor/nodes/COM_PixelateNode.h
index f46035398e2..87cb4df59e8 100644
--- a/source/blender/compositor/nodes/COM_PixelateNode.h
+++ b/source/blender/compositor/nodes/COM_PixelateNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_PIXELATENODE_H__
-#define __COM_PIXELATENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class PixelateNode : public Node {
PixelateNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h
index 2c17739a220..36844bc1650 100644
--- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h
+++ b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h
@@ -16,8 +16,7 @@
* Copyright 2013, Blender Foundation.
*/
-#ifndef __COM_PLANETRACKDEFORMNODE_H__
-#define __COM_PLANETRACKDEFORMNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -33,5 +32,3 @@ class PlaneTrackDeformNode : public Node {
PlaneTrackDeformNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_PLANETRACKDEFORMNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.h b/source/blender/compositor/nodes/COM_RenderLayersNode.h
index c992f60581f..1ffd084ad1e 100644
--- a/source/blender/compositor/nodes/COM_RenderLayersNode.h
+++ b/source/blender/compositor/nodes/COM_RenderLayersNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_RENDERLAYERSNODE_H__
-#define __COM_RENDERLAYERSNODE_H__
+#pragma once
#include "COM_Node.h"
#include "COM_RenderLayersProg.h"
@@ -49,5 +48,3 @@ class RenderLayersNode : public Node {
void missingSocketLink(NodeConverter &converter, NodeOutput *output) const;
void missingRenderLink(NodeConverter &converter) const;
};
-
-#endif /* __COM_RENDERLAYERSNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_RotateNode.h b/source/blender/compositor/nodes/COM_RotateNode.h
index e7440bb7a8e..b75fdd52683 100644
--- a/source/blender/compositor/nodes/COM_RotateNode.h
+++ b/source/blender/compositor/nodes/COM_RotateNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ROTATENODE_H__
-#define __COM_ROTATENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class RotateNode : public Node {
RotateNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_ScaleNode.h b/source/blender/compositor/nodes/COM_ScaleNode.h
index b6e589cfcec..c9a02411b1c 100644
--- a/source/blender/compositor/nodes/COM_ScaleNode.h
+++ b/source/blender/compositor/nodes/COM_ScaleNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SCALENODE_H__
-#define __COM_SCALENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ScaleNode : public Node {
ScaleNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.h b/source/blender/compositor/nodes/COM_SeparateColorNode.h
index f98a9d6d12f..aaf86c6e22b 100644
--- a/source/blender/compositor/nodes/COM_SeparateColorNode.h
+++ b/source/blender/compositor/nodes/COM_SeparateColorNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SEPARATECOLORNODE_H__
-#define __COM_SEPARATECOLORNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -65,5 +64,3 @@ class SeparateYUVANode : public SeparateColorNode {
NodeOperation *getColorConverter(const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.h b/source/blender/compositor/nodes/COM_SetAlphaNode.h
index 9882b3e62e9..2e652539cec 100644
--- a/source/blender/compositor/nodes/COM_SetAlphaNode.h
+++ b/source/blender/compositor/nodes/COM_SetAlphaNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SETALPHANODE_H__
-#define __COM_SETALPHANODE_H__
+#pragma once
#include "COM_Node.h"
@@ -32,5 +31,3 @@ class SetAlphaNode : public Node {
}
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.h b/source/blender/compositor/nodes/COM_SocketProxyNode.h
index 21e888d323e..a0c0b63dafd 100644
--- a/source/blender/compositor/nodes/COM_SocketProxyNode.h
+++ b/source/blender/compositor/nodes/COM_SocketProxyNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SOCKETPROXYNODE_H__
-#define __COM_SOCKETPROXYNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -52,5 +51,3 @@ class SocketBufferNode : public Node {
SocketBufferNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.h b/source/blender/compositor/nodes/COM_SplitViewerNode.h
index 2e350720841..c9ce5164ef4 100644
--- a/source/blender/compositor/nodes/COM_SplitViewerNode.h
+++ b/source/blender/compositor/nodes/COM_SplitViewerNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SPLITVIEWERNODE_H__
-#define __COM_SPLITVIEWERNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -30,4 +29,3 @@ class SplitViewerNode : public Node {
SplitViewerNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.h b/source/blender/compositor/nodes/COM_Stabilize2dNode.h
index bbf7b239d82..cb46926a3f3 100644
--- a/source/blender/compositor/nodes/COM_Stabilize2dNode.h
+++ b/source/blender/compositor/nodes/COM_Stabilize2dNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_STABILIZE2DNODE_H__
-#define __COM_STABILIZE2DNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -31,5 +30,3 @@ class Stabilize2dNode : public Node {
Stabilize2dNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_SunBeamsNode.h b/source/blender/compositor/nodes/COM_SunBeamsNode.h
index 9d35f40f760..9a56fc1fcea 100644
--- a/source/blender/compositor/nodes/COM_SunBeamsNode.h
+++ b/source/blender/compositor/nodes/COM_SunBeamsNode.h
@@ -15,8 +15,7 @@
* Copyright 2014, Blender Foundation.
*/
-#ifndef __COM_SUNBEAMSNODE_H__
-#define __COM_SUNBEAMSNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -29,5 +28,3 @@ class SunBeamsNode : public Node {
SunBeamsNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_SwitchNode.h b/source/blender/compositor/nodes/COM_SwitchNode.h
index 509b748b18a..d4d8dd23a98 100644
--- a/source/blender/compositor/nodes/COM_SwitchNode.h
+++ b/source/blender/compositor/nodes/COM_SwitchNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SWITCHNODE_H__
-#define __COM_SWITCHNODE_H__
+#pragma once
#include "COM_Node.h"
#include "COM_NodeOperation.h"
@@ -31,4 +30,3 @@ class SwitchNode : public Node {
SwitchNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_SwitchViewNode.h b/source/blender/compositor/nodes/COM_SwitchViewNode.h
index 0260621961d..9423740f668 100644
--- a/source/blender/compositor/nodes/COM_SwitchViewNode.h
+++ b/source/blender/compositor/nodes/COM_SwitchViewNode.h
@@ -16,8 +16,7 @@
* Copyright 2015, Blender Foundation.
*/
-#ifndef __COM_SWITCHVIEWNODE_H__
-#define __COM_SWITCHVIEWNODE_H__
+#pragma once
#include "COM_Node.h"
#include "COM_NodeOperation.h"
@@ -31,4 +30,3 @@ class SwitchViewNode : public Node {
SwitchViewNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_TextureNode.h b/source/blender/compositor/nodes/COM_TextureNode.h
index 8fe620a89b3..4d780850190 100644
--- a/source/blender/compositor/nodes/COM_TextureNode.h
+++ b/source/blender/compositor/nodes/COM_TextureNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_TEXTURENODE_H__
-#define __COM_TEXTURENODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -31,5 +30,3 @@ class TextureNode : public Node {
TextureNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_TEXTURENODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_TimeNode.cpp b/source/blender/compositor/nodes/COM_TimeNode.cpp
index 9722ead0716..247e0d11df6 100644
--- a/source/blender/compositor/nodes/COM_TimeNode.cpp
+++ b/source/blender/compositor/nodes/COM_TimeNode.cpp
@@ -49,7 +49,7 @@ void TimeNode::convertToOperations(NodeConverter &converter,
fac = (context.getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
}
- BKE_curvemapping_initialize((CurveMapping *)node->storage);
+ BKE_curvemapping_init((CurveMapping *)node->storage);
fac = BKE_curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac);
operation->setValue(clamp_f(fac, 0.0f, 1.0f));
converter.addOperation(operation);
diff --git a/source/blender/compositor/nodes/COM_TimeNode.h b/source/blender/compositor/nodes/COM_TimeNode.h
index 230ffe3b676..78177014dc1 100644
--- a/source/blender/compositor/nodes/COM_TimeNode.h
+++ b/source/blender/compositor/nodes/COM_TimeNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_TIMENODE_H__
-#define __COM_TIMENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class TimeNode : public Node {
TimeNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_TonemapNode.h b/source/blender/compositor/nodes/COM_TonemapNode.h
index 9e6c01a5e45..d934a1ede5b 100644
--- a/source/blender/compositor/nodes/COM_TonemapNode.h
+++ b/source/blender/compositor/nodes/COM_TonemapNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_TONEMAPNODE_H__
-#define __COM_TONEMAPNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class TonemapNode : public Node {
TonemapNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_TrackPositionNode.h b/source/blender/compositor/nodes/COM_TrackPositionNode.h
index 7136077a123..37d3d25d592 100644
--- a/source/blender/compositor/nodes/COM_TrackPositionNode.h
+++ b/source/blender/compositor/nodes/COM_TrackPositionNode.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_TRACKPOSITIONNODE_H__
-#define __COM_TRACKPOSITIONNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -31,5 +30,3 @@ class TrackPositionNode : public Node {
TrackPositionNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_TRACKPOSITIONNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_TransformNode.h b/source/blender/compositor/nodes/COM_TransformNode.h
index 12eb66a19bb..bd01808d662 100644
--- a/source/blender/compositor/nodes/COM_TransformNode.h
+++ b/source/blender/compositor/nodes/COM_TransformNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_TRANSFORMNODE_H__
-#define __COM_TRANSFORMNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -31,5 +30,3 @@ class TransformNode : public Node {
TransformNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif /* __COM_TRANSFORMNODE_H__ */
diff --git a/source/blender/compositor/nodes/COM_TranslateNode.h b/source/blender/compositor/nodes/COM_TranslateNode.h
index d9ef6c639a0..d381274c0e5 100644
--- a/source/blender/compositor/nodes/COM_TranslateNode.h
+++ b/source/blender/compositor/nodes/COM_TranslateNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_TRANSLATENODE_H__
-#define __COM_TRANSLATENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class TranslateNode : public Node {
TranslateNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_ValueNode.h b/source/blender/compositor/nodes/COM_ValueNode.h
index a973649aa46..5179e6828e4 100644
--- a/source/blender/compositor/nodes/COM_ValueNode.h
+++ b/source/blender/compositor/nodes/COM_ValueNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_VALUENODE_H__
-#define __COM_VALUENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ValueNode : public Node {
ValueNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.h b/source/blender/compositor/nodes/COM_VectorBlurNode.h
index 027c241f72d..f370c82a1ee 100644
--- a/source/blender/compositor/nodes/COM_VectorBlurNode.h
+++ b/source/blender/compositor/nodes/COM_VectorBlurNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_VECTORBLURNODE_H__
-#define __COM_VECTORBLURNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class VectorBlurNode : public Node {
VectorBlurNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.h b/source/blender/compositor/nodes/COM_VectorCurveNode.h
index 14bea25cf8d..4d7f92897a1 100644
--- a/source/blender/compositor/nodes/COM_VectorCurveNode.h
+++ b/source/blender/compositor/nodes/COM_VectorCurveNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_VECTORCURVENODE_H__
-#define __COM_VECTORCURVENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class VectorCurveNode : public Node {
VectorCurveNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.h b/source/blender/compositor/nodes/COM_ViewLevelsNode.h
index 851b1ecbd78..0e931fed055 100644
--- a/source/blender/compositor/nodes/COM_ViewLevelsNode.h
+++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_VIEWLEVELSNODE_H__
-#define __COM_VIEWLEVELSNODE_H__
+#pragma once
#include "COM_Node.h"
@@ -30,5 +29,3 @@ class ViewLevelsNode : public Node {
ViewLevelsNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/nodes/COM_ViewerNode.h b/source/blender/compositor/nodes/COM_ViewerNode.h
index 6168623e69c..74758417014 100644
--- a/source/blender/compositor/nodes/COM_ViewerNode.h
+++ b/source/blender/compositor/nodes/COM_ViewerNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_VIEWERNODE_H__
-#define __COM_VIEWERNODE_H__
+#pragma once
#include "COM_Node.h"
#include "DNA_node_types.h"
@@ -30,4 +29,3 @@ class ViewerNode : public Node {
ViewerNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-#endif
diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.h b/source/blender/compositor/nodes/COM_ZCombineNode.h
index 95e81ca8c8f..ca54fd7fffa 100644
--- a/source/blender/compositor/nodes/COM_ZCombineNode.h
+++ b/source/blender/compositor/nodes/COM_ZCombineNode.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ZCOMBINENODE_H__
-#define __COM_ZCOMBINENODE_H__
+#pragma once
#include "COM_Node.h"
@@ -32,5 +31,3 @@ class ZCombineNode : public Node {
}
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h
index a4475bc2fbc..de3d6bd1ee0 100644
--- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h
+++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ALPHAOVERKEYOPERATION_H__
-#define __COM_ALPHAOVERKEYOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -36,4 +36,3 @@ class AlphaOverKeyOperation : public MixBaseOperation {
*/
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h
index 88fa3d963f4..22d64807512 100644
--- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h
+++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ALPHAOVERMIXEDOPERATION_H__
-#define __COM_ALPHAOVERMIXEDOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -44,4 +44,3 @@ class AlphaOverMixedOperation : public MixBaseOperation {
this->m_x = x;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h
index 4ef5f9d996e..bc5cd07baf8 100644
--- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h
+++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ALPHAOVERPREMULTIPLYOPERATION_H__
-#define __COM_ALPHAOVERPREMULTIPLYOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -36,4 +36,3 @@ class AlphaOverPremultiplyOperation : public MixBaseOperation {
*/
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.h b/source/blender/compositor/operations/COM_AntiAliasOperation.h
index 6141fb92c3f..8600c6dd481 100644
--- a/source/blender/compositor/operations/COM_AntiAliasOperation.h
+++ b/source/blender/compositor/operations/COM_AntiAliasOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ANTIALIASOPERATION_H__
-#define __COM_ANTIALIASOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -56,4 +56,3 @@ class AntiAliasOperation : public NodeOperation {
ReadBufferOperation *readOperation,
rcti *output);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.h b/source/blender/compositor/operations/COM_BilateralBlurOperation.h
index c3482005d8c..a54e830459b 100644
--- a/source/blender/compositor/operations/COM_BilateralBlurOperation.h
+++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BILATERALBLUROPERATION_H__
-#define __COM_BILATERALBLUROPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "COM_QualityStepHelper.h"
@@ -55,4 +55,3 @@ class BilateralBlurOperation : public NodeOperation, public QualityStepHelper {
this->m_data = data;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h
index 07893c19126..e4ac8b3c874 100644
--- a/source/blender/compositor/operations/COM_BlurBaseOperation.h
+++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BLURBASEOPERATION_H__
-#define __COM_BLURBASEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "COM_QualityStepHelper.h"
@@ -77,4 +77,3 @@ class BlurBaseOperation : public NodeOperation, public QualityStepHelper {
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.h b/source/blender/compositor/operations/COM_BokehBlurOperation.h
index 4f594f16cb4..e6873a4b70b 100644
--- a/source/blender/compositor/operations/COM_BokehBlurOperation.h
+++ b/source/blender/compositor/operations/COM_BokehBlurOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BOKEHBLUROPERATION_H__
-#define __COM_BOKEHBLUROPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
#include "COM_QualityStepHelper.h"
@@ -78,4 +77,3 @@ class BokehBlurOperation : public NodeOperation, public QualityStepHelper {
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h
index e907559d6e7..db1d3976d44 100644
--- a/source/blender/compositor/operations/COM_BokehImageOperation.h
+++ b/source/blender/compositor/operations/COM_BokehImageOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BOKEHIMAGEOPERATION_H__
-#define __COM_BOKEHIMAGEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -149,4 +149,3 @@ class BokehImageOperation : public NodeOperation {
this->m_deleteData = true;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.h b/source/blender/compositor/operations/COM_BoxMaskOperation.h
index f770922ee7c..070a7f52b1b 100644
--- a/source/blender/compositor/operations/COM_BoxMaskOperation.h
+++ b/source/blender/compositor/operations/COM_BoxMaskOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BOXMASKOPERATION_H__
-#define __COM_BOXMASKOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class BoxMaskOperation : public NodeOperation {
@@ -63,4 +63,3 @@ class BoxMaskOperation : public NodeOperation {
this->m_maskType = maskType;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.h b/source/blender/compositor/operations/COM_BrightnessOperation.h
index df6b3ef7b6e..28bd3576201 100644
--- a/source/blender/compositor/operations/COM_BrightnessOperation.h
+++ b/source/blender/compositor/operations/COM_BrightnessOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_BRIGHTNESSOPERATION_H__
-#define __COM_BRIGHTNESSOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class BrightnessOperation : public NodeOperation {
@@ -51,4 +51,3 @@ class BrightnessOperation : public NodeOperation {
void setUsePremultiply(bool use_premultiply);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.h b/source/blender/compositor/operations/COM_CalculateMeanOperation.h
index 38d68b2a6fd..aa08555467b 100644
--- a/source/blender/compositor/operations/COM_CalculateMeanOperation.h
+++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CALCULATEMEANOPERATION_H__
-#define __COM_CALCULATEMEANOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -67,4 +67,3 @@ class CalculateMeanOperation : public NodeOperation {
protected:
void calculateMean(MemoryBuffer *tile);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h
index 377276777f0..2ab0e82728d 100644
--- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h
+++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CALCULATESTANDARDDEVIATIONOPERATION_H__
-#define __COM_CALCULATESTANDARDDEVIATIONOPERATION_H__
+#pragma once
+
#include "COM_CalculateMeanOperation.h"
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -40,4 +40,3 @@ class CalculateStandardDeviationOperation : public CalculateMeanOperation {
void *initializeTileData(rcti *rect);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.h b/source/blender/compositor/operations/COM_ChangeHSVOperation.h
index 3898345f922..b4fa1a3bdd4 100644
--- a/source/blender/compositor/operations/COM_ChangeHSVOperation.h
+++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CHANGEHSVOPERATION_H__
-#define __COM_CHANGEHSVOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -45,4 +45,3 @@ class ChangeHSVOperation : public NodeOperation {
*/
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.h b/source/blender/compositor/operations/COM_ChannelMatteOperation.h
index ad88b41cc91..d4c097fe66e 100644
--- a/source/blender/compositor/operations/COM_ChannelMatteOperation.h
+++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.h
@@ -16,8 +16,8 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_CHANNELMATTEOPERATION_H__
-#define __COM_CHANNELMATTEOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -70,4 +70,3 @@ class ChannelMatteOperation : public NodeOperation {
this->m_matte_channel = custom2;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.h b/source/blender/compositor/operations/COM_ChromaMatteOperation.h
index 58da839823d..5c4ada8de38 100644
--- a/source/blender/compositor/operations/COM_ChromaMatteOperation.h
+++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CHROMAMATTEOPERATION_H__
-#define __COM_CHROMAMATTEOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -49,4 +49,3 @@ class ChromaMatteOperation : public NodeOperation {
this->m_settings = nodeChroma;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h
index fd1d51a293b..77ead2f1d26 100644
--- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h
+++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORBALANCEASCCDLOPERATION_H__
-#define __COM_COLORBALANCEASCCDLOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -70,4 +70,3 @@ class ColorBalanceASCCDLOperation : public NodeOperation {
copy_v3_v3(this->m_slope, slope);
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h
index a2d4b4cd13a..c34591172b9 100644
--- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h
+++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORBALANCELGGOPERATION_H__
-#define __COM_COLORBALANCELGGOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -70,4 +70,3 @@ class ColorBalanceLGGOperation : public NodeOperation {
copy_v3_v3(this->m_gamma_inv, gamma_inv);
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h
index ec9632acc7c..66213eb88a4 100644
--- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h
+++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORCORRECTIONOPERATION_H__
-#define __COM_COLORCORRECTIONOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class ColorCorrectionOperation : public NodeOperation {
@@ -68,4 +68,3 @@ class ColorCorrectionOperation : public NodeOperation {
this->m_blueChannelEnabled = enabled;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.h b/source/blender/compositor/operations/COM_ColorCurveOperation.h
index 7869d1c4a56..65a822508b8 100644
--- a/source/blender/compositor/operations/COM_ColorCurveOperation.h
+++ b/source/blender/compositor/operations/COM_ColorCurveOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORCURVEOPERATION_H__
-#define __COM_COLORCURVEOPERATION_H__
+#pragma once
+
#include "COM_CurveBaseOperation.h"
#include "COM_NodeOperation.h"
#include "DNA_color_types.h"
@@ -88,5 +88,3 @@ class ConstantLevelColorCurveOperation : public CurveBaseOperation {
copy_v3_v3(this->m_white, white);
}
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.h b/source/blender/compositor/operations/COM_ColorMatteOperation.h
index 7e8a0e295e1..bb00c344606 100644
--- a/source/blender/compositor/operations/COM_ColorMatteOperation.h
+++ b/source/blender/compositor/operations/COM_ColorMatteOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORMATTEOPERATION_H__
-#define __COM_COLORMATTEOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -49,4 +49,3 @@ class ColorMatteOperation : public NodeOperation {
this->m_settings = nodeChroma;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.h b/source/blender/compositor/operations/COM_ColorRampOperation.h
index 3e2acda1d10..b4253a3f074 100644
--- a/source/blender/compositor/operations/COM_ColorRampOperation.h
+++ b/source/blender/compositor/operations/COM_ColorRampOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORRAMPOPERATION_H__
-#define __COM_COLORRAMPOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_texture_types.h"
@@ -52,4 +52,3 @@ class ColorRampOperation : public NodeOperation {
this->m_colorBand = colorBand;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.h b/source/blender/compositor/operations/COM_ColorSpillOperation.h
index 73f4f5b045d..560d198693f 100644
--- a/source/blender/compositor/operations/COM_ColorSpillOperation.h
+++ b/source/blender/compositor/operations/COM_ColorSpillOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COLORSPILLOPERATION_H__
-#define __COM_COLORSPILLOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -64,5 +64,3 @@ class ColorSpillOperation : public NodeOperation {
float calculateMapValue(float fac, float *input);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h
index 8db8fe00d3c..3633bfd511c 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.h
+++ b/source/blender/compositor/operations/COM_CompositorOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_COMPOSITOROPERATION_H__
-#define __COM_COMPOSITOROPERATION_H__
+#pragma once
+
#include "BLI_rect.h"
#include "BLI_string.h"
#include "COM_NodeOperation.h"
@@ -123,4 +123,3 @@ class CompositorOperation : public NodeOperation {
this->m_active = active;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h
index 7cc39a47dd0..8fce5ef3e1a 100644
--- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h
+++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CONVERTCOLORPROFILEOPERATION_H__
-#define __COM_CONVERTCOLORPROFILEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -80,4 +80,3 @@ class ConvertColorProfileOperation : public NodeOperation {
this->m_predivided = predivided;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h
index 7c3e0ed9738..3babcfe4dc3 100644
--- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h
+++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CONVERTDEPTHTORADIUSOPERATION_H__
-#define __COM_CONVERTDEPTHTORADIUSOPERATION_H__
+#pragma once
+
#include "COM_FastGaussianBlurOperation.h"
#include "COM_NodeOperation.h"
#include "DNA_object_types.h"
@@ -81,4 +81,3 @@ class ConvertDepthToRadiusOperation : public NodeOperation {
this->m_blurPostOperation = operation;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ConvertOperation.h b/source/blender/compositor/operations/COM_ConvertOperation.h
index a4cf05372a5..ca026528a38 100644
--- a/source/blender/compositor/operations/COM_ConvertOperation.h
+++ b/source/blender/compositor/operations/COM_ConvertOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CONVERTOPERATION_H__
-#define __COM_CONVERTOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -183,5 +182,3 @@ class CombineChannelsOperation : public NodeOperation {
void initExecution();
void deinitExecution();
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h
index 17509b018bf..ab4b8a1dad1 100644
--- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h
+++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CONVOLUTIONEDGEFILTEROPERATION_H__
-#define __COM_CONVOLUTIONEDGEFILTEROPERATION_H__
+#pragma once
#include "COM_ConvolutionFilterOperation.h"
@@ -26,5 +25,3 @@ class ConvolutionEdgeFilterOperation : public ConvolutionFilterOperation {
ConvolutionEdgeFilterOperation();
void executePixel(float output[4], int x, int y, void *data);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h
index 78db5a5ae9d..d178b0a7418 100644
--- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h
+++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CONVOLUTIONFILTEROPERATION_H__
-#define __COM_CONVOLUTIONFILTEROPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -43,5 +42,3 @@ class ConvolutionFilterOperation : public NodeOperation {
void initExecution();
void deinitExecution();
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h
index 36c18d29e92..f20664f0501 100644
--- a/source/blender/compositor/operations/COM_CropOperation.h
+++ b/source/blender/compositor/operations/COM_CropOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CROPOPERATION_H__
-#define __COM_CROPOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -64,4 +63,3 @@ class CropImageOperation : public CropBaseOperation {
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.h b/source/blender/compositor/operations/COM_CryptomatteOperation.h
index 459d8b65f12..8c5a3134720 100644
--- a/source/blender/compositor/operations/COM_CryptomatteOperation.h
+++ b/source/blender/compositor/operations/COM_CryptomatteOperation.h
@@ -16,8 +16,8 @@
* Copyright 2018, Blender Foundation.
*/
-#ifndef __COM_CRYPTOMATTEOPERATION_H__
-#define __COM_CRYPTOMATTEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class CryptomatteOperation : public NodeOperation {
@@ -34,4 +34,3 @@ class CryptomatteOperation : public NodeOperation {
void addObjectIndex(float objectIndex);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp
index b18e77cf0e3..855f728f7bf 100644
--- a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp
@@ -35,7 +35,7 @@ CurveBaseOperation::~CurveBaseOperation()
void CurveBaseOperation::initExecution()
{
- BKE_curvemapping_initialize(this->m_curveMapping);
+ BKE_curvemapping_init(this->m_curveMapping);
}
void CurveBaseOperation::deinitExecution()
{
diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.h b/source/blender/compositor/operations/COM_CurveBaseOperation.h
index f42ce3c366f..63e667cfe12 100644
--- a/source/blender/compositor/operations/COM_CurveBaseOperation.h
+++ b/source/blender/compositor/operations/COM_CurveBaseOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_CURVEBASEOPERATION_H__
-#define __COM_CURVEBASEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_color_types.h"
@@ -40,4 +40,3 @@ class CurveBaseOperation : public NodeOperation {
void setCurveMapping(CurveMapping *mapping);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.h b/source/blender/compositor/operations/COM_DenoiseOperation.h
index 6a53eead65c..5af6e16c958 100644
--- a/source/blender/compositor/operations/COM_DenoiseOperation.h
+++ b/source/blender/compositor/operations/COM_DenoiseOperation.h
@@ -16,8 +16,7 @@
* Copyright 2019, Blender Foundation.
*/
-#ifndef __COM_DENOISEOPERATION_H__
-#define __COM_DENOISEOPERATION_H__
+#pragma once
#include "COM_SingleThreadedOperation.h"
#include "DNA_node_types.h"
@@ -65,5 +64,3 @@ class DenoiseOperation : public SingleThreadedOperation {
MemoryBuffer *createMemoryBuffer(rcti *rect);
};
-
-#endif /* __COM_DENOISEOPERATION_H__ */
diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.h b/source/blender/compositor/operations/COM_DespeckleOperation.h
index 280948b7fbe..af37c276bd2 100644
--- a/source/blender/compositor/operations/COM_DespeckleOperation.h
+++ b/source/blender/compositor/operations/COM_DespeckleOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DESPECKLEOPERATION_H__
-#define __COM_DESPECKLEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class DespeckleOperation : public NodeOperation {
@@ -51,5 +51,3 @@ class DespeckleOperation : public NodeOperation {
void initExecution();
void deinitExecution();
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h
index e96e212e511..beaa4400712 100644
--- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h
+++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DIFFERENCEMATTEOPERATION_H__
-#define __COM_DIFFERENCEMATTEOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -49,4 +49,3 @@ class DifferenceMatteOperation : public NodeOperation {
this->m_settings = nodeChroma;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h
index bd7e0938c58..95a799ab648 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.h
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DILATEERODEOPERATION_H__
-#define __COM_DILATEERODEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class DilateErodeThresholdOperation : public NodeOperation {
@@ -180,5 +180,3 @@ class ErodeStepOperation : public DilateStepOperation {
void *initializeTileData(rcti *rect);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h
index f8b7bab010b..57fc0bb7fa3 100644
--- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h
+++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DIRECTIONALBLUROPERATION_H__
-#define __COM_DIRECTIONALBLUROPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "COM_QualityStepHelper.h"
@@ -64,4 +64,3 @@ class DirectionalBlurOperation : public NodeOperation, public QualityStepHelper
list<cl_mem> *clMemToCleanUp,
list<cl_kernel> *clKernelsToCleanUp);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.h b/source/blender/compositor/operations/COM_DisplaceOperation.h
index 4e44572fcf2..ee06bf320a6 100644
--- a/source/blender/compositor/operations/COM_DisplaceOperation.h
+++ b/source/blender/compositor/operations/COM_DisplaceOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DISPLACEOPERATION_H__
-#define __COM_DISPLACEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class DisplaceOperation : public NodeOperation {
@@ -64,4 +64,3 @@ class DisplaceOperation : public NodeOperation {
bool read_displacement(
float x, float y, float xscale, float yscale, const float origin[2], float &r_u, float &r_v);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h
index 6d4d6047137..6930985b0e5 100644
--- a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h
+++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h
@@ -16,8 +16,8 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_DISPLACESIMPLEOPERATION_H__
-#define __COM_DISPLACESIMPLEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class DisplaceSimpleOperation : public NodeOperation {
@@ -58,4 +58,3 @@ class DisplaceSimpleOperation : public NodeOperation {
*/
void deinitExecution();
};
-#endif
diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h
index c64c6da8d24..d99ab262c18 100644
--- a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h
+++ b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DISTANCERGBMATTEOPERATION_H__
-#define __COM_DISTANCERGBMATTEOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -51,4 +51,3 @@ class DistanceRGBMatteOperation : public NodeOperation {
this->m_settings = nodeChroma;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h
index 1cb477bc05d..e9b2cda6251 100644
--- a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h
+++ b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DISTANCEYCCMATTEOPERATION_H__
-#define __COM_DISTANCEYCCMATTEOPERATION_H__
+#pragma once
+
#include "COM_DistanceRGBMatteOperation.h"
#include "COM_MixOperation.h"
@@ -35,4 +35,3 @@ class DistanceYCCMatteOperation : public DistanceRGBMatteOperation {
*/
DistanceYCCMatteOperation();
};
-#endif
diff --git a/source/blender/compositor/operations/COM_DotproductOperation.h b/source/blender/compositor/operations/COM_DotproductOperation.h
index 9ef9753f4c9..63b735ce30f 100644
--- a/source/blender/compositor/operations/COM_DotproductOperation.h
+++ b/source/blender/compositor/operations/COM_DotproductOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DOTPRODUCTOPERATION_H__
-#define __COM_DOTPRODUCTOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -33,5 +32,3 @@ class DotproductOperation : public NodeOperation {
void initExecution();
void deinitExecution();
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
index ae6f49bffcd..84f7fe2d225 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
@@ -26,8 +26,8 @@
// this part has been copied from the double edge mask
static void do_adjacentKeepBorders(unsigned int t,
unsigned int rw,
- unsigned int *limask,
- unsigned int *lomask,
+ const unsigned int *limask,
+ const unsigned int *lomask,
unsigned int *lres,
float *res,
unsigned int *rsize)
@@ -196,8 +196,8 @@ static void do_adjacentKeepBorders(unsigned int t,
static void do_adjacentBleedBorders(unsigned int t,
unsigned int rw,
- unsigned int *limask,
- unsigned int *lomask,
+ const unsigned int *limask,
+ const unsigned int *lomask,
unsigned int *lres,
float *res,
unsigned int *rsize)
@@ -417,8 +417,8 @@ static void do_adjacentBleedBorders(unsigned int t,
static void do_allKeepBorders(unsigned int t,
unsigned int rw,
- unsigned int *limask,
- unsigned int *lomask,
+ const unsigned int *limask,
+ const unsigned int *lomask,
unsigned int *lres,
float *res,
unsigned int *rsize)
@@ -579,8 +579,8 @@ static void do_allKeepBorders(unsigned int t,
static void do_allBleedBorders(unsigned int t,
unsigned int rw,
- unsigned int *limask,
- unsigned int *lomask,
+ const unsigned int *limask,
+ const unsigned int *lomask,
unsigned int *lres,
float *res,
unsigned int *rsize)
@@ -793,8 +793,8 @@ static void do_allBleedBorders(unsigned int t,
static void do_allEdgeDetection(unsigned int t,
unsigned int rw,
- unsigned int *limask,
- unsigned int *lomask,
+ const unsigned int *limask,
+ const unsigned int *lomask,
unsigned int *lres,
float *res,
unsigned int *rsize,
@@ -863,8 +863,8 @@ static void do_allEdgeDetection(unsigned int t,
static void do_adjacentEdgeDetection(unsigned int t,
unsigned int rw,
- unsigned int *limask,
- unsigned int *lomask,
+ const unsigned int *limask,
+ const unsigned int *lomask,
unsigned int *lres,
float *res,
unsigned int *rsize,
@@ -935,7 +935,7 @@ static void do_adjacentEdgeDetection(unsigned int t,
static void do_createEdgeLocationBuffer(unsigned int t,
unsigned int rw,
- unsigned int *lres,
+ const unsigned int *lres,
float *res,
unsigned short *gbuf,
unsigned int *innerEdgeOffset,
@@ -1060,7 +1060,7 @@ static void do_createEdgeLocationBuffer(unsigned int t,
static void do_fillGradientBuffer(unsigned int rw,
float *res,
- unsigned short *gbuf,
+ const unsigned short *gbuf,
unsigned int isz,
unsigned int osz,
unsigned int gsz,
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h
index 40cfa370cb7..0c77e83daec 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_DOUBLEEDGEMASKOPERATION_H__
-#define __COM_DOUBLEEDGEMASKOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class DoubleEdgeMaskOperation : public NodeOperation {
@@ -65,4 +65,3 @@ class DoubleEdgeMaskOperation : public NodeOperation {
this->m_keepInside = keepInside;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.h b/source/blender/compositor/operations/COM_EllipseMaskOperation.h
index b73a35a5452..2e6b1f782a1 100644
--- a/source/blender/compositor/operations/COM_EllipseMaskOperation.h
+++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ELLIPSEMASKOPERATION_H__
-#define __COM_ELLIPSEMASKOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class EllipseMaskOperation : public NodeOperation {
@@ -63,4 +63,3 @@ class EllipseMaskOperation : public NodeOperation {
this->m_maskType = maskType;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
index 22f9a6f9cf2..6ab6474c20a 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_FASTGAUSSIANBLUROPERATION_H__
-#define __COM_FASTGAUSSIANBLUROPERATION_H__
+#pragma once
#include "COM_BlurBaseOperation.h"
#include "DNA_node_types.h"
@@ -80,5 +79,3 @@ class FastGaussianBlurValueOperation : public NodeOperation {
this->m_overlay = overlay;
}
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_FlipOperation.h b/source/blender/compositor/operations/COM_FlipOperation.h
index 2d00c50dc8a..711b51261e6 100644
--- a/source/blender/compositor/operations/COM_FlipOperation.h
+++ b/source/blender/compositor/operations/COM_FlipOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_FLIPOPERATION_H__
-#define __COM_FLIPOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -45,5 +44,3 @@ class FlipOperation : public NodeOperation {
this->m_flipY = flipY;
}
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.h b/source/blender/compositor/operations/COM_GammaCorrectOperation.h
index 26e31df880f..be57e279ac8 100644
--- a/source/blender/compositor/operations/COM_GammaCorrectOperation.h
+++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GAMMACORRECTOPERATION_H__
-#define __COM_GAMMACORRECTOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class GammaCorrectOperation : public NodeOperation {
@@ -71,5 +71,3 @@ class GammaUncorrectOperation : public NodeOperation {
*/
void deinitExecution();
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_GammaOperation.h b/source/blender/compositor/operations/COM_GammaOperation.h
index ba0b84db931..493fdb1f889 100644
--- a/source/blender/compositor/operations/COM_GammaOperation.h
+++ b/source/blender/compositor/operations/COM_GammaOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GAMMAOPERATION_H__
-#define __COM_GAMMAOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class GammaOperation : public NodeOperation {
@@ -46,4 +46,3 @@ class GammaOperation : public NodeOperation {
*/
void deinitExecution();
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
index 9de75ff53a7..a8e1ddfb885 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GAUSSIANALPHAXBLUROPERATION_H__
-#define __COM_GAUSSIANALPHAXBLUROPERATION_H__
+#pragma once
+
#include "COM_BlurBaseOperation.h"
#include "COM_NodeOperation.h"
@@ -65,4 +65,3 @@ class GaussianAlphaXBlurOperation : public BlurBaseOperation {
this->m_falloff = falloff;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
index 44689922bfc..df34f15fccc 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GAUSSIANALPHAYBLUROPERATION_H__
-#define __COM_GAUSSIANALPHAYBLUROPERATION_H__
+#pragma once
+
#include "COM_BlurBaseOperation.h"
#include "COM_NodeOperation.h"
@@ -65,4 +65,3 @@ class GaussianAlphaYBlurOperation : public BlurBaseOperation {
this->m_falloff = falloff;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
index 3aa380853bd..b4b5c0e8b2f 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GAUSSIANBOKEHBLUROPERATION_H__
-#define __COM_GAUSSIANBOKEHBLUROPERATION_H__
+#pragma once
+
#include "COM_BlurBaseOperation.h"
#include "COM_NodeOperation.h"
#include "COM_QualityStepHelper.h"
@@ -75,5 +75,3 @@ class GaussianBlurReferenceOperation : public BlurBaseOperation {
ReadBufferOperation *readOperation,
rcti *output);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h
index c5c08df8ce7..1bd6ef20a48 100644
--- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GAUSSIANXBLUROPERATION_H__
-#define __COM_GAUSSIANXBLUROPERATION_H__
+#pragma once
+
#include "COM_BlurBaseOperation.h"
#include "COM_NodeOperation.h"
@@ -65,4 +65,3 @@ class GaussianXBlurOperation : public BlurBaseOperation {
this->setOpenCL(m_data.sizex >= 128);
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h
index 92154aa7518..a9af28791f8 100644
--- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GAUSSIANYBLUROPERATION_H__
-#define __COM_GAUSSIANYBLUROPERATION_H__
+#pragma once
+
#include "COM_BlurBaseOperation.h"
#include "COM_NodeOperation.h"
@@ -65,4 +65,3 @@ class GaussianYBlurOperation : public BlurBaseOperation {
this->setOpenCL(m_data.sizex >= 128);
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h
index ba2b9a8f4b8..aabb76f5cf0 100644
--- a/source/blender/compositor/operations/COM_GlareBaseOperation.h
+++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GLAREBASEOPERATION_H__
-#define __COM_GLAREBASEOPERATION_H__
+#pragma once
#include "COM_SingleThreadedOperation.h"
#include "DNA_node_types.h"
@@ -74,4 +73,3 @@ class GlareBaseOperation : public SingleThreadedOperation {
MemoryBuffer *createMemoryBuffer(rcti *rect);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
index b43b94af06a..0087c720ac0 100644
--- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
@@ -198,7 +198,7 @@ static void FHT2D(
//------------------------------------------------------------------------------
/* 2D convolution calc, d1 *= d2, M/N - > log2 of width/height */
-static void fht_convolve(fREAL *d1, fREAL *d2, unsigned int M, unsigned int N)
+static void fht_convolve(fREAL *d1, const fREAL *d2, unsigned int M, unsigned int N)
{
fREAL a, b;
unsigned int i, j, k, L, mj, mL;
diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.h b/source/blender/compositor/operations/COM_GlareFogGlowOperation.h
index dae0b714e56..9084f27052e 100644
--- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.h
+++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GLAREFOGGLOWOPERATION_H__
-#define __COM_GLAREFOGGLOWOPERATION_H__
+#pragma once
+
#include "COM_GlareBaseOperation.h"
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -31,4 +31,3 @@ class GlareFogGlowOperation : public GlareBaseOperation {
protected:
void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.h b/source/blender/compositor/operations/COM_GlareGhostOperation.h
index c0b41762c8a..8ecf8da3385 100644
--- a/source/blender/compositor/operations/COM_GlareGhostOperation.h
+++ b/source/blender/compositor/operations/COM_GlareGhostOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GLAREGHOSTOPERATION_H__
-#define __COM_GLAREGHOSTOPERATION_H__
+#pragma once
+
#include "COM_GlareBaseOperation.h"
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -31,4 +31,3 @@ class GlareGhostOperation : public GlareBaseOperation {
protected:
void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h
index b6e2e499f64..0f5913fcef9 100644
--- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h
+++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GLARESIMPLESTAROPERATION_H__
-#define __COM_GLARESIMPLESTAROPERATION_H__
+#pragma once
+
#include "COM_GlareBaseOperation.h"
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -31,4 +31,3 @@ class GlareSimpleStarOperation : public GlareBaseOperation {
protected:
void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.h b/source/blender/compositor/operations/COM_GlareStreaksOperation.h
index 9f137f90b71..df31981170d 100644
--- a/source/blender/compositor/operations/COM_GlareStreaksOperation.h
+++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GLARESTREAKSOPERATION_H__
-#define __COM_GLARESTREAKSOPERATION_H__
+#pragma once
+
#include "COM_GlareBaseOperation.h"
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -31,4 +31,3 @@ class GlareStreaksOperation : public GlareBaseOperation {
protected:
void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.h b/source/blender/compositor/operations/COM_GlareThresholdOperation.h
index 385111cdf0b..e4ac36f2053 100644
--- a/source/blender/compositor/operations/COM_GlareThresholdOperation.h
+++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_GLARETHRESHOLDOPERATION_H__
-#define __COM_GLARETHRESHOLDOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_light_types.h"
@@ -58,4 +58,3 @@ class GlareThresholdOperation : public NodeOperation {
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h
index 0624a5c022f..f29a932d7f8 100644
--- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h
+++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_HUESATURATIONVALUECORRECTOPERATION_H__
-#define __COM_HUESATURATIONVALUECORRECTOPERATION_H__
+#pragma once
+
#include "COM_CurveBaseOperation.h"
#include "COM_NodeOperation.h"
@@ -46,4 +46,3 @@ class HueSaturationValueCorrectOperation : public CurveBaseOperation {
*/
void deinitExecution();
};
-#endif
diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.h b/source/blender/compositor/operations/COM_IDMaskOperation.h
index b3a40106b9d..abd2a719371 100644
--- a/source/blender/compositor/operations/COM_IDMaskOperation.h
+++ b/source/blender/compositor/operations/COM_IDMaskOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_IDMASKOPERATION_H__
-#define __COM_IDMASKOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class IDMaskOperation : public NodeOperation {
@@ -35,4 +35,3 @@ class IDMaskOperation : public NodeOperation {
this->m_objectIndex = objectIndex;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h
index 3e081ee0000..fcffdc7aae9 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.h
+++ b/source/blender/compositor/operations/COM_ImageOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_IMAGEOPERATION_H__
-#define __COM_IMAGEOPERATION_H__
+#pragma once
#include "BKE_image.h"
#include "BLI_listbase.h"
@@ -103,4 +102,3 @@ class ImageDepthOperation : public BaseImageOperation {
ImageDepthOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cpp b/source/blender/compositor/operations/COM_InpaintOperation.cpp
index 0967984899d..b8329b1cb29 100644
--- a/source/blender/compositor/operations/COM_InpaintOperation.cpp
+++ b/source/blender/compositor/operations/COM_InpaintOperation.cpp
@@ -34,7 +34,7 @@ InpaintSimpleOperation::InpaintSimpleOperation() : NodeOperation()
this->setComplex(true);
this->m_inputImageProgram = NULL;
this->m_pixelorder = NULL;
- this->m_manhatten_distance = NULL;
+ this->m_manhattan_distance = NULL;
this->m_cached_buffer = NULL;
this->m_cached_buffer_ready = false;
}
@@ -43,7 +43,7 @@ void InpaintSimpleOperation::initExecution()
this->m_inputImageProgram = this->getInputSocketReader(0);
this->m_pixelorder = NULL;
- this->m_manhatten_distance = NULL;
+ this->m_manhattan_distance = NULL;
this->m_cached_buffer = NULL;
this->m_cached_buffer_ready = false;
@@ -85,7 +85,7 @@ int InpaintSimpleOperation::mdist(int x, int y)
ASSERT_XY_RANGE(x, y);
- return this->m_manhatten_distance[y * width + x];
+ return this->m_manhattan_distance[y * width + x];
}
bool InpaintSimpleOperation::next_pixel(int &x, int &y, int &curr, int iters)
@@ -108,11 +108,11 @@ bool InpaintSimpleOperation::next_pixel(int &x, int &y, int &curr, int iters)
return true;
}
-void InpaintSimpleOperation::calc_manhatten_distance()
+void InpaintSimpleOperation::calc_manhattan_distance()
{
int width = this->getWidth();
int height = this->getHeight();
- short *m = this->m_manhatten_distance = (short *)MEM_mallocN(sizeof(short) * width * height,
+ short *m = this->m_manhattan_distance = (short *)MEM_mallocN(sizeof(short) * width * height,
__func__);
int *offsets;
@@ -223,7 +223,7 @@ void *InpaintSimpleOperation::initializeTileData(rcti *rect)
MemoryBuffer *buf = (MemoryBuffer *)this->m_inputImageProgram->initializeTileData(rect);
this->m_cached_buffer = (float *)MEM_dupallocN(buf->getBuffer());
- this->calc_manhatten_distance();
+ this->calc_manhattan_distance();
int curr = 0;
int x, y;
@@ -258,9 +258,9 @@ void InpaintSimpleOperation::deinitExecution()
this->m_pixelorder = NULL;
}
- if (this->m_manhatten_distance) {
- MEM_freeN(this->m_manhatten_distance);
- this->m_manhatten_distance = NULL;
+ if (this->m_manhattan_distance) {
+ MEM_freeN(this->m_manhattan_distance);
+ this->m_manhattan_distance = NULL;
}
this->m_cached_buffer_ready = false;
}
diff --git a/source/blender/compositor/operations/COM_InpaintOperation.h b/source/blender/compositor/operations/COM_InpaintOperation.h
index 2fef7c590ea..86f3393e1ea 100644
--- a/source/blender/compositor/operations/COM_InpaintOperation.h
+++ b/source/blender/compositor/operations/COM_InpaintOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_INPAINTOPERATION_H__
-#define __COM_INPAINTOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class InpaintSimpleOperation : public NodeOperation {
@@ -34,7 +34,7 @@ class InpaintSimpleOperation : public NodeOperation {
int *m_pixelorder;
int m_area_size;
- short *m_manhatten_distance;
+ short *m_manhattan_distance;
public:
InpaintSimpleOperation();
@@ -65,12 +65,10 @@ class InpaintSimpleOperation : public NodeOperation {
rcti *output);
private:
- void calc_manhatten_distance();
+ void calc_manhattan_distance();
void clamp_xy(int &x, int &y);
float *get_pixel(int x, int y);
int mdist(int x, int y);
bool next_pixel(int &x, int &y, int &curr, int iters);
void pix_step(int x, int y);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_InvertOperation.h b/source/blender/compositor/operations/COM_InvertOperation.h
index 39161455a76..5399122ab62 100644
--- a/source/blender/compositor/operations/COM_InvertOperation.h
+++ b/source/blender/compositor/operations/COM_InvertOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_INVERTOPERATION_H__
-#define __COM_INVERTOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class InvertOperation : public NodeOperation {
@@ -58,4 +58,3 @@ class InvertOperation : public NodeOperation {
this->m_alpha = alpha;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.h b/source/blender/compositor/operations/COM_KeyingBlurOperation.h
index 0e45f1c32b8..6a2b43a6cd4 100644
--- a/source/blender/compositor/operations/COM_KeyingBlurOperation.h
+++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_KEYINGBLUROPERATION_H__
-#define __COM_KEYINGBLUROPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -54,5 +53,3 @@ class KeyingBlurOperation : public NodeOperation {
ReadBufferOperation *readOperation,
rcti *output);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.h b/source/blender/compositor/operations/COM_KeyingClipOperation.h
index 8237c443cf2..9d876966e96 100644
--- a/source/blender/compositor/operations/COM_KeyingClipOperation.h
+++ b/source/blender/compositor/operations/COM_KeyingClipOperation.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_KEYINGCLIPOPERATION_H__
-#define __COM_KEYINGCLIPOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -68,5 +67,3 @@ class KeyingClipOperation : public NodeOperation {
ReadBufferOperation *readOperation,
rcti *output);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.h b/source/blender/compositor/operations/COM_KeyingDespillOperation.h
index eb43a478e50..32df7939c43 100644
--- a/source/blender/compositor/operations/COM_KeyingDespillOperation.h
+++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_KEYINGDESPILLOPERATION_H__
-#define __COM_KEYINGDESPILLOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -48,5 +47,3 @@ class KeyingDespillOperation : public NodeOperation {
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h
index 81d23e76b2a..946d7bdc1f7 100644
--- a/source/blender/compositor/operations/COM_KeyingOperation.h
+++ b/source/blender/compositor/operations/COM_KeyingOperation.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_KEYINGOPERATION_H__
-#define __COM_KEYINGOPERATION_H__
+#pragma once
#include <string.h>
@@ -48,5 +47,3 @@ class KeyingOperation : public NodeOperation {
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h
index 593e902117b..595301bb951 100644
--- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h
+++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_KEYINGSCREENOPERATION_H__
-#define __COM_KEYINGSCREENOPERATION_H__
+#pragma once
#include <string.h>
@@ -83,5 +82,3 @@ class KeyingScreenOperation : public NodeOperation {
void executePixel(float output[4], int x, int y, void *data);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h
index 2df7847f7ff..2b77b3cde85 100644
--- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h
+++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_LUMINANCEMATTEOPERATION_H__
-#define __COM_LUMINANCEMATTEOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -48,4 +48,3 @@ class LuminanceMatteOperation : public NodeOperation {
this->m_settings = nodeChroma;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.h b/source/blender/compositor/operations/COM_MapRangeOperation.h
index 55b5cc7453c..8656b5539a0 100644
--- a/source/blender/compositor/operations/COM_MapRangeOperation.h
+++ b/source/blender/compositor/operations/COM_MapRangeOperation.h
@@ -16,8 +16,8 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_MAPRANGEOPERATION_H__
-#define __COM_MAPRANGEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_texture_types.h"
@@ -67,4 +67,3 @@ class MapRangeOperation : public NodeOperation {
this->m_useClamp = value;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_MapUVOperation.h b/source/blender/compositor/operations/COM_MapUVOperation.h
index 64e17b180b4..639b61847c4 100644
--- a/source/blender/compositor/operations/COM_MapUVOperation.h
+++ b/source/blender/compositor/operations/COM_MapUVOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MAPUVOPERATION_H__
-#define __COM_MAPUVOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class MapUVOperation : public NodeOperation {
@@ -65,5 +65,3 @@ class MapUVOperation : public NodeOperation {
private:
bool read_uv(float x, float y, float &r_u, float &r_v, float &r_alpha);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_MapValueOperation.h b/source/blender/compositor/operations/COM_MapValueOperation.h
index 81071d78cd7..cdbc98bd2a5 100644
--- a/source/blender/compositor/operations/COM_MapValueOperation.h
+++ b/source/blender/compositor/operations/COM_MapValueOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MAPVALUEOPERATION_H__
-#define __COM_MAPVALUEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_texture_types.h"
@@ -62,4 +62,3 @@ class MapValueOperation : public NodeOperation {
this->m_settings = settings;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h
index 45363ea5220..eba14d10373 100644
--- a/source/blender/compositor/operations/COM_MaskOperation.h
+++ b/source/blender/compositor/operations/COM_MaskOperation.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_MASKOPERATION_H__
-#define __COM_MASKOPERATION_H__
+#pragma once
#include "BLI_listbase.h"
#include "COM_NodeOperation.h"
@@ -94,5 +93,3 @@ class MaskOperation : public NodeOperation {
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h
index 199b59d8649..f844f668f08 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.h
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MATHBASEOPERATION_H__
-#define __COM_MATHBASEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -372,4 +372,3 @@ class MathSmoothMaxOperation : public MathBaseOperation {
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_MixOperation.h b/source/blender/compositor/operations/COM_MixOperation.h
index cea0e59b541..e597e8af63a 100644
--- a/source/blender/compositor/operations/COM_MixOperation.h
+++ b/source/blender/compositor/operations/COM_MixOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MIXOPERATION_H__
-#define __COM_MIXOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -193,5 +193,3 @@ class MixValueOperation : public MixBaseOperation {
MixValueOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h
index 8a95293b470..449e5d01a37 100644
--- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h
+++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MOVIECLIPATTRIBUTEOPERATION_H__
-#define __COM_MOVIECLIPATTRIBUTEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_movieclip_types.h"
@@ -70,4 +70,3 @@ class MovieClipAttributeOperation : public NodeOperation {
this->m_invert = invert;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h
index 7ae85eac25e..8897f85f77c 100644
--- a/source/blender/compositor/operations/COM_MovieClipOperation.h
+++ b/source/blender/compositor/operations/COM_MovieClipOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MOVIECLIPOPERATION_H__
-#define __COM_MOVIECLIPOPERATION_H__
+#pragma once
#include "BLI_listbase.h"
#include "COM_NodeOperation.h"
@@ -77,5 +76,3 @@ class MovieClipAlphaOperation : public MovieClipBaseOperation {
MovieClipAlphaOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h
index 799c6385a10..f11ce485f97 100644
--- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h
+++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MOVIEDISTORTIONOPERATION_H__
-#define __COM_MOVIEDISTORTIONOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
#include "DNA_movieclip_types.h"
@@ -58,5 +57,3 @@ class MovieDistortionOperation : public NodeOperation {
ReadBufferOperation *readOperation,
rcti *output);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.h b/source/blender/compositor/operations/COM_MultilayerImageOperation.h
index 10c475ced4d..adfcc975ade 100644
--- a/source/blender/compositor/operations/COM_MultilayerImageOperation.h
+++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_MULTILAYERIMAGEOPERATION_H__
-#define __COM_MULTILAYERIMAGEOPERATION_H__
+#pragma once
#include "COM_ImageOperation.h"
@@ -67,5 +66,3 @@ class MultilayerVectorOperation : public MultilayerBaseOperation {
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp
index f7e689fa008..55faa480b83 100644
--- a/source/blender/compositor/operations/COM_NormalizeOperation.cpp
+++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp
@@ -53,9 +53,7 @@ void NormalizeOperation::executePixel(float output[4], int x, int y, void *data)
void NormalizeOperation::deinitExecution()
{
this->m_imageReader = NULL;
- if (this->m_cachedInstance) {
- delete this->m_cachedInstance;
- }
+ delete this->m_cachedInstance;
NodeOperation::deinitMutex();
}
diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.h b/source/blender/compositor/operations/COM_NormalizeOperation.h
index a38e79bb0ab..58c03e633e2 100644
--- a/source/blender/compositor/operations/COM_NormalizeOperation.h
+++ b/source/blender/compositor/operations/COM_NormalizeOperation.h
@@ -16,8 +16,8 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_NORMALIZEOPERATION_H__
-#define __COM_NORMALIZEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -63,5 +63,3 @@ class NormalizeOperation : public NodeOperation {
ReadBufferOperation *readOperation,
rcti *output);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
index 609448c0bcb..1deaf121173 100644
--- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
@@ -16,8 +16,8 @@
* Copyright 2015, Blender Foundation.
*/
-#ifndef __COM_OUTPUTFILEMULTIVIEWOPERATION_H__
-#define __COM_OUTPUTFILEMULTIVIEWOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "COM_OutputFileOperation.h"
@@ -77,5 +77,3 @@ class OutputStereoOperation : public OutputSingleLayerOperation {
void *get_handle(const char *filename);
void deinitExecution();
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h
index d00d1d0dc0d..b2454e17e3f 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.h
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_OUTPUTFILEOPERATION_H__
-#define __COM_OUTPUTFILEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "BLI_path_util.h"
@@ -140,5 +140,3 @@ void free_exr_channels(void *exrhandle,
const char *layerName,
const DataType datatype);
int get_datatype_size(DataType datatype);
-
-#endif
diff --git a/source/blender/compositor/operations/COM_PixelateOperation.h b/source/blender/compositor/operations/COM_PixelateOperation.h
index 86aab26ee00..c7595756d39 100644
--- a/source/blender/compositor/operations/COM_PixelateOperation.h
+++ b/source/blender/compositor/operations/COM_PixelateOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_PIXELATEOPERATION_H__
-#define __COM_PIXELATEOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -61,5 +60,3 @@ class PixelateOperation : public NodeOperation {
*/
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h
index 444616e13f2..1e892465db8 100644
--- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h
@@ -15,8 +15,7 @@
* Copyright 2014, Blender Foundation.
*/
-#ifndef __COM_PLANECORNERPINOPERATION_H__
-#define __COM_PLANECORNERPINOPERATION_H__
+#pragma once
#include <string.h>
@@ -59,5 +58,3 @@ class PlaneCornerPinWarpImageOperation : public PlaneDistortWarpImageOperation {
ReadBufferOperation *readOperation,
rcti *output);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
index 35e7745cb5d..6cc9456c13f 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
@@ -16,8 +16,7 @@
* Copyright 2013, Blender Foundation.
*/
-#ifndef __COM_PLANEDISTORTCOMMONOPERATION_H__
-#define __COM_PLANEDISTORTCOMMONOPERATION_H__
+#pragma once
#include <string.h>
@@ -97,5 +96,3 @@ class PlaneDistortMaskOperation : public NodeOperation {
this->m_motion_blur_shutter = shutter;
}
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
index 875c8ce8fa0..fc0a0873d5f 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
@@ -16,8 +16,7 @@
* Copyright 2013, Blender Foundation.
*/
-#ifndef __COM_PLANETRACKOPERATION_H__
-#define __COM_PLANETRACKOPERATION_H__
+#pragma once
#include <string.h>
@@ -96,5 +95,3 @@ class PlaneTrackWarpImageOperation : public PlaneDistortWarpImageOperation,
NodeOperation::determineResolution(temp, resolution);
}
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp
index 30fe2ca824d..43d20271141 100644
--- a/source/blender/compositor/operations/COM_PreviewOperation.cpp
+++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp
@@ -126,14 +126,27 @@ void PreviewOperation::determineResolution(unsigned int resolution[2],
unsigned int preferredResolution[2])
{
NodeOperation::determineResolution(resolution, preferredResolution);
- int width = resolution[0];
- int height = resolution[1];
+
+ /* If resolution is 0 there are two possible scenarios:
+ * - Either node is not connected at all
+ * - It is connected to input which doesn't have own resolution (i.e. color input).
+ *
+ * In the former case we rely on the execution system to not evaluate this node.
+ *
+ * For the latter case we use 1 pixel preview, so that it's possible to see preview color in the
+ * preview. This is how final F12 render will behave (flood-fill final frame with the color).
+ *
+ * Having things consistent in terms that node preview is scaled down F12 render is a very
+ * natural thing to do. */
+ int width = max_ii(1, resolution[0]);
+ int height = max_ii(1, resolution[1]);
+
this->m_divider = 0.0f;
if (width > height) {
- this->m_divider = COM_PREVIEW_SIZE / (width - 1);
+ this->m_divider = (float)COM_PREVIEW_SIZE / (width);
}
else {
- this->m_divider = COM_PREVIEW_SIZE / (height - 1);
+ this->m_divider = (float)COM_PREVIEW_SIZE / (height);
}
width = width * this->m_divider;
height = height * this->m_divider;
diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h
index f31bd533971..eca50c5cda4 100644
--- a/source/blender/compositor/operations/COM_PreviewOperation.h
+++ b/source/blender/compositor/operations/COM_PreviewOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_PREVIEWOPERATION_H__
-#define __COM_PREVIEWOPERATION_H__
+#pragma once
+
#include "BKE_global.h"
#include "BLI_rect.h"
#include "COM_NodeOperation.h"
@@ -61,4 +61,3 @@ class PreviewOperation : public NodeOperation {
return true;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
index 3574f40e3bb..b9290fa1548 100644
--- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
+++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_PROJECTORLENSDISTORTIONOPERATION_H__
-#define __COM_PROJECTORLENSDISTORTIONOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -58,4 +58,3 @@ class ProjectorLensDistortionOperation : public NodeOperation {
void updateDispersion();
};
-#endif
diff --git a/source/blender/compositor/operations/COM_QualityStepHelper.h b/source/blender/compositor/operations/COM_QualityStepHelper.h
index 0814f5cdb4c..e437613fb29 100644
--- a/source/blender/compositor/operations/COM_QualityStepHelper.h
+++ b/source/blender/compositor/operations/COM_QualityStepHelper.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_QUALITYSTEPHELPER_H__
-#define __COM_QUALITYSTEPHELPER_H__
+#pragma once
+
#include "COM_defines.h"
typedef enum QualityHelper {
@@ -54,4 +54,3 @@ class QualityStepHelper {
this->m_quality = quality;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h
index 60d064a5582..e59cb5449d6 100644
--- a/source/blender/compositor/operations/COM_ReadBufferOperation.h
+++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_READBUFFEROPERATION_H__
-#define __COM_READBUFFEROPERATION_H__
+#pragma once
#include "COM_MemoryBuffer.h"
#include "COM_MemoryProxy.h"
@@ -73,5 +72,3 @@ class ReadBufferOperation : public NodeOperation {
void readResolutionFromWriteBuffer();
void updateMemoryBuffer();
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h
index 6f84eae3252..74664c128c0 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.h
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_RENDERLAYERSPROG_H__
-#define __COM_RENDERLAYERSPROG_H__
+#pragma once
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
@@ -150,5 +149,3 @@ class RenderLayersDepthProg : public RenderLayersProg {
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h
index 46bdc68161e..0ef4466671a 100644
--- a/source/blender/compositor/operations/COM_RotateOperation.h
+++ b/source/blender/compositor/operations/COM_RotateOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ROTATEOPERATION_H__
-#define __COM_ROTATEOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -47,5 +46,3 @@ class RotateOperation : public NodeOperation {
void ensureDegree();
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h
index 28e32ff8606..f28b8237485 100644
--- a/source/blender/compositor/operations/COM_ScaleOperation.h
+++ b/source/blender/compositor/operations/COM_ScaleOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SCALEOPERATION_H__
-#define __COM_SCALEOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -129,5 +128,3 @@ class ScaleFixedSizeOperation : public BaseScaleOperation {
this->m_offsetY = y;
}
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h
index c9db5bc88b8..f9982d94f60 100644
--- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h
+++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SCREENLENSDISTORTIONOPERATION_H__
-#define __COM_SCREENLENSDISTORTIONOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -96,4 +96,3 @@ class ScreenLensDistortionOperation : public NodeOperation {
float sum[4],
int count[3]) const;
};
-#endif
diff --git a/source/blender/compositor/operations/COM_SetAlphaOperation.h b/source/blender/compositor/operations/COM_SetAlphaOperation.h
index 24f80b71eae..a84fb0f2228 100644
--- a/source/blender/compositor/operations/COM_SetAlphaOperation.h
+++ b/source/blender/compositor/operations/COM_SetAlphaOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SETALPHAOPERATION_H__
-#define __COM_SETALPHAOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -43,4 +43,3 @@ class SetAlphaOperation : public NodeOperation {
void initExecution();
void deinitExecution();
};
-#endif
diff --git a/source/blender/compositor/operations/COM_SetColorOperation.h b/source/blender/compositor/operations/COM_SetColorOperation.h
index d16d3806864..0723ac8a8e4 100644
--- a/source/blender/compositor/operations/COM_SetColorOperation.h
+++ b/source/blender/compositor/operations/COM_SetColorOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SETCOLOROPERATION_H__
-#define __COM_SETCOLOROPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -82,4 +82,3 @@ class SetColorOperation : public NodeOperation {
return true;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.h b/source/blender/compositor/operations/COM_SetSamplerOperation.h
index 62f01129ff7..c0b5d5a37be 100644
--- a/source/blender/compositor/operations/COM_SetSamplerOperation.h
+++ b/source/blender/compositor/operations/COM_SetSamplerOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SETSAMPLEROPERATION_H__
-#define __COM_SETSAMPLEROPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -47,4 +47,3 @@ class SetSamplerOperation : public NodeOperation {
void initExecution();
void deinitExecution();
};
-#endif
diff --git a/source/blender/compositor/operations/COM_SetValueOperation.h b/source/blender/compositor/operations/COM_SetValueOperation.h
index 6fb2832450d..6645cd558b2 100644
--- a/source/blender/compositor/operations/COM_SetValueOperation.h
+++ b/source/blender/compositor/operations/COM_SetValueOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SETVALUEOPERATION_H__
-#define __COM_SETVALUEOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -54,4 +54,3 @@ class SetValueOperation : public NodeOperation {
return true;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h
index a2f9aaa6b3b..05c8e6dc56b 100644
--- a/source/blender/compositor/operations/COM_SetVectorOperation.h
+++ b/source/blender/compositor/operations/COM_SetVectorOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SETVECTOROPERATION_H__
-#define __COM_SETVECTOROPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
/**
@@ -88,4 +88,3 @@ class SetVectorOperation : public NodeOperation {
setZ(vector[2]);
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.h b/source/blender/compositor/operations/COM_SocketProxyOperation.h
index 3855c26088a..22c144598f6 100644
--- a/source/blender/compositor/operations/COM_SocketProxyOperation.h
+++ b/source/blender/compositor/operations/COM_SocketProxyOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SOCKETPROXYOPERATION_H__
-#define __COM_SOCKETPROXYOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -46,5 +45,3 @@ class SocketProxyOperation : public NodeOperation {
private:
bool m_use_conversion;
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_SplitOperation.h b/source/blender/compositor/operations/COM_SplitOperation.h
index ea923123290..62d41a615ff 100644
--- a/source/blender/compositor/operations/COM_SplitOperation.h
+++ b/source/blender/compositor/operations/COM_SplitOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_SPLITOPERATION_H__
-#define __COM_SPLITOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
class SplitOperation : public NodeOperation {
@@ -43,4 +43,3 @@ class SplitOperation : public NodeOperation {
this->m_xSplit = xsplit;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
index 6f47e0e190b..4a7139537c1 100644
--- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
+++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
@@ -172,7 +172,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
return;
}
- /* initialise the iteration variables */
+ /* Initialize the iteration variables. */
float *buffer = init_buffer_iterator(
input, source, co, dist_min, dist_max, x, y, num, v, dv, falloff_factor);
zero_v3(border);
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.h b/source/blender/compositor/operations/COM_SunBeamsOperation.h
index d8153264d98..09bdb018cc3 100644
--- a/source/blender/compositor/operations/COM_SunBeamsOperation.h
+++ b/source/blender/compositor/operations/COM_SunBeamsOperation.h
@@ -15,8 +15,7 @@
* Copyright 2014, Blender Foundation.
*/
-#ifndef __COM_SUNBEAMSOPERATION_H__
-#define __COM_SUNBEAMSOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -45,5 +44,3 @@ class SunBeamsOperation : public NodeOperation {
float m_source_px[2];
float m_ray_length_px;
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h
index ebfdbb6513a..7fa85922b0b 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.h
+++ b/source/blender/compositor/operations/COM_TextureOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_TEXTUREOPERATION_H__
-#define __COM_TEXTUREOPERATION_H__
+#pragma once
#include "BLI_listbase.h"
#include "COM_NodeOperation.h"
@@ -81,5 +80,3 @@ class TextureAlphaOperation : public TextureBaseOperation {
TextureAlphaOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp
index 417fe8713ed..59354ff7581 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.cpp
+++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp
@@ -85,9 +85,7 @@ void PhotoreceptorTonemapOperation::executePixel(float output[4], int x, int y,
void TonemapOperation::deinitExecution()
{
this->m_imageReader = NULL;
- if (this->m_cachedInstance) {
- delete this->m_cachedInstance;
- }
+ delete this->m_cachedInstance;
NodeOperation::deinitMutex();
}
diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h
index 11e82c1fc9c..066332fb7e4 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.h
+++ b/source/blender/compositor/operations/COM_TonemapOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_TONEMAPOPERATION_H__
-#define __COM_TONEMAPOPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
@@ -98,5 +98,3 @@ class PhotoreceptorTonemapOperation : public TonemapOperation {
*/
void executePixel(float output[4], int x, int y, void *data);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h
index 695e85f4fa3..7d831ec5d8d 100644
--- a/source/blender/compositor/operations/COM_TrackPositionOperation.h
+++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h
@@ -16,8 +16,7 @@
* Copyright 2012, Blender Foundation.
*/
-#ifndef __COM_TRACKPOSITIONOPERATION_H__
-#define __COM_TRACKPOSITIONOPERATION_H__
+#pragma once
#include <string.h>
@@ -97,5 +96,3 @@ class TrackPositionOperation : public NodeOperation {
return true;
}
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h
index 2d13813a86a..99cfb528858 100644
--- a/source/blender/compositor/operations/COM_TranslateOperation.h
+++ b/source/blender/compositor/operations/COM_TranslateOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_TRANSLATEOPERATION_H__
-#define __COM_TRANSLATEOPERATION_H__
+#pragma once
#include "COM_NodeOperation.h"
@@ -65,5 +64,3 @@ class TranslateOperation : public NodeOperation {
void setFactorXY(float factorX, float factorY);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h
index 930bfd77943..82f41ad68e3 100644
--- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h
+++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_VARIABLESIZEBOKEHBLUROPERATION_H__
-#define __COM_VARIABLESIZEBOKEHBLUROPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "COM_QualityStepHelper.h"
@@ -123,4 +123,3 @@ class InverseSearchRadiusOperation : public NodeOperation {
}
};
#endif
-#endif
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
index ee1bb0739b9..56e0ab9b93f 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
@@ -138,7 +138,6 @@ void VectorBlurOperation::generateVectorBlur(float *data,
inputImage->getBuffer(),
inputSpeed->getBuffer(),
inputZ->getBuffer());
- return;
}
/* ****************** Spans ******************************* */
@@ -515,7 +514,7 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove)
/* we make this into 3 points, center point is (0, 0) */
/* and offset the center point just enough to make curve go through midpoint */
-static void quad_bezier_2d(float *result, float *v1, float *v2, float *ipodata)
+static void quad_bezier_2d(float *result, const float *v1, const float *v2, const float *ipodata)
{
float p1[2], p2[2], p3[2];
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.h b/source/blender/compositor/operations/COM_VectorBlurOperation.h
index 3caf5c5c8e4..846b69310bf 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.h
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_VECTORBLUROPERATION_H__
-#define __COM_VECTORBLUROPERATION_H__
+#pragma once
+
#include "COM_NodeOperation.h"
#include "COM_QualityStepHelper.h"
#include "DNA_node_types.h"
@@ -72,4 +72,3 @@ class VectorBlurOperation : public NodeOperation, public QualityStepHelper {
MemoryBuffer *inputSpeed,
MemoryBuffer *inputZ);
};
-#endif
diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.h b/source/blender/compositor/operations/COM_VectorCurveOperation.h
index 65441dbdfb7..9fa5fe78a4b 100644
--- a/source/blender/compositor/operations/COM_VectorCurveOperation.h
+++ b/source/blender/compositor/operations/COM_VectorCurveOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_VECTORCURVEOPERATION_H__
-#define __COM_VECTORCURVEOPERATION_H__
+#pragma once
+
#include "COM_CurveBaseOperation.h"
#include "COM_NodeOperation.h"
@@ -46,4 +46,3 @@ class VectorCurveOperation : public CurveBaseOperation {
*/
void deinitExecution();
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h
index aae2e912804..680744c70d9 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.h
+++ b/source/blender/compositor/operations/COM_ViewerOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_VIEWEROPERATION_H__
-#define __COM_VIEWEROPERATION_H__
+#pragma once
+
#include "BKE_global.h"
#include "BLI_rect.h"
#include "COM_NodeOperation.h"
@@ -129,4 +129,3 @@ class ViewerOperation : public NodeOperation {
void updateImage(rcti *rect);
void initImage();
};
-#endif
diff --git a/source/blender/compositor/operations/COM_WrapOperation.h b/source/blender/compositor/operations/COM_WrapOperation.h
index 6360fa0c246..d1acfb10f25 100644
--- a/source/blender/compositor/operations/COM_WrapOperation.h
+++ b/source/blender/compositor/operations/COM_WrapOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_WRAPOPERATION_H__
-#define __COM_WRAPOPERATION_H__
+#pragma once
#include "COM_ReadBufferOperation.h"
@@ -38,5 +37,3 @@ class WrapOperation : public ReadBufferOperation {
void setFactorXY(float factorX, float factorY);
};
-
-#endif
diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h
index be525db4420..a9f90830a92 100644
--- a/source/blender/compositor/operations/COM_WriteBufferOperation.h
+++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h
@@ -16,8 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_WRITEBUFFEROPERATION_H__
-#define __COM_WRITEBUFFEROPERATION_H__
+#pragma once
#include "COM_MemoryProxy.h"
#include "COM_NodeOperation.h"
@@ -63,4 +62,3 @@ class WriteBufferOperation : public NodeOperation {
return m_input;
}
};
-#endif
diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.h b/source/blender/compositor/operations/COM_ZCombineOperation.h
index 9a93d080a2f..8c6e73f8c55 100644
--- a/source/blender/compositor/operations/COM_ZCombineOperation.h
+++ b/source/blender/compositor/operations/COM_ZCombineOperation.h
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
-#ifndef __COM_ZCOMBINEOPERATION_H__
-#define __COM_ZCOMBINEOPERATION_H__
+#pragma once
+
#include "COM_MixOperation.h"
/**
@@ -66,5 +66,3 @@ class ZCombineMaskOperation : public NodeOperation {
class ZCombineMaskAlphaOperation : public ZCombineMaskOperation {
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-
-#endif
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index 355d2536e1a..417aaa2c4c0 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -46,6 +46,7 @@ set(SRC
intern/builder/deg_builder_nodes_view_layer.cc
intern/builder/deg_builder_pchanmap.cc
intern/builder/deg_builder_relations.cc
+ intern/builder/deg_builder_relations_drivers.cc
intern/builder/deg_builder_relations_keys.cc
intern/builder/deg_builder_relations_rig.cc
intern/builder/deg_builder_relations_scene.cc
@@ -53,6 +54,11 @@ set(SRC
intern/builder/deg_builder_remove_noop.cc
intern/builder/deg_builder_rna.cc
intern/builder/deg_builder_transitive.cc
+ intern/builder/pipeline.cc
+ intern/builder/pipeline_compositor.cc
+ intern/builder/pipeline_from_ids.cc
+ intern/builder/pipeline_render.cc
+ intern/builder/pipeline_view_layer.cc
intern/debug/deg_debug.cc
intern/debug/deg_debug_relations_graphviz.cc
intern/debug/deg_debug_stats_gnuplot.cc
@@ -100,6 +106,7 @@ set(SRC
intern/builder/deg_builder.h
intern/builder/deg_builder_cache.h
intern/builder/deg_builder_cycle.h
+ intern/builder/deg_builder_relations_drivers.h
intern/builder/deg_builder_map.h
intern/builder/deg_builder_nodes.h
intern/builder/deg_builder_pchanmap.h
@@ -108,6 +115,11 @@ set(SRC
intern/builder/deg_builder_remove_noop.h
intern/builder/deg_builder_rna.h
intern/builder/deg_builder_transitive.h
+ intern/builder/pipeline.h
+ intern/builder/pipeline_compositor.h
+ intern/builder/pipeline_from_ids.h
+ intern/builder/pipeline_render.h
+ intern/builder/pipeline_view_layer.h
intern/debug/deg_debug.h
intern/debug/deg_time_average.h
intern/eval/deg_eval.h
@@ -145,3 +157,14 @@ set(LIB
)
blender_add_lib(bf_depsgraph "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+if(WITH_GTESTS)
+ set(TEST_SRC
+ intern/builder/deg_builder_rna_test.cc
+ )
+ set(TEST_LIB
+ bf_depsgraph
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_depsgraph_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB}")
+endif()
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index d735d3b89bc..b3636743101 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -43,8 +43,7 @@
* - These are used in all depsgraph code and by all callers of Depsgraph API...
*/
-#ifndef __DEG_DEPSGRAPH_H__
-#define __DEG_DEPSGRAPH_H__
+#pragma once
#include "DNA_ID.h"
@@ -233,5 +232,3 @@ void DEG_debug_print_eval_time(struct Depsgraph *depsgraph,
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-#endif /* __DEG_DEPSGRAPH_H__ */
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h
index 81157102bb1..50f22b00028 100644
--- a/source/blender/depsgraph/DEG_depsgraph_build.h
+++ b/source/blender/depsgraph/DEG_depsgraph_build.h
@@ -23,8 +23,7 @@
* Public API for Depsgraph
*/
-#ifndef __DEG_DEPSGRAPH_BUILD_H__
-#define __DEG_DEPSGRAPH_BUILD_H__
+#pragma once
/* ************************************************* */
@@ -201,5 +200,3 @@ struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle);
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-#endif /* __DEG_DEPSGRAPH_BUILD_H__ */
diff --git a/source/blender/depsgraph/DEG_depsgraph_debug.h b/source/blender/depsgraph/DEG_depsgraph_debug.h
index 73e03523003..e261ff67a20 100644
--- a/source/blender/depsgraph/DEG_depsgraph_debug.h
+++ b/source/blender/depsgraph/DEG_depsgraph_debug.h
@@ -23,8 +23,7 @@
* Public API for Querying and Filtering Depsgraph
*/
-#ifndef __DEG_DEPSGRAPH_DEBUG_H__
-#define __DEG_DEPSGRAPH_DEBUG_H__
+#pragma once
#include <stdio.h>
@@ -80,5 +79,3 @@ bool DEG_debug_consistency_check(struct Depsgraph *graph);
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-#endif /* __DEG_DEPSGRAPH_DEBUG_H__ */
diff --git a/source/blender/depsgraph/DEG_depsgraph_physics.h b/source/blender/depsgraph/DEG_depsgraph_physics.h
index 7eae6b4eec4..7bd2994b426 100644
--- a/source/blender/depsgraph/DEG_depsgraph_physics.h
+++ b/source/blender/depsgraph/DEG_depsgraph_physics.h
@@ -23,8 +23,7 @@
* Physics utilities for effectors and collision.
*/
-#ifndef __DEG_DEPSGRAPH_PHYSICS_H__
-#define __DEG_DEPSGRAPH_PHYSICS_H__
+#pragma once
#include "DEG_depsgraph.h"
@@ -74,5 +73,3 @@ void DEG_add_forcefield_relations(struct DepsNodeHandle *handle,
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-#endif /* __DEG_DEPSGRAPH_PHYSICS_H__ */
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 3d570536223..e0166a13d69 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -23,8 +23,7 @@
* Public API for Querying Depsgraph.
*/
-#ifndef __DEG_DEPSGRAPH_QUERY_H__
-#define __DEG_DEPSGRAPH_QUERY_H__
+#pragma once
#include "BLI_iterator.h"
@@ -261,5 +260,3 @@ void DEG_foreach_ID(const Depsgraph *depsgraph, DEGForeachIDCallback callback, v
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-#endif /* __DEG_DEPSGRAPH_QUERY_H__ */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
index 1095905c570..750bccf0e52 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
@@ -72,11 +72,11 @@ bool operator==(const AnimatedPropertyID &a, const AnimatedPropertyID &b)
return a.data == b.data && a.property_rna == b.property_rna;
}
-uint32_t AnimatedPropertyID::hash() const
+uint64_t AnimatedPropertyID::hash() const
{
uintptr_t ptr1 = (uintptr_t)data;
uintptr_t ptr2 = (uintptr_t)property_rna;
- return (uint32_t)(((ptr1 >> 4) * 33) ^ (ptr2 >> 4));
+ return (uint64_t)(((ptr1 >> 4) * 33) ^ (ptr2 >> 4));
}
namespace {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.h b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
index 43348e3bf23..e04ae3a3727 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
@@ -47,7 +47,7 @@ class AnimatedPropertyID {
AnimatedPropertyID(ID *id, StructRNA *type, const char *property_name);
AnimatedPropertyID(ID *id, StructRNA *type, void *data, const char *property_name);
- uint32_t hash() const;
+ uint64_t hash() const;
friend bool operator==(const AnimatedPropertyID &a, const AnimatedPropertyID &b);
/* Corresponds to PointerRNA.data. */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_map.h b/source/blender/depsgraph/intern/builder/deg_builder_map.h
index 5dfc3297b3e..8b23d3d0d3b 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_map.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_map.h
@@ -40,7 +40,7 @@ class BuilderMap {
TAG_SCENE_COMPOSITOR = (1 << 4),
TAG_SCENE_SEQUENCER = (1 << 5),
- TAG_SCENE_AUDIO = (1 << 5),
+ TAG_SCENE_AUDIO = (1 << 6),
/* All ID components has been built. */
TAG_COMPLETE = (TAG_ANIMATION | TAG_PARAMETERS | TAG_TRANSFORM | TAG_GEOMETRY |
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index f5cc5963253..e262c880421 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1126,6 +1126,12 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
if (object->type != OB_MESH) {
continue;
}
+ if (object->rigidbody_object == nullptr) {
+ continue;
+ }
+ if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
+ continue;
+ }
/* Create operation for flushing results. */
/* Object's transform component - where the rigidbody operation
* lives. */
@@ -1466,6 +1472,18 @@ void DepsgraphNodeBuilder::build_light(Light *lamp)
function_bind(BKE_light_eval, _1, lamp_cow));
}
+void DepsgraphNodeBuilder::build_nodetree_socket(bNodeSocket *socket)
+{
+ build_idproperties(socket->prop);
+
+ if (socket->type == SOCK_OBJECT) {
+ build_id((ID *)((bNodeSocketValueObject *)socket->default_value)->value);
+ }
+ else if (socket->type == SOCK_IMAGE) {
+ build_id((ID *)((bNodeSocketValueImage *)socket->default_value)->value);
+ }
+}
+
void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
{
if (ntree == nullptr) {
@@ -1494,10 +1512,10 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
build_idproperties(bnode->prop);
LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) {
- build_idproperties(socket->prop);
+ build_nodetree_socket(socket);
}
LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) {
- build_idproperties(socket->prop);
+ build_nodetree_socket(socket);
}
ID *id = bnode->id;
@@ -1780,8 +1798,10 @@ void DepsgraphNodeBuilder::build_simulation(Simulation *simulation)
return;
}
add_id_node(&simulation->id);
+ build_idproperties(simulation->id.properties);
build_animdata(&simulation->id);
build_parameters(&simulation->id);
+ build_nodetree(simulation->nodetree);
Simulation *simulation_cow = get_cow_datablock(simulation);
Scene *scene_cow = get_cow_datablock(scene_);
@@ -1797,6 +1817,9 @@ void DepsgraphNodeBuilder::build_scene_sequencer(Scene *scene)
if (scene->ed == nullptr) {
return;
}
+ if (built_map_.checkIsBuiltAndTag(scene, BuilderMap::TAG_SCENE_SEQUENCER)) {
+ return;
+ }
build_scene_audio(scene);
Scene *scene_cow = get_cow_datablock(scene);
add_operation_node(&scene->id,
@@ -1831,6 +1854,10 @@ void DepsgraphNodeBuilder::build_scene_audio(Scene *scene)
return;
}
+ OperationNode *audio_entry_node = add_operation_node(
+ &scene->id, NodeType::AUDIO, OperationCode::AUDIO_ENTRY);
+ audio_entry_node->set_as_entry();
+
add_operation_node(&scene->id, NodeType::AUDIO, OperationCode::SOUND_EVAL);
Scene *scene_cow = get_cow_datablock(scene);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 256fa3450a6..40f42705a52 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -31,6 +31,7 @@
#include "DEG_depsgraph.h"
+struct bNodeSocket;
struct CacheFile;
struct Camera;
struct Collection;
@@ -211,6 +212,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
virtual void build_camera(Camera *camera);
virtual void build_light(Light *lamp);
virtual void build_nodetree(bNodeTree *ntree);
+ virtual void build_nodetree_socket(bNodeSocket *socket);
virtual void build_material(Material *ma);
virtual void build_materials(Material **materials, int num_materials);
virtual void build_freestyle_lineset(FreestyleLineSet *fls);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 50c52a519b4..5ae71dd1792 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -104,6 +104,7 @@
#include "intern/builder/deg_builder.h"
#include "intern/builder/deg_builder_pchanmap.h"
+#include "intern/builder/deg_builder_relations_drivers.h"
#include "intern/debug/deg_debug.h"
#include "intern/depsgraph_physics.h"
#include "intern/depsgraph_tag.h"
@@ -1697,6 +1698,22 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
if (object->type != OB_MESH) {
continue;
}
+ if (object->rigidbody_object == nullptr) {
+ continue;
+ }
+ if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
+ continue;
+ }
+
+ if (object->parent != nullptr && object->parent->rigidbody_object != nullptr &&
+ object->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) {
+ /* If we are a child of a compound shape object, the transforms and sim evaluation will be
+ * handled by the parent compound shape object. Do not add any evaluation triggers
+ * for the child objects.
+ */
+ continue;
+ }
+
OperationKey rb_transform_copy_key(
&object->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
/* Rigid body synchronization depends on the actual simulation. */
@@ -1746,13 +1763,18 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* final result of the constraint object's transform controls how
* the constraint affects the physics sim for these objects. */
ComponentKey trans_key(&object->id, NodeType::TRANSFORM);
- OperationKey ob1_key(
- &rbc->ob1->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
- OperationKey ob2_key(
- &rbc->ob2->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
- /* Constrained-objects sync depends on the constraint-holder. */
- add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1");
- add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2");
+ if (rbc->ob1->rigidbody_object->type == RBO_TYPE_ACTIVE) {
+ OperationKey ob1_key(
+ &rbc->ob1->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
+ /* Constrained-objects sync depends on the constraint-holder. */
+ add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1");
+ }
+ if (rbc->ob2->rigidbody_object->type == RBO_TYPE_ACTIVE) {
+ OperationKey ob2_key(
+ &rbc->ob2->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
+ /* Constrained-objects sync depends on the constraint-holder. */
+ add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2");
+ }
/* Ensure that sim depends on this constraint's transform. */
add_relation(trans_key, rb_simulate_key, "RigidBodyConstraint Transform -> RB Simulation");
}
@@ -2275,6 +2297,24 @@ void DepsgraphRelationBuilder::build_light(Light *lamp)
add_relation(lamp_parameters_key, shading_key, "Light Shading Parameters");
}
+void DepsgraphRelationBuilder::build_nodetree_socket(bNodeSocket *socket)
+{
+ build_idproperties(socket->prop);
+
+ if (socket->type == SOCK_OBJECT) {
+ Object *object = ((bNodeSocketValueObject *)socket->default_value)->value;
+ if (object != nullptr) {
+ build_object(object);
+ }
+ }
+ else if (socket->type == SOCK_IMAGE) {
+ Image *image = ((bNodeSocketValueImage *)socket->default_value)->value;
+ if (image != nullptr) {
+ build_image(image);
+ }
+ }
+}
+
void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
{
if (ntree == nullptr) {
@@ -2291,10 +2331,10 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
build_idproperties(bnode->prop);
LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) {
- build_idproperties(socket->prop);
+ build_nodetree_socket(socket);
}
LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) {
- build_idproperties(socket->prop);
+ build_nodetree_socket(socket);
}
ID *id = bnode->id;
@@ -2601,13 +2641,39 @@ void DepsgraphRelationBuilder::build_simulation(Simulation *simulation)
if (built_map_.checkIsBuiltAndTag(simulation)) {
return;
}
+ build_idproperties(simulation->id.properties);
build_animdata(&simulation->id);
build_parameters(&simulation->id);
- OperationKey simulation_update_key(
+ build_nodetree(simulation->nodetree);
+ build_nested_nodetree(&simulation->id, simulation->nodetree);
+
+ OperationKey simulation_eval_key(
&simulation->id, NodeType::SIMULATION, OperationCode::SIMULATION_EVAL);
TimeSourceKey time_src_key;
- add_relation(time_src_key, simulation_update_key, "TimeSrc -> Simulation");
+ add_relation(time_src_key, simulation_eval_key, "TimeSrc -> Simulation");
+
+ OperationKey nodetree_key(
+ &simulation->nodetree->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EXIT);
+ add_relation(nodetree_key, simulation_eval_key, "NodeTree -> Simulation", 0);
+
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ if (dependency->id == nullptr) {
+ continue;
+ }
+ build_id(dependency->id);
+ if (GS(dependency->id->name) == ID_OB) {
+ Object *object = (Object *)dependency->id;
+ if (dependency->flag & SIM_DEPENDS_ON_TRANSFORM) {
+ ComponentKey object_transform_key(&object->id, NodeType::TRANSFORM);
+ add_relation(object_transform_key, simulation_eval_key, "Object Transform -> Simulation");
+ }
+ if (dependency->flag & SIM_DEPENDS_ON_GEOMETRY) {
+ ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY);
+ add_relation(object_geometry_key, simulation_eval_key, "Object Geometry -> Simulation");
+ }
+ }
+ }
}
void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
@@ -2655,8 +2721,10 @@ void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
void DepsgraphRelationBuilder::build_scene_audio(Scene *scene)
{
+ OperationKey scene_audio_entry_key(&scene->id, NodeType::AUDIO, OperationCode::AUDIO_ENTRY);
OperationKey scene_audio_volume_key(&scene->id, NodeType::AUDIO, OperationCode::AUDIO_VOLUME);
OperationKey scene_sound_eval_key(&scene->id, NodeType::AUDIO, OperationCode::SOUND_EVAL);
+ add_relation(scene_audio_entry_key, scene_audio_volume_key, "Audio Entry -> Volume");
add_relation(scene_audio_volume_key, scene_sound_eval_key, "Audio Volume -> Sound");
if (scene->audio.flag & AUDIO_VOLUME_ANIMATED) {
@@ -2841,121 +2909,6 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
#endif
}
-static bool is_reachable(const Node *const from, const Node *const to)
-{
- if (from == to) {
- return true;
- }
-
- // Perform a graph walk from 'to' towards its incoming connections.
- // Walking from 'from' towards its outgoing connections is 10x slower on the Spring rig.
- deque<const Node *> queue;
- Set<const Node *> seen;
- queue.push_back(to);
- while (!queue.empty()) {
- // Visit the next node to inspect.
- const Node *visit = queue.back();
- queue.pop_back();
-
- if (visit == from) {
- return true;
- }
-
- // Queue all incoming relations that we haven't seen before.
- for (Relation *relation : visit->inlinks) {
- const Node *prev_node = relation->from;
- if (seen.add(prev_node)) {
- queue.push_back(prev_node);
- }
- }
- }
- return false;
-}
-
-void DepsgraphRelationBuilder::build_driver_relations()
-{
- for (IDNode *id_node : graph_->id_nodes) {
- build_driver_relations(id_node);
- }
-}
-
-void DepsgraphRelationBuilder::build_driver_relations(IDNode *id_node)
-{
- /* Add relations between drivers that write to the same datablock.
- *
- * This prevents threading issues when two separate RNA properties write to
- * the same memory address. For example:
- * - Drivers on individual array elements, as the animation system will write
- * the whole array back to RNA even when changing individual array value.
- * - Drivers on RNA properties that map to a single bit flag. Changing the RNA
- * value will write the entire int containing the bit, in a non-thread-safe
- * way.
- */
- ID *id_orig = id_node->id_orig;
- AnimData *adt = BKE_animdata_from_id(id_orig);
- if (adt == nullptr) {
- return;
- }
-
- // Mapping from RNA prefix -> set of driver evaluation nodes:
- Map<string, Vector<Node *>> driver_groups;
-
- LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
- if (fcu->rna_path == nullptr) {
- continue;
- }
- // Get the RNA path except the part after the last dot.
- char *last_dot = strrchr(fcu->rna_path, '.');
- StringRef rna_prefix;
- if (last_dot != nullptr) {
- rna_prefix = StringRef(fcu->rna_path, last_dot);
- }
-
- // Insert this driver node into the group belonging to the RNA prefix.
- OperationKey driver_key(
- id_orig, NodeType::PARAMETERS, OperationCode::DRIVER, fcu->rna_path, fcu->array_index);
- Node *node_driver = get_node(driver_key);
- driver_groups.lookup_or_add_default_as(rna_prefix).append(node_driver);
- }
-
- for (Span<Node *> prefix_group : driver_groups.values()) {
- // For each node in the driver group, try to connect it to another node
- // in the same group without creating any cycles.
- int num_drivers = prefix_group.size();
- if (num_drivers < 2) {
- // A relation requires two drivers.
- continue;
- }
- for (int from_index = 0; from_index < num_drivers; ++from_index) {
- Node *op_from = prefix_group[from_index];
-
- // Start by trying the next node in the group.
- for (int to_offset = 1; to_offset < num_drivers; ++to_offset) {
- int to_index = (from_index + to_offset) % num_drivers;
- Node *op_to = prefix_group[to_index];
-
- // Investigate whether this relation would create a dependency cycle.
- // Example graph:
- // A -> B -> C
- // and investigating a potential connection C->A. Because A->C is an
- // existing transitive connection, adding C->A would create a cycle.
- if (is_reachable(op_to, op_from)) {
- continue;
- }
-
- // No need to directly connect this node if there is already a transitive connection.
- if (is_reachable(op_from, op_to)) {
- break;
- }
-
- add_operation_relation(
- op_from->get_exit_operation(), op_to->get_entry_operation(), "Driver Serialisation");
- break;
- }
- }
- }
-} // namespace DEG
-
/* **** ID traversal callbacks functions **** */
void DepsgraphRelationBuilder::modifier_walk(void *user_data,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index b4b0dc71f85..04f2a3f911d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -46,6 +46,7 @@
#include "intern/node/deg_node_operation.h"
struct Base;
+struct bNodeSocket;
struct CacheFile;
struct Camera;
struct Collection;
@@ -275,6 +276,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
virtual void build_camera(Camera *camera);
virtual void build_light(Light *lamp);
virtual void build_nodetree(bNodeTree *ntree);
+ virtual void build_nodetree_socket(bNodeSocket *socket);
virtual void build_material(Material *ma);
virtual void build_materials(Material **materials, int num_materials);
virtual void build_freestyle_lineset(FreestyleLineSet *fls);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc
new file mode 100644
index 00000000000..717c8300f9b
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc
@@ -0,0 +1,258 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ *
+ * Methods for constructing depsgraph relations for drivers.
+ */
+
+#include "intern/builder/deg_builder_relations_drivers.h"
+
+#include <cstring>
+
+#include "DNA_anim_types.h"
+
+#include "BKE_anim_data.h"
+
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph_relation.h"
+#include "intern/node/deg_node.h"
+
+namespace blender {
+namespace deg {
+
+DriverDescriptor::DriverDescriptor(PointerRNA *id_ptr, FCurve *fcu)
+ : rna_prefix(),
+ rna_suffix(),
+ id_ptr_(id_ptr),
+ fcu_(fcu),
+ driver_relations_needed_(false),
+ pointer_rna_(),
+ property_rna_(nullptr),
+ is_array_(false)
+{
+ driver_relations_needed_ = determine_relations_needed();
+ split_rna_path();
+}
+
+bool DriverDescriptor::determine_relations_needed()
+{
+ if (fcu_->array_index > 0) {
+ /* Drivers on array elements always need relations. */
+ is_array_ = true;
+ return true;
+ }
+
+ if (!resolve_rna()) {
+ /* Properties that don't exist can't cause threading issues either. */
+ return false;
+ }
+
+ if (RNA_property_array_check(property_rna_)) {
+ /* Drivers on array elements always need relations. */
+ is_array_ = true;
+ return true;
+ }
+
+ /* Drivers on Booleans and Enums (when used as bitflags) can write to the same memory location,
+ * so they need relations between each other. */
+ return ELEM(RNA_property_type(property_rna_), PROP_BOOLEAN, PROP_ENUM);
+}
+
+bool DriverDescriptor::driver_relations_needed() const
+{
+ return driver_relations_needed_;
+}
+
+bool DriverDescriptor::is_array() const
+{
+ return is_array_;
+}
+
+/* Assumes that 'other' comes from the same RNA group, that is, has the same RNA path prefix. */
+bool DriverDescriptor::is_same_array_as(const DriverDescriptor &other) const
+{
+ if (!is_array_ || !other.is_array_) {
+ return false;
+ }
+ return rna_suffix == other.rna_suffix;
+}
+
+OperationKey DriverDescriptor::depsgraph_key() const
+{
+ return OperationKey(id_ptr_->owner_id,
+ NodeType::PARAMETERS,
+ OperationCode::DRIVER,
+ fcu_->rna_path,
+ fcu_->array_index);
+}
+
+void DriverDescriptor::split_rna_path()
+{
+ const char *last_dot = strrchr(fcu_->rna_path, '.');
+ if (last_dot == nullptr || last_dot[1] == '\0') {
+ rna_prefix = StringRef();
+ rna_suffix = StringRef(fcu_->rna_path);
+ return;
+ }
+
+ rna_prefix = StringRef(fcu_->rna_path, last_dot);
+ rna_suffix = StringRef(last_dot + 1);
+}
+
+bool DriverDescriptor::resolve_rna()
+{
+ return RNA_path_resolve_property(id_ptr_, fcu_->rna_path, &pointer_rna_, &property_rna_);
+}
+
+static bool is_reachable(const Node *const from, const Node *const to)
+{
+ if (from == to) {
+ return true;
+ }
+
+ // Perform a graph walk from 'to' towards its incoming connections.
+ // Walking from 'from' towards its outgoing connections is 10x slower on the Spring rig.
+ deque<const Node *> queue;
+ Set<const Node *> seen;
+ queue.push_back(to);
+ while (!queue.empty()) {
+ // Visit the next node to inspect.
+ const Node *visit = queue.back();
+ queue.pop_back();
+
+ if (visit == from) {
+ return true;
+ }
+
+ // Queue all incoming relations that we haven't seen before.
+ for (Relation *relation : visit->inlinks) {
+ const Node *prev_node = relation->from;
+ if (seen.add(prev_node)) {
+ queue.push_back(prev_node);
+ }
+ }
+ }
+ return false;
+}
+
+/* **** DepsgraphRelationBuilder functions **** */
+
+void DepsgraphRelationBuilder::build_driver_relations()
+{
+ for (IDNode *id_node : graph_->id_nodes) {
+ build_driver_relations(id_node);
+ }
+}
+
+void DepsgraphRelationBuilder::build_driver_relations(IDNode *id_node)
+{
+ /* Add relations between drivers that write to the same datablock.
+ *
+ * This prevents threading issues when two separate RNA properties write to
+ * the same memory address. For example:
+ * - Drivers on individual array elements, as the animation system will write
+ * the whole array back to RNA even when changing individual array value.
+ * - Drivers on RNA properties that map to a single bit flag. Changing the RNA
+ * value will write the entire int containing the bit, in a non-thread-safe
+ * way.
+ */
+ ID *id_orig = id_node->id_orig;
+ AnimData *adt = BKE_animdata_from_id(id_orig);
+ if (adt == nullptr) {
+ return;
+ }
+
+ // Mapping from RNA prefix -> set of driver descriptors:
+ Map<string, Vector<DriverDescriptor>> driver_groups;
+
+ PointerRNA id_ptr;
+ RNA_id_pointer_create(id_orig, &id_ptr);
+
+ LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
+ if (fcu->rna_path == nullptr) {
+ continue;
+ }
+
+ DriverDescriptor driver_desc(&id_ptr, fcu);
+ if (!driver_desc.driver_relations_needed()) {
+ continue;
+ }
+
+ driver_groups.lookup_or_add_default_as(driver_desc.rna_prefix).append(driver_desc);
+ }
+
+ for (Span<DriverDescriptor> prefix_group : driver_groups.values()) {
+ // For each node in the driver group, try to connect it to another node
+ // in the same group without creating any cycles.
+ int num_drivers = prefix_group.size();
+ if (num_drivers < 2) {
+ // A relation requires two drivers.
+ continue;
+ }
+ for (int from_index = 0; from_index < num_drivers; ++from_index) {
+ const DriverDescriptor &driver_from = prefix_group[from_index];
+ Node *op_from = get_node(driver_from.depsgraph_key());
+
+ // Start by trying the next node in the group.
+ for (int to_offset = 1; to_offset < num_drivers; ++to_offset) {
+ const int to_index = (from_index + to_offset) % num_drivers;
+ const DriverDescriptor &driver_to = prefix_group[to_index];
+ Node *op_to = get_node(driver_to.depsgraph_key());
+
+ // Duplicate drivers can exist (see T78615), but cannot be distinguished by OperationKey
+ // and thus have the same depsgraph node. Relations between those drivers should not be
+ // created. This not something that is expected to happen (both the UI and the Python API
+ // prevent duplicate drivers), it did happen in a file and it is easy to deal with here.
+ if (op_from == op_to) {
+ continue;
+ }
+
+ if (from_index < to_index && driver_from.is_same_array_as(driver_to)) {
+ // This is for adding a relation like `color[0]` -> `color[1]`.
+ // When the search for another driver wraps around, we cannot blindly add relations any
+ // more.
+ }
+ else {
+ // Investigate whether this relation would create a dependency cycle.
+ // Example graph:
+ // A -> B -> C
+ // and investigating a potential connection C->A. Because A->C is an
+ // existing transitive connection, adding C->A would create a cycle.
+ if (is_reachable(op_to, op_from)) {
+ continue;
+ }
+
+ // No need to directly connect this node if there is already a transitive connection.
+ if (is_reachable(op_from, op_to)) {
+ break;
+ }
+ }
+
+ add_operation_relation(
+ op_from->get_exit_operation(), op_to->get_entry_operation(), "Driver Serialization");
+ break;
+ }
+ }
+ }
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.h b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.h
new file mode 100644
index 00000000000..c80c69be9e2
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.h
@@ -0,0 +1,76 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "BLI_string_ref.hh"
+
+#include "RNA_types.h"
+
+#include "intern/builder/deg_builder_relations.h"
+
+struct FCurve;
+
+namespace blender {
+namespace deg {
+
+/* Helper class for determining which relations are needed between driver evaluation nodes. */
+class DriverDescriptor {
+ public:
+ /* Drivers are grouped by their RNA prefix. The prefix is the part of the RNA
+ * path up to the last dot, the suffix is the remainder of the RNA path:
+ *
+ * fcu->rna_path rna_prefix rna_suffix
+ * ------------------------------- ---------------------- ----------
+ * 'color' '' 'color'
+ * 'rigidbody_world.time_scale' 'rigidbody_world' 'time_scale'
+ * 'pose.bones["master"].location' 'pose.bones["master"]' 'location'
+ */
+ StringRef rna_prefix;
+ StringRef rna_suffix;
+
+ public:
+ DriverDescriptor(PointerRNA *id_ptr, FCurve *fcu);
+
+ bool driver_relations_needed() const;
+ bool is_array() const;
+ /* Assumes that 'other' comes from the same RNA group, that is, has the same RNA path prefix. */
+ bool is_same_array_as(const DriverDescriptor &other) const;
+ OperationKey depsgraph_key() const;
+
+ private:
+ PointerRNA *id_ptr_;
+ FCurve *fcu_;
+ bool driver_relations_needed_;
+
+ PointerRNA pointer_rna_;
+ PropertyRNA *property_rna_;
+ bool is_array_;
+
+ bool determine_relations_needed();
+ void split_rna_path();
+ bool resolve_rna();
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index 98ae653d294..e3b667427a2 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -149,6 +149,25 @@ Node *RNANodeQuery::find_node(const PointerRNA *ptr,
node_identifier.operation_name_tag);
}
+bool RNANodeQuery::contains(const char *prop_identifier, const char *rna_path_component)
+{
+ const char *substr = strstr(prop_identifier, rna_path_component);
+ if (substr == nullptr) {
+ return false;
+ }
+
+ // If substr != prop_identifier, it means that the substring is found further in prop_identifier,
+ // and that thus index -1 is a valid memory location.
+ const bool start_ok = substr == prop_identifier || substr[-1] == '.';
+ if (!start_ok) {
+ return false;
+ }
+
+ const size_t component_len = strlen(rna_path_component);
+ const bool end_ok = ELEM(substr[component_len], '\0', '.', '[');
+ return end_ok;
+}
+
RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
const PropertyRNA *prop,
RNAPointerSource source)
@@ -283,12 +302,20 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
if (prop != nullptr) {
const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
/* TODO(sergey): How to optimize this? */
- if (strstr(prop_identifier, "location") || strstr(prop_identifier, "rotation") ||
- strstr(prop_identifier, "scale") || strstr(prop_identifier, "matrix_")) {
+ if (contains(prop_identifier, "location") || contains(prop_identifier, "matrix_basis") ||
+ contains(prop_identifier, "matrix_channel") ||
+ contains(prop_identifier, "matrix_inverse") ||
+ contains(prop_identifier, "matrix_local") ||
+ contains(prop_identifier, "matrix_parent_inverse") ||
+ contains(prop_identifier, "matrix_world") ||
+ contains(prop_identifier, "rotation_axis_angle") ||
+ contains(prop_identifier, "rotation_euler") ||
+ contains(prop_identifier, "rotation_mode") ||
+ contains(prop_identifier, "rotation_quaternion") || contains(prop_identifier, "scale")) {
node_identifier.type = NodeType::TRANSFORM;
return node_identifier;
}
- else if (strstr(prop_identifier, "data")) {
+ else if (contains(prop_identifier, "data")) {
/* We access object.data, most likely a geometry.
* Might be a bone tho. */
node_identifier.type = NodeType::GEOMETRY;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.h b/source/blender/depsgraph/intern/builder/deg_builder_rna.h
index 52d0e5f6b12..d03903d508c 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.h
@@ -93,6 +93,19 @@ class RNANodeQuery {
/* Make sure ID data exists for the given ID, and returns it. */
RNANodeQueryIDData *ensure_id_data(const ID *id);
+
+ /* Check whether prop_identifier contains rna_path_component.
+ *
+ * This checks more than a sub-string:
+ *
+ * prop_identifier contains(prop_identifier, "location")
+ * ------------------------ -------------------------------------
+ * location true
+ * ["test_location"] false
+ * pose["bone"].location true
+ * pose["bone"].location.x true
+ */
+ static bool contains(const char *prop_identifier, const char *rna_path_component);
};
} // namespace deg
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna_test.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna_test.cc
new file mode 100644
index 00000000000..c91dda87190
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna_test.cc
@@ -0,0 +1,60 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/builder/deg_builder_rna.h"
+
+#include "testing/testing.h"
+
+namespace blender {
+namespace deg {
+namespace tests {
+
+class TestableRNANodeQuery : public RNANodeQuery {
+ public:
+ static bool contains(const char *prop_identifier, const char *rna_path_component)
+ {
+ return RNANodeQuery::contains(prop_identifier, rna_path_component);
+ }
+};
+
+TEST(deg_builder_rna, contains)
+{
+ EXPECT_TRUE(TestableRNANodeQuery::contains("location", "location"));
+ EXPECT_TRUE(TestableRNANodeQuery::contains("location.x", "location"));
+ EXPECT_TRUE(TestableRNANodeQuery::contains("pose.bone[\"blork\"].location", "location"));
+ EXPECT_TRUE(TestableRNANodeQuery::contains("pose.bone[\"blork\"].location.x", "location"));
+ EXPECT_TRUE(TestableRNANodeQuery::contains("pose.bone[\"blork\"].location[0]", "location"));
+
+ EXPECT_FALSE(TestableRNANodeQuery::contains("", "location"));
+ EXPECT_FALSE(TestableRNANodeQuery::contains("locatio", "location"));
+ EXPECT_FALSE(TestableRNANodeQuery::contains("locationnn", "location"));
+ EXPECT_FALSE(TestableRNANodeQuery::contains("test_location", "location"));
+ EXPECT_FALSE(TestableRNANodeQuery::contains("location_test", "location"));
+ EXPECT_FALSE(TestableRNANodeQuery::contains("test_location_test", "location"));
+ EXPECT_FALSE(TestableRNANodeQuery::contains("pose.bone[\"location\"].scale", "location"));
+ EXPECT_FALSE(TestableRNANodeQuery::contains("pose.bone[\"location\"].scale[0]", "location"));
+}
+
+} // namespace tests
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline.cc b/source/blender/depsgraph/intern/builder/pipeline.cc
new file mode 100644
index 00000000000..d6893ba11d8
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline.cc
@@ -0,0 +1,132 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline.h"
+
+#include "PIL_time.h"
+
+#include "BKE_global.h"
+
+#include "DNA_scene_types.h"
+
+#include "deg_builder_cycle.h"
+#include "deg_builder_nodes.h"
+#include "deg_builder_relations.h"
+#include "deg_builder_transitive.h"
+
+namespace blender {
+namespace deg {
+
+AbstractBuilderPipeline::AbstractBuilderPipeline(::Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer)
+ : deg_graph_(reinterpret_cast<Depsgraph *>(graph)),
+ bmain_(bmain),
+ scene_(scene),
+ view_layer_(view_layer),
+ builder_cache_()
+{
+}
+
+AbstractBuilderPipeline::~AbstractBuilderPipeline()
+{
+}
+
+void AbstractBuilderPipeline::build()
+{
+ double start_time = 0.0;
+ if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
+ start_time = PIL_check_seconds_timer();
+ }
+
+ build_step_sanity_check();
+ build_step_nodes();
+ build_step_relations();
+ build_step_finalize();
+
+ if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
+ printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
+ }
+}
+
+void AbstractBuilderPipeline::build_step_sanity_check()
+{
+ BLI_assert(BLI_findindex(&scene_->view_layers, view_layer_) != -1);
+ BLI_assert(deg_graph_->scene == scene_);
+ BLI_assert(deg_graph_->view_layer == view_layer_);
+}
+
+void AbstractBuilderPipeline::build_step_nodes()
+{
+ /* Generate all the nodes in the graph first */
+ unique_ptr<DepsgraphNodeBuilder> node_builder = construct_node_builder();
+ node_builder->begin_build();
+ build_nodes(*node_builder);
+ node_builder->end_build();
+}
+
+void AbstractBuilderPipeline::build_step_relations()
+{
+ /* Hook up relationships between operations - to determine evaluation order. */
+ unique_ptr<DepsgraphRelationBuilder> relation_builder = construct_relation_builder();
+ relation_builder->begin_build();
+ build_relations(*relation_builder);
+ relation_builder->build_copy_on_write_relations();
+ relation_builder->build_driver_relations();
+}
+
+void AbstractBuilderPipeline::build_step_finalize()
+{
+ /* Detect and solve cycles. */
+ deg_graph_detect_cycles(deg_graph_);
+ /* Simplify the graph by removing redundant relations (to optimize
+ * traversal later). */
+ /* TODO: it would be useful to have an option to disable this in cases where
+ * it is causing trouble. */
+ if (G.debug_value == 799) {
+ deg_graph_transitive_reduction(deg_graph_);
+ }
+ /* Store pointers to commonly used valuated datablocks. */
+ deg_graph_->scene_cow = (Scene *)deg_graph_->get_cow_id(&deg_graph_->scene->id);
+ /* Flush visibility layer and re-schedule nodes for update. */
+ deg_graph_build_finalize(bmain_, deg_graph_);
+ DEG_graph_on_visible_update(bmain_, reinterpret_cast<::Depsgraph *>(deg_graph_), false);
+#if 0
+ if (!DEG_debug_consistency_check(deg_graph_)) {
+ printf("Consistency validation failed, ABORTING!\n");
+ abort();
+ }
+#endif
+ /* Relations are up to date. */
+ deg_graph_->need_update = false;
+}
+
+unique_ptr<DepsgraphNodeBuilder> AbstractBuilderPipeline::construct_node_builder()
+{
+ return std::make_unique<DepsgraphNodeBuilder>(bmain_, deg_graph_, &builder_cache_);
+}
+
+unique_ptr<DepsgraphRelationBuilder> AbstractBuilderPipeline::construct_relation_builder()
+{
+ return std::make_unique<DepsgraphRelationBuilder>(bmain_, deg_graph_, &builder_cache_);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline.h b/source/blender/depsgraph/intern/builder/pipeline.h
new file mode 100644
index 00000000000..2c9c78bb2cb
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline.h
@@ -0,0 +1,77 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "deg_builder_cache.h"
+
+#include "intern/depsgraph_type.h"
+
+struct Main;
+struct Scene;
+struct ViewLayer;
+struct Depsgraph;
+
+namespace blender {
+namespace deg {
+
+struct Depsgraph;
+class DepsgraphNodeBuilder;
+class DepsgraphRelationBuilder;
+
+/* Base class for Depsgraph Builder pipelines.
+ *
+ * Basically it runs through the following steps:
+ * - sanity check
+ * - build nodes
+ * - build relations
+ * - finalize
+ */
+class AbstractBuilderPipeline {
+ public:
+ AbstractBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+ virtual ~AbstractBuilderPipeline();
+
+ void build();
+
+ protected:
+ Depsgraph *deg_graph_;
+ Main *bmain_;
+ Scene *scene_;
+ ViewLayer *view_layer_;
+ DepsgraphBuilderCache builder_cache_;
+
+ virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder();
+ virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder();
+
+ virtual void build_step_sanity_check();
+ void build_step_nodes();
+ void build_step_relations();
+ void build_step_finalize();
+
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) = 0;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) = 0;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.cc b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc
new file mode 100644
index 00000000000..3e56f17fc7e
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc
@@ -0,0 +1,49 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_compositor.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+namespace blender {
+namespace deg {
+
+CompositorBuilderPipeline::CompositorBuilderPipeline(
+ ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, bNodeTree *nodetree)
+ : AbstractBuilderPipeline(graph, bmain, scene, view_layer), nodetree_(nodetree)
+{
+ deg_graph_->is_render_pipeline_depsgraph = true;
+}
+
+void CompositorBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder)
+{
+ node_builder.build_scene_render(scene_, view_layer_);
+ node_builder.build_nodetree(nodetree_);
+}
+
+void CompositorBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder)
+{
+ relation_builder.build_scene_render(scene_, view_layer_);
+ relation_builder.build_nodetree(nodetree_);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/functions/FN_cpp_types.hh b/source/blender/depsgraph/intern/builder/pipeline_compositor.h
index 704a1363935..892ece7c2a4 100644
--- a/source/blender/functions/FN_cpp_types.hh
+++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.h
@@ -12,37 +12,36 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
*/
-#ifndef __FN_CPP_TYPES_HH__
-#define __FN_CPP_TYPES_HH__
-
/** \file
- * \ingroup functions
- *
- * This header provides convenient access to CPPType instances for some core types like integer
- * types.
+ * \ingroup depsgraph
*/
-#include "FN_cpp_type.hh"
-
-namespace blender::fn {
+#pragma once
-extern const CPPType &CPPType_bool;
+#include "pipeline.h"
-extern const CPPType &CPPType_float;
-extern const CPPType &CPPType_float3;
-extern const CPPType &CPPType_float4x4;
+struct bNodeTree;
-extern const CPPType &CPPType_int32;
-extern const CPPType &CPPType_uint32;
-extern const CPPType &CPPType_uint8;
+namespace blender {
+namespace deg {
-extern const CPPType &CPPType_Color4f;
-extern const CPPType &CPPType_Color4b;
+class CompositorBuilderPipeline : public AbstractBuilderPipeline {
+ public:
+ CompositorBuilderPipeline(
+ ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, bNodeTree *nodetree);
-extern const CPPType &CPPType_string;
+ protected:
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
-} // namespace blender::fn
+ private:
+ bNodeTree *nodetree_;
+};
-#endif /* __FN_CPP_TYPES_HH__ */
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
new file mode 100644
index 00000000000..e44f554f197
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
@@ -0,0 +1,154 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_from_ids.h"
+
+#include "DNA_layer_types.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+namespace blender {
+namespace deg {
+
+namespace {
+
+class DepsgraphFromIDsFilter {
+ public:
+ DepsgraphFromIDsFilter(ID **ids, const int num_ids)
+ {
+ for (int i = 0; i < num_ids; ++i) {
+ ids_.add(ids[i]);
+ }
+ }
+
+ bool contains(ID *id)
+ {
+ return ids_.contains(id);
+ }
+
+ protected:
+ Set<ID *> ids_;
+};
+
+class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
+ public:
+ DepsgraphFromIDsNodeBuilder(
+ Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
+ : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids, num_ids)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base *base) override
+ {
+ if (!filter_.contains(&base->object->id)) {
+ return false;
+ }
+ return DepsgraphNodeBuilder::need_pull_base_into_graph(base);
+ }
+
+ virtual void build_object_proxy_group(Object *object, bool is_visible) override
+ {
+ if (object->proxy_group == nullptr) {
+ return;
+ }
+ if (!filter_.contains(&object->proxy_group->id)) {
+ return;
+ }
+ DepsgraphNodeBuilder::build_object_proxy_group(object, is_visible);
+ }
+
+ protected:
+ DepsgraphFromIDsFilter filter_;
+};
+
+class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
+ public:
+ DepsgraphFromIDsRelationBuilder(
+ Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
+ : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids, num_ids)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base *base) override
+ {
+ if (!filter_.contains(&base->object->id)) {
+ return false;
+ }
+ return DepsgraphRelationBuilder::need_pull_base_into_graph(base);
+ }
+
+ virtual void build_object_proxy_group(Object *object) override
+ {
+ if (object->proxy_group == nullptr) {
+ return;
+ }
+ if (!filter_.contains(&object->proxy_group->id)) {
+ return;
+ }
+ DepsgraphRelationBuilder::build_object_proxy_group(object);
+ }
+
+ protected:
+ DepsgraphFromIDsFilter filter_;
+};
+
+} // namespace
+
+FromIDsBuilderPipeline::FromIDsBuilderPipeline(::Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer,
+ ID **ids,
+ const int num_ids)
+ : AbstractBuilderPipeline(graph, bmain, scene, view_layer), ids_(ids), num_ids_(num_ids)
+{
+}
+
+unique_ptr<DepsgraphNodeBuilder> FromIDsBuilderPipeline::construct_node_builder()
+{
+ return std::make_unique<DepsgraphFromIDsNodeBuilder>(
+ bmain_, deg_graph_, &builder_cache_, ids_, num_ids_);
+}
+
+unique_ptr<DepsgraphRelationBuilder> FromIDsBuilderPipeline::construct_relation_builder()
+{
+ return std::make_unique<DepsgraphFromIDsRelationBuilder>(
+ bmain_, deg_graph_, &builder_cache_, ids_, num_ids_);
+}
+
+void FromIDsBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder)
+{
+ node_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
+ for (int i = 0; i < num_ids_; ++i) {
+ node_builder.build_id(ids_[i]);
+ }
+}
+
+void FromIDsBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder)
+{
+ relation_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
+ for (int i = 0; i < num_ids_; ++i) {
+ relation_builder.build_id(ids_[i]);
+ }
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.h b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
new file mode 100644
index 00000000000..4a507f2c728
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
@@ -0,0 +1,62 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "pipeline.h"
+
+namespace blender {
+namespace deg {
+
+/* Optimized builders for dependency graph built from a given set of IDs.
+ *
+ * General notes:
+ *
+ * - We pull in all bases if their objects are in the set of IDs. This allows to have proper
+ * visibility and other flags assigned to the objects.
+ * All other bases (the ones which points to object which is outside of the set of IDs) are
+ * completely ignored.
+ *
+ * - Proxy groups pointing to objects which are outside of the IDs set are also ignored.
+ * This way we avoid high-poly character body pulled into the dependency graph when it's coming
+ * from a library into an animation file and the dependency graph constructed for a proxy rig. */
+
+class FromIDsBuilderPipeline : public AbstractBuilderPipeline {
+ public:
+ FromIDsBuilderPipeline(
+ ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, ID **ids, int num_ids);
+
+ protected:
+ virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder() override;
+ virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder() override;
+
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
+
+ private:
+ ID **ids_;
+ const int num_ids_;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.cc b/source/blender/depsgraph/intern/builder/pipeline_render.cc
new file mode 100644
index 00000000000..50a37d0d3e4
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_render.cc
@@ -0,0 +1,49 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_render.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+namespace blender {
+namespace deg {
+
+RenderBuilderPipeline::RenderBuilderPipeline(::Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer)
+ : AbstractBuilderPipeline(graph, bmain, scene, view_layer)
+{
+ deg_graph_->is_render_pipeline_depsgraph = true;
+}
+
+void RenderBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder)
+{
+ node_builder.build_scene_render(scene_, view_layer_);
+}
+
+void RenderBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder)
+{
+ relation_builder.build_scene_render(scene_, view_layer_);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.h b/source/blender/depsgraph/intern/builder/pipeline_render.h
new file mode 100644
index 00000000000..df7f9e0de68
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_render.h
@@ -0,0 +1,41 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "pipeline.h"
+
+namespace blender {
+namespace deg {
+
+class RenderBuilderPipeline : public AbstractBuilderPipeline {
+ public:
+ RenderBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+
+ protected:
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc
new file mode 100644
index 00000000000..3223f17f349
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc
@@ -0,0 +1,48 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_view_layer.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+namespace blender {
+namespace deg {
+
+ViewLayerBuilderPipeline::ViewLayerBuilderPipeline(::Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer)
+ : AbstractBuilderPipeline(graph, bmain, scene, view_layer)
+{
+}
+
+void ViewLayerBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder)
+{
+ node_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
+}
+
+void ViewLayerBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder)
+{
+ relation_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.h b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
new file mode 100644
index 00000000000..fbd7b98acad
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
@@ -0,0 +1,41 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "pipeline.h"
+
+namespace blender {
+namespace deg {
+
+class ViewLayerBuilderPipeline : public AbstractBuilderPipeline {
+ public:
+ ViewLayerBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+
+ protected:
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
index 458baf4fb1e..d0356f44022 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
@@ -25,6 +25,7 @@
#include <cstdarg>
+#include "BLI_dot_export.hh"
#include "BLI_utildefines.h"
#include "DNA_listBase.h"
@@ -41,6 +42,7 @@
#include "intern/node/deg_node_time.h"
namespace deg = blender::deg;
+namespace dot = blender::dot;
/* ****************** */
/* Graphviz Debugging */
@@ -48,8 +50,6 @@ namespace deg = blender::deg;
namespace blender {
namespace deg {
-#define NL "\r\n"
-
/* Only one should be enabled, defines whether graphviz nodes
* get colored by individual types or classes.
*/
@@ -158,47 +158,43 @@ static int deg_debug_node_color_index(const Node *node)
#endif
}
-struct DebugContext {
- FILE *file;
+struct DotExportContext {
bool show_tags;
+ dot::DirectedGraph &digraph;
+ Map<const Node *, dot::Node *> nodes_map;
+ Map<const Node *, dot::Cluster *> clusters_map;
};
-static void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...)
- ATTR_PRINTF_FORMAT(2, 3);
-static void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...)
+static void deg_debug_graphviz_legend_color(const char *name,
+ const char *color,
+ std::stringstream &ss)
{
- va_list args;
- va_start(args, fmt);
- vfprintf(ctx.file, fmt, args);
- va_end(args);
-}
-static void deg_debug_graphviz_legend_color(const DebugContext &ctx,
- const char *name,
- const char *color)
-{
- deg_debug_fprintf(ctx, "<TR>");
- deg_debug_fprintf(ctx, "<TD>%s</TD>", name);
- deg_debug_fprintf(ctx, "<TD BGCOLOR=\"%s\"></TD>", color);
- deg_debug_fprintf(ctx, "</TR>" NL);
+ ss << "<TR>";
+ ss << "<TD>" << name << "</TD>";
+ ss << "<TD BGCOLOR=\"" << color << "\"></TD>";
+ ss << "</TR>";
}
-static void deg_debug_graphviz_legend(const DebugContext &ctx)
+static void deg_debug_graphviz_legend(DotExportContext &ctx)
{
- deg_debug_fprintf(ctx, "{" NL);
- deg_debug_fprintf(ctx, "rank = sink;" NL);
- deg_debug_fprintf(ctx, "Legend [shape=none, margin=0, label=<" NL);
- deg_debug_fprintf(
- ctx, " <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">" NL);
- deg_debug_fprintf(ctx, "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>" NL);
+ dot::Node &legend_node = ctx.digraph.new_node("");
+ legend_node.attributes.set("rank", "sink");
+ legend_node.attributes.set("shape", "none");
+ legend_node.attributes.set("margin", 0);
+
+ std::stringstream ss;
+ ss << "<";
+ ss << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">";
+ ss << "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>";
#ifdef COLOR_SCHEME_NODE_CLASS
const char **colors = deg_debug_colors_light;
- deg_debug_graphviz_legend_color(ctx, "Operation", colors[4]);
- deg_debug_graphviz_legend_color(ctx, "Component", colors[1]);
- deg_debug_graphviz_legend_color(ctx, "ID Node", colors[5]);
- deg_debug_graphviz_legend_color(ctx, "NOOP", colors[8]);
- deg_debug_graphviz_legend_color(ctx, "Pinned OP", colors[7]);
+ deg_debug_graphviz_legend_color("Operation", colors[4], ss);
+ deg_debug_graphviz_legend_color("Component", colors[1], ss);
+ deg_debug_graphviz_legend_color("ID Node", colors[5], ss);
+ deg_debug_graphviz_legend_color("NOOP", colors[8], ss);
+ deg_debug_graphviz_legend_color("Pinned OP", colors[7], ss);
#endif
#ifdef COLOR_SCHEME_NODE_TYPE
@@ -206,18 +202,19 @@ static void deg_debug_graphviz_legend(const DebugContext &ctx)
for (pair = deg_debug_node_type_color_map; (*pair)[0] >= 0; pair++) {
DepsNodeFactory *nti = type_get_factory((NodeType)(*pair)[0]);
deg_debug_graphviz_legend_color(
- ctx, nti->tname().c_str(), deg_debug_colors_light[(*pair)[1] % deg_debug_max_colors]);
+ ctx, nti->tname().c_str(), deg_debug_colors_light[(*pair)[1] % deg_debug_max_colors], ss);
}
#endif
- deg_debug_fprintf(ctx, "</TABLE>" NL);
- deg_debug_fprintf(ctx, ">" NL);
- deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg_debug_graphviz_fontname);
- deg_debug_fprintf(ctx, "];" NL);
- deg_debug_fprintf(ctx, "}" NL);
+ ss << "</TABLE>";
+ ss << ">";
+ legend_node.attributes.set("label", ss.str());
+ legend_node.attributes.set("fontname", deg_debug_graphviz_fontname);
}
-static void deg_debug_graphviz_node_color(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_color(DotExportContext &ctx,
+ const Node *node,
+ dot::Attributes &dot_attributes)
{
const char *color_default = "black";
const char *color_modified = "orangered4";
@@ -234,10 +231,12 @@ static void deg_debug_graphviz_node_color(const DebugContext &ctx, const Node *n
}
}
}
- deg_debug_fprintf(ctx, "\"%s\"", color);
+ dot_attributes.set("color", color);
}
-static void deg_debug_graphviz_node_penwidth(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_penwidth(DotExportContext &ctx,
+ const Node *node,
+ dot::Attributes &dot_attributes)
{
float penwidth_default = 1.0f;
float penwidth_modified = 4.0f;
@@ -254,20 +253,20 @@ static void deg_debug_graphviz_node_penwidth(const DebugContext &ctx, const Node
}
}
}
- deg_debug_fprintf(ctx, "\"%f\"", penwidth);
+ dot_attributes.set("penwidth", penwidth);
}
-static void deg_debug_graphviz_node_fillcolor(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_fillcolor(const Node *node, dot::Attributes &dot_attributes)
{
const char *defaultcolor = "gainsboro";
int color_index = deg_debug_node_color_index(node);
const char *fillcolor = color_index < 0 ?
defaultcolor :
deg_debug_colors_light[color_index % deg_debug_max_colors];
- deg_debug_fprintf(ctx, "\"%s\"", fillcolor);
+ dot_attributes.set("fillcolor", fillcolor);
}
-static void deg_debug_graphviz_relation_color(const DebugContext &ctx, const Relation *rel)
+static void deg_debug_graphviz_relation_color(const Relation *rel, dot::DirectedEdge &edge)
{
const char *color_default = "black";
const char *color_cyclic = "red4"; /* The color of crime scene. */
@@ -279,10 +278,10 @@ static void deg_debug_graphviz_relation_color(const DebugContext &ctx, const Rel
else if (rel->flag & RELATION_FLAG_GODMODE) {
color = color_godmode;
}
- deg_debug_fprintf(ctx, "%s", color);
+ edge.attributes.set("color", color);
}
-static void deg_debug_graphviz_relation_style(const DebugContext &ctx, const Relation *rel)
+static void deg_debug_graphviz_relation_style(const Relation *rel, dot::DirectedEdge &edge)
{
const char *style_default = "solid";
const char *style_no_flush = "dashed";
@@ -294,10 +293,10 @@ static void deg_debug_graphviz_relation_style(const DebugContext &ctx, const Rel
if (rel->flag & RELATION_FLAG_FLUSH_USER_EDIT_ONLY) {
style = style_flush_user_only;
}
- deg_debug_fprintf(ctx, "%s", style);
+ edge.attributes.set("style", style);
}
-static void deg_debug_graphviz_relation_arrowhead(const DebugContext &ctx, const Relation *rel)
+static void deg_debug_graphviz_relation_arrowhead(const Relation *rel, dot::DirectedEdge &edge)
{
const char *shape_default = "normal";
const char *shape_no_cow = "box";
@@ -311,12 +310,14 @@ static void deg_debug_graphviz_relation_arrowhead(const DebugContext &ctx, const
shape = shape_no_cow;
}
}
- deg_debug_fprintf(ctx, "%s", shape);
+ edge.attributes.set("arrowhead", shape);
}
-static void deg_debug_graphviz_node_style(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_style(DotExportContext &ctx,
+ const Node *node,
+ dot::Attributes &dot_attributes)
{
- const char *base_style = "filled"; /* default style */
+ StringRef base_style = "filled"; /* default style */
if (ctx.show_tags) {
if (node->get_class() == NodeClass::OPERATION) {
OperationNode *op_node = (OperationNode *)node;
@@ -327,95 +328,78 @@ static void deg_debug_graphviz_node_style(const DebugContext &ctx, const Node *n
}
switch (node->get_class()) {
case NodeClass::GENERIC:
- deg_debug_fprintf(ctx, "\"%s\"", base_style);
+ dot_attributes.set("style", base_style);
break;
case NodeClass::COMPONENT:
- deg_debug_fprintf(ctx, "\"%s\"", base_style);
+ dot_attributes.set("style", base_style);
break;
case NodeClass::OPERATION:
- deg_debug_fprintf(ctx, "\"%s,rounded\"", base_style);
+ dot_attributes.set("style", base_style + ",rounded");
break;
}
}
-static void deg_debug_graphviz_node_single(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_single(DotExportContext &ctx,
+ const Node *node,
+ dot::Cluster *parent_cluster)
{
- const char *shape = "box";
string name = node->identifier();
- deg_debug_fprintf(ctx, "// %s\n", name.c_str());
- deg_debug_fprintf(ctx, "\"node_%p\"", node);
- deg_debug_fprintf(ctx, "[");
- // deg_debug_fprintf(ctx, "label=<<B>%s</B>>", name);
- deg_debug_fprintf(ctx, "label=<%s>", name.c_str());
- deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg_debug_graphviz_fontname);
- deg_debug_fprintf(ctx, ",fontsize=%f", deg_debug_graphviz_node_label_size);
- deg_debug_fprintf(ctx, ",shape=%s", shape);
- deg_debug_fprintf(ctx, ",style=");
- deg_debug_graphviz_node_style(ctx, node);
- deg_debug_fprintf(ctx, ",color=");
- deg_debug_graphviz_node_color(ctx, node);
- deg_debug_fprintf(ctx, ",fillcolor=");
- deg_debug_graphviz_node_fillcolor(ctx, node);
- deg_debug_fprintf(ctx, ",penwidth=");
- deg_debug_graphviz_node_penwidth(ctx, node);
- deg_debug_fprintf(ctx, "];" NL);
- deg_debug_fprintf(ctx, NL);
+
+ dot::Node &dot_node = ctx.digraph.new_node(name);
+ ctx.nodes_map.add_new(node, &dot_node);
+ dot_node.set_parent_cluster(parent_cluster);
+ dot_node.attributes.set("fontname", deg_debug_graphviz_fontname);
+ dot_node.attributes.set("frontsize", deg_debug_graphviz_node_label_size);
+ dot_node.attributes.set("shape", "box");
+
+ deg_debug_graphviz_node_style(ctx, node, dot_node.attributes);
+ deg_debug_graphviz_node_color(ctx, node, dot_node.attributes);
+ deg_debug_graphviz_node_fillcolor(node, dot_node.attributes);
+ deg_debug_graphviz_node_penwidth(ctx, node, dot_node.attributes);
}
-static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx, const Node *node)
+static dot::Cluster &deg_debug_graphviz_node_cluster_create(DotExportContext &ctx,
+ const Node *node,
+ dot::Cluster *parent_cluster)
{
string name = node->identifier();
- deg_debug_fprintf(ctx, "// %s\n", name.c_str());
- deg_debug_fprintf(ctx, "subgraph \"cluster_%p\" {" NL, node);
- // deg_debug_fprintf(ctx, "label=<<B>%s</B>>;" NL, name);
- deg_debug_fprintf(ctx, "label=<%s>;" NL, name.c_str());
- deg_debug_fprintf(ctx, "fontname=\"%s\";" NL, deg_debug_graphviz_fontname);
- deg_debug_fprintf(ctx, "fontsize=%f;" NL, deg_debug_graphviz_node_label_size);
- deg_debug_fprintf(ctx, "margin=\"%d\";" NL, 16);
- deg_debug_fprintf(ctx, "style=");
- deg_debug_graphviz_node_style(ctx, node);
- deg_debug_fprintf(ctx, ";" NL);
- deg_debug_fprintf(ctx, "color=");
- deg_debug_graphviz_node_color(ctx, node);
- deg_debug_fprintf(ctx, ";" NL);
- deg_debug_fprintf(ctx, "fillcolor=");
- deg_debug_graphviz_node_fillcolor(ctx, node);
- deg_debug_fprintf(ctx, ";" NL);
- deg_debug_fprintf(ctx, "penwidth=");
- deg_debug_graphviz_node_penwidth(ctx, node);
- deg_debug_fprintf(ctx, ";" NL);
+ dot::Cluster &cluster = ctx.digraph.new_cluster(name);
+ cluster.set_parent_cluster(parent_cluster);
+ cluster.attributes.set("fontname", deg_debug_graphviz_fontname);
+ cluster.attributes.set("fontsize", deg_debug_graphviz_node_label_size);
+ cluster.attributes.set("margin", 16);
+ deg_debug_graphviz_node_style(ctx, node, cluster.attributes);
+ deg_debug_graphviz_node_color(ctx, node, cluster.attributes);
+ deg_debug_graphviz_node_fillcolor(node, cluster.attributes);
+ deg_debug_graphviz_node_penwidth(ctx, node, cluster.attributes);
/* dummy node, so we can add edges between clusters */
- deg_debug_fprintf(ctx, "\"node_%p\"", node);
- deg_debug_fprintf(ctx, "[");
- deg_debug_fprintf(ctx, "shape=%s", "point");
- deg_debug_fprintf(ctx, ",style=%s", "invis");
- deg_debug_fprintf(ctx, "];" NL);
- deg_debug_fprintf(ctx, NL);
+ dot::Node &dot_node = ctx.digraph.new_node("");
+ dot_node.attributes.set("shape", "point");
+ dot_node.attributes.set("style", "invis");
+ dot_node.set_parent_cluster(&cluster);
+ ctx.nodes_map.add_new(node, &dot_node);
+ ctx.clusters_map.add_new(node, &cluster);
+ return cluster;
}
-static void deg_debug_graphviz_node_cluster_end(const DebugContext &ctx)
-{
- deg_debug_fprintf(ctx, "}" NL);
- deg_debug_fprintf(ctx, NL);
-}
+static void deg_debug_graphviz_graph_nodes(DotExportContext &ctx, const Depsgraph *graph);
+static void deg_debug_graphviz_graph_relations(DotExportContext &ctx, const Depsgraph *graph);
-static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx, const Depsgraph *graph);
-static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, const Depsgraph *graph);
-
-static void deg_debug_graphviz_node(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node(DotExportContext &ctx,
+ const Node *node,
+ dot::Cluster *parent_cluster)
{
switch (node->type) {
case NodeType::ID_REF: {
const IDNode *id_node = (const IDNode *)node;
if (id_node->components.is_empty()) {
- deg_debug_graphviz_node_single(ctx, node);
+ deg_debug_graphviz_node_single(ctx, node, parent_cluster);
}
else {
- deg_debug_graphviz_node_cluster_begin(ctx, node);
+ dot::Cluster &cluster = deg_debug_graphviz_node_cluster_create(ctx, node, parent_cluster);
for (const ComponentNode *comp : id_node->components.values()) {
- deg_debug_graphviz_node(ctx, comp);
+ deg_debug_graphviz_node(ctx, comp, &cluster);
}
- deg_debug_graphviz_node_cluster_end(ctx);
}
break;
}
@@ -445,127 +429,72 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, const Node *node)
case NodeType::GENERIC_DATABLOCK:
case NodeType::SIMULATION: {
ComponentNode *comp_node = (ComponentNode *)node;
- if (!comp_node->operations.is_empty()) {
- deg_debug_graphviz_node_cluster_begin(ctx, node);
- for (Node *op_node : comp_node->operations) {
- deg_debug_graphviz_node(ctx, op_node);
- }
- deg_debug_graphviz_node_cluster_end(ctx);
+ if (comp_node->operations.is_empty()) {
+ deg_debug_graphviz_node_single(ctx, node, parent_cluster);
}
else {
- deg_debug_graphviz_node_single(ctx, node);
+ dot::Cluster &cluster = deg_debug_graphviz_node_cluster_create(ctx, node, parent_cluster);
+ for (Node *op_node : comp_node->operations) {
+ deg_debug_graphviz_node(ctx, op_node, &cluster);
+ }
}
break;
}
case NodeType::UNDEFINED:
case NodeType::TIMESOURCE:
case NodeType::OPERATION:
- deg_debug_graphviz_node_single(ctx, node);
+ deg_debug_graphviz_node_single(ctx, node, parent_cluster);
break;
case NodeType::NUM_TYPES:
break;
}
}
-static bool deg_debug_graphviz_is_cluster(const Node *node)
-{
- switch (node->type) {
- case NodeType::ID_REF: {
- const IDNode *id_node = (const IDNode *)node;
- return !id_node->components.is_empty();
- }
- case NodeType::PARAMETERS:
- case NodeType::ANIMATION:
- case NodeType::TRANSFORM:
- case NodeType::PROXY:
- case NodeType::GEOMETRY:
- case NodeType::SEQUENCER:
- case NodeType::EVAL_POSE:
- case NodeType::BONE: {
- ComponentNode *comp_node = (ComponentNode *)node;
- return !comp_node->operations.is_empty();
- }
- default:
- return false;
- }
-}
-
-static bool deg_debug_graphviz_is_owner(const Node *node, const Node *other)
-{
- switch (node->get_class()) {
- case NodeClass::COMPONENT: {
- ComponentNode *comp_node = (ComponentNode *)node;
- if (comp_node->owner == other) {
- return true;
- }
- break;
- }
- case NodeClass::OPERATION: {
- OperationNode *op_node = (OperationNode *)node;
- if (op_node->owner == other) {
- return true;
- }
- else if (op_node->owner->owner == other) {
- return true;
- }
- break;
- }
- default:
- break;
- }
- return false;
-}
-
-static void deg_debug_graphviz_node_relations(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_relations(DotExportContext &ctx, const Node *node)
{
for (Relation *rel : node->inlinks) {
float penwidth = 2.0f;
- const Node *tail = rel->to; /* same as node */
- const Node *head = rel->from;
- deg_debug_fprintf(
- ctx, "// %s -> %s\n", head->identifier().c_str(), tail->identifier().c_str());
- deg_debug_fprintf(ctx, "\"node_%p\"", head);
- deg_debug_fprintf(ctx, " -> ");
- deg_debug_fprintf(ctx, "\"node_%p\"", tail);
+ const Node *head = rel->to; /* same as node */
+ const Node *tail = rel->from;
+ dot::Node &dot_tail = *ctx.nodes_map.lookup(tail);
+ dot::Node &dot_head = *ctx.nodes_map.lookup(head);
+
+ dot::DirectedEdge &edge = ctx.digraph.new_edge(dot_tail, dot_head);
- deg_debug_fprintf(ctx, "[");
/* Note: without label an id seem necessary to avoid bugs in graphviz/dot */
- deg_debug_fprintf(ctx, "id=\"%s\"", rel->name);
- // deg_debug_fprintf(ctx, "label=\"%s\"", rel->name);
- deg_debug_fprintf(ctx, ",color=");
- deg_debug_graphviz_relation_color(ctx, rel);
- deg_debug_fprintf(ctx, ",style=");
- deg_debug_graphviz_relation_style(ctx, rel);
- deg_debug_fprintf(ctx, ",arrowhead=");
- deg_debug_graphviz_relation_arrowhead(ctx, rel);
- deg_debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth);
+ edge.attributes.set("id", rel->name);
+ deg_debug_graphviz_relation_color(rel, edge);
+ deg_debug_graphviz_relation_style(rel, edge);
+ deg_debug_graphviz_relation_arrowhead(rel, edge);
+ edge.attributes.set("penwidth", penwidth);
+
/* NOTE: edge from node to own cluster is not possible and gives graphviz
* warning, avoid this here by just linking directly to the invisible
* placeholder node. */
- if (deg_debug_graphviz_is_cluster(tail) && !deg_debug_graphviz_is_owner(head, tail)) {
- deg_debug_fprintf(ctx, ",ltail=\"cluster_%p\"", tail);
+ dot::Cluster *tail_cluster = ctx.clusters_map.lookup_default(tail, nullptr);
+ if (tail_cluster != nullptr && tail_cluster->contains(dot_head)) {
+ edge.attributes.set("ltail", tail_cluster->name());
}
- if (deg_debug_graphviz_is_cluster(head) && !deg_debug_graphviz_is_owner(tail, head)) {
- deg_debug_fprintf(ctx, ",lhead=\"cluster_%p\"", head);
+ dot::Cluster *head_cluster = ctx.clusters_map.lookup_default(head, nullptr);
+ if (head_cluster != nullptr && head_cluster->contains(dot_tail)) {
+ edge.attributes.set("lhead", head_cluster->name());
}
- deg_debug_fprintf(ctx, "];" NL);
- deg_debug_fprintf(ctx, NL);
}
}
-static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx, const Depsgraph *graph)
+static void deg_debug_graphviz_graph_nodes(DotExportContext &ctx, const Depsgraph *graph)
{
for (Node *node : graph->id_nodes) {
- deg_debug_graphviz_node(ctx, node);
+ deg_debug_graphviz_node(ctx, node, nullptr);
}
TimeSourceNode *time_source = graph->find_time_source();
if (time_source != nullptr) {
- deg_debug_graphviz_node(ctx, time_source);
+ deg_debug_graphviz_node(ctx, time_source, nullptr);
}
}
-static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, const Depsgraph *graph)
+static void deg_debug_graphviz_graph_relations(DotExportContext &ctx, const Depsgraph *graph)
{
for (IDNode *id_node : graph->id_nodes) {
for (ComponentNode *comp_node : id_node->components.values()) {
@@ -592,27 +521,23 @@ void DEG_debug_relations_graphviz(const Depsgraph *graph, FILE *f, const char *l
const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
- deg::DebugContext ctx;
- ctx.file = f;
-
- deg::deg_debug_fprintf(ctx, "digraph depgraph {" NL);
- deg::deg_debug_fprintf(ctx, "rankdir=LR;" NL);
- deg::deg_debug_fprintf(ctx, "graph [");
- deg::deg_debug_fprintf(ctx, "compound=true");
- deg::deg_debug_fprintf(ctx, ",labelloc=\"t\"");
- deg::deg_debug_fprintf(ctx, ",fontsize=%f", deg::deg_debug_graphviz_graph_label_size);
- deg::deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg::deg_debug_graphviz_fontname);
- deg::deg_debug_fprintf(ctx, ",label=\"%s\"", label);
- deg::deg_debug_fprintf(ctx, ",splines=ortho");
- deg::deg_debug_fprintf(ctx, ",overlap=scalexy"); // XXX: only when using neato
- deg::deg_debug_fprintf(ctx, "];" NL);
+ dot::DirectedGraph digraph;
+ deg::DotExportContext ctx{false, digraph};
+
+ digraph.set_rankdir(dot::Attr_rankdir::LeftToRight);
+ digraph.attributes.set("compound", "true");
+ digraph.attributes.set("labelloc", "t");
+ digraph.attributes.set("fontsize", deg::deg_debug_graphviz_graph_label_size);
+ digraph.attributes.set("fontname", deg::deg_debug_graphviz_fontname);
+ digraph.attributes.set("label", label);
+ digraph.attributes.set("splines", "ortho");
+ digraph.attributes.set("overlap", "scalexy");
deg::deg_debug_graphviz_graph_nodes(ctx, deg_graph);
deg::deg_debug_graphviz_graph_relations(ctx, deg_graph);
deg::deg_debug_graphviz_legend(ctx);
- deg::deg_debug_fprintf(ctx, "}" NL);
+ std::string dot_string = digraph.to_dot_string();
+ fprintf(f, "%s", dot_string.c_str());
}
-
-#undef NL
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
index 515b53297b9..16bdc2d6115 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
@@ -83,7 +83,7 @@ string gnuplotify_id_code(const string &name)
string gnuplotify_name(const string &name)
{
- string result = "";
+ string result;
const int length = name.length();
for (int i = 0; i < length; i++) {
const char ch = name[i];
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index c11d051e663..fb933cb38f3 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -43,12 +43,11 @@
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_debug.h"
-#include "builder/deg_builder.h"
-#include "builder/deg_builder_cache.h"
-#include "builder/deg_builder_cycle.h"
-#include "builder/deg_builder_nodes.h"
#include "builder/deg_builder_relations.h"
-#include "builder/deg_builder_transitive.h"
+#include "builder/pipeline_compositor.h"
+#include "builder/pipeline_from_ids.h"
+#include "builder/pipeline_render.h"
+#include "builder/pipeline_view_layer.h"
#include "intern/debug/deg_debug.h"
@@ -209,65 +208,14 @@ struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle)
/* ******************** */
/* Graph Building API's */
-static void graph_build_finalize_common(deg::Depsgraph *deg_graph, Main *bmain)
-{
- /* Detect and solve cycles. */
- deg::deg_graph_detect_cycles(deg_graph);
- /* Simplify the graph by removing redundant relations (to optimize
- * traversal later). */
- /* TODO: it would be useful to have an option to disable this in cases where
- * it is causing trouble. */
- if (G.debug_value == 799) {
- deg::deg_graph_transitive_reduction(deg_graph);
- }
- /* Store pointers to commonly used valuated datablocks. */
- deg_graph->scene_cow = (Scene *)deg_graph->get_cow_id(&deg_graph->scene->id);
- /* Flush visibility layer and re-schedule nodes for update. */
- deg::deg_graph_build_finalize(bmain, deg_graph);
- DEG_graph_on_visible_update(bmain, reinterpret_cast<::Depsgraph *>(deg_graph), false);
-#if 0
- if (!DEG_debug_consistency_check(deg_graph)) {
- printf("Consistency validation failed, ABORTING!\n");
- abort();
- }
-#endif
- /* Relations are up to date. */
- deg_graph->need_update = false;
-}
-
/* Build depsgraph for the given scene layer, and dump results in given graph container. */
void DEG_graph_build_from_view_layer(Depsgraph *graph,
Main *bmain,
Scene *scene,
ViewLayer *view_layer)
{
- double start_time = 0.0;
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- start_time = PIL_check_seconds_timer();
- }
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- /* Perform sanity checks. */
- BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1);
- BLI_assert(deg_graph->scene == scene);
- BLI_assert(deg_graph->view_layer == view_layer);
- deg::DepsgraphBuilderCache builder_cache;
- /* Generate all the nodes in the graph first */
- deg::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache);
- node_builder.begin_build();
- node_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY);
- node_builder.end_build();
- /* Hook up relationships between operations - to determine evaluation order. */
- deg::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache);
- relation_builder.begin_build();
- relation_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY);
- relation_builder.build_copy_on_write_relations();
- relation_builder.build_driver_relations();
- /* Finalize building. */
- graph_build_finalize_common(deg_graph, bmain);
- /* Finish statistics. */
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
- }
+ deg::ViewLayerBuilderPipeline builder(graph, bmain, scene, view_layer);
+ builder.build();
}
void DEG_graph_build_for_render_pipeline(Depsgraph *graph,
@@ -275,170 +223,17 @@ void DEG_graph_build_for_render_pipeline(Depsgraph *graph,
Scene *scene,
ViewLayer *view_layer)
{
- double start_time = 0.0;
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- start_time = PIL_check_seconds_timer();
- }
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- /* Perform sanity checks. */
- BLI_assert(deg_graph->scene == scene);
- deg_graph->is_render_pipeline_depsgraph = true;
- deg::DepsgraphBuilderCache builder_cache;
- /* Generate all the nodes in the graph first */
- deg::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache);
- node_builder.begin_build();
- node_builder.build_scene_render(scene, view_layer);
- node_builder.end_build();
- /* Hook up relationships between operations - to determine evaluation
- * order. */
- deg::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache);
- relation_builder.begin_build();
- relation_builder.build_scene_render(scene, view_layer);
- relation_builder.build_copy_on_write_relations();
- relation_builder.build_driver_relations();
- /* Finalize building. */
- graph_build_finalize_common(deg_graph, bmain);
- /* Finish statistics. */
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
- }
+ deg::RenderBuilderPipeline builder(graph, bmain, scene, view_layer);
+ builder.build();
}
void DEG_graph_build_for_compositor_preview(
Depsgraph *graph, Main *bmain, Scene *scene, struct ViewLayer *view_layer, bNodeTree *nodetree)
{
- double start_time = 0.0;
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- start_time = PIL_check_seconds_timer();
- }
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- /* Perform sanity checks. */
- BLI_assert(deg_graph->scene == scene);
- deg_graph->is_render_pipeline_depsgraph = true;
- deg::DepsgraphBuilderCache builder_cache;
- /* Generate all the nodes in the graph first */
- deg::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache);
- node_builder.begin_build();
- node_builder.build_scene_render(scene, view_layer);
- node_builder.build_nodetree(nodetree);
- node_builder.end_build();
- /* Hook up relationships between operations - to determine evaluation
- * order. */
- deg::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache);
- relation_builder.begin_build();
- relation_builder.build_scene_render(scene, view_layer);
- relation_builder.build_nodetree(nodetree);
- relation_builder.build_copy_on_write_relations();
- relation_builder.build_driver_relations();
- /* Finalize building. */
- graph_build_finalize_common(deg_graph, bmain);
- /* Finish statistics. */
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
- }
+ deg::CompositorBuilderPipeline builder(graph, bmain, scene, view_layer, nodetree);
+ builder.build();
}
-/* Optimized builders for dependency graph built from a given set of IDs.
- *
- * General notes:
- *
- * - We pull in all bases if their objects are in the set of IDs. This allows to have proper
- * visibility and other flags assigned to the objects.
- * All other bases (the ones which points to object which is outside of the set of IDs) are
- * completely ignored.
- *
- * - Proxy groups pointing to objects which are outside of the IDs set are also ignored.
- * This way we avoid high-poly character body pulled into the dependency graph when it's coming
- * from a library into an animation file and the dependency graph constructed for a proxy rig. */
-
-namespace blender {
-namespace deg {
-namespace {
-
-class DepsgraphFromIDsFilter {
- public:
- DepsgraphFromIDsFilter(ID **ids, const int num_ids)
- {
- for (int i = 0; i < num_ids; ++i) {
- ids_.add(ids[i]);
- }
- }
-
- bool contains(ID *id)
- {
- return ids_.contains(id);
- }
-
- protected:
- Set<ID *> ids_;
-};
-
-class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
- public:
- DepsgraphFromIDsNodeBuilder(
- Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
- : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids, num_ids)
- {
- }
-
- virtual bool need_pull_base_into_graph(Base *base) override
- {
- if (!filter_.contains(&base->object->id)) {
- return false;
- }
- return DepsgraphNodeBuilder::need_pull_base_into_graph(base);
- }
-
- virtual void build_object_proxy_group(Object *object, bool is_visible) override
- {
- if (object->proxy_group == nullptr) {
- return;
- }
- if (!filter_.contains(&object->proxy_group->id)) {
- return;
- }
- DepsgraphNodeBuilder::build_object_proxy_group(object, is_visible);
- }
-
- protected:
- DepsgraphFromIDsFilter filter_;
-};
-
-class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
- public:
- DepsgraphFromIDsRelationBuilder(
- Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
- : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids, num_ids)
- {
- }
-
- virtual bool need_pull_base_into_graph(Base *base) override
- {
- if (!filter_.contains(&base->object->id)) {
- return false;
- }
- return DepsgraphRelationBuilder::need_pull_base_into_graph(base);
- }
-
- virtual void build_object_proxy_group(Object *object) override
- {
- if (object->proxy_group == nullptr) {
- return;
- }
- if (!filter_.contains(&object->proxy_group->id)) {
- return;
- }
- DepsgraphRelationBuilder::build_object_proxy_group(object);
- }
-
- protected:
- DepsgraphFromIDsFilter filter_;
-};
-
-} // namespace
-} // namespace deg
-} // namespace blender
-
void DEG_graph_build_from_ids(Depsgraph *graph,
Main *bmain,
Scene *scene,
@@ -446,40 +241,8 @@ void DEG_graph_build_from_ids(Depsgraph *graph,
ID **ids,
const int num_ids)
{
- double start_time = 0.0;
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- start_time = PIL_check_seconds_timer();
- }
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- /* Perform sanity checks. */
- BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1);
- BLI_assert(deg_graph->scene == scene);
- BLI_assert(deg_graph->view_layer == view_layer);
- deg::DepsgraphBuilderCache builder_cache;
- /* Generate all the nodes in the graph first */
- deg::DepsgraphFromIDsNodeBuilder node_builder(bmain, deg_graph, &builder_cache, ids, num_ids);
- node_builder.begin_build();
- node_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY);
- for (int i = 0; i < num_ids; ++i) {
- node_builder.build_id(ids[i]);
- }
- node_builder.end_build();
- /* Hook up relationships between operations - to determine evaluation order. */
- deg::DepsgraphFromIDsRelationBuilder relation_builder(
- bmain, deg_graph, &builder_cache, ids, num_ids);
- relation_builder.begin_build();
- relation_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY);
- for (int i = 0; i < num_ids; ++i) {
- relation_builder.build_id(ids[i]);
- }
- relation_builder.build_copy_on_write_relations();
- relation_builder.build_driver_relations();
- /* Finalize building. */
- graph_build_finalize_common(deg_graph, bmain);
- /* Finish statistics. */
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
- }
+ deg::FromIDsBuilderPipeline builder(graph, bmain, scene, view_layer, ids, num_ids);
+ builder.build();
}
/* Tag graph relations for update. */
diff --git a/source/blender/depsgraph/intern/depsgraph_registry.cc b/source/blender/depsgraph/intern/depsgraph_registry.cc
index 6bfd2e881cc..623702ee3ae 100644
--- a/source/blender/depsgraph/intern/depsgraph_registry.cc
+++ b/source/blender/depsgraph/intern/depsgraph_registry.cc
@@ -30,29 +30,35 @@
namespace blender {
namespace deg {
-static Map<Main *, VectorSet<Depsgraph *>> g_graph_registry;
+using GraphRegistry = Map<Main *, VectorSet<Depsgraph *>>;
+static GraphRegistry &get_graph_registry()
+{
+ static GraphRegistry graph_registry;
+ return graph_registry;
+}
void register_graph(Depsgraph *depsgraph)
{
Main *bmain = depsgraph->bmain;
- g_graph_registry.lookup_or_add_default(bmain).add_new(depsgraph);
+ get_graph_registry().lookup_or_add_default(bmain).add_new(depsgraph);
}
void unregister_graph(Depsgraph *depsgraph)
{
Main *bmain = depsgraph->bmain;
- VectorSet<Depsgraph *> &graphs = g_graph_registry.lookup(bmain);
+ GraphRegistry &graph_registry = get_graph_registry();
+ VectorSet<Depsgraph *> &graphs = graph_registry.lookup(bmain);
graphs.remove(depsgraph);
// If this was the last depsgraph associated with the main, remove the main entry as well.
if (graphs.is_empty()) {
- g_graph_registry.remove(bmain);
+ graph_registry.remove(bmain);
}
}
Span<Depsgraph *> get_all_registered_graphs(Main *bmain)
{
- VectorSet<Depsgraph *> *graphs = g_graph_registry.lookup_ptr(bmain);
+ VectorSet<Depsgraph *> *graphs = get_graph_registry().lookup_ptr(bmain);
if (graphs != nullptr) {
return *graphs;
}
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 848275eb899..7c201de66f2 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -48,11 +48,8 @@
#include "BKE_idtype.h"
#include "BKE_node.h"
#include "BKE_scene.h"
-#include "BKE_workspace.h"
-
-#define new new_
#include "BKE_screen.h"
-#undef new
+#include "BKE_workspace.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_debug.h"
@@ -432,7 +429,7 @@ string stringify_update_bitfield(int flag)
if (flag == 0) {
return "LEGACY_0";
}
- string result = "";
+ string result;
int current_flag = flag;
/* Special cases to avoid ALL flags form being split into
* individual bits. */
@@ -786,6 +783,7 @@ void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
DEG_graph_id_type_tag(depsgraph, ID_LA);
DEG_graph_id_type_tag(depsgraph, ID_WO);
DEG_graph_id_type_tag(depsgraph, ID_SCE);
+ DEG_graph_id_type_tag(depsgraph, ID_SIM);
}
const int id_type_index = BKE_idtype_idcode_to_index(id_type);
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
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 38350d50da6..89df41944e5 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
@@ -120,6 +120,7 @@ union NestedIDHackTempStorage {
Scene scene;
Tex tex;
World world;
+ Simulation simulation;
};
/* Set nested owned ID pointers to nullptr. */
@@ -137,6 +138,7 @@ void nested_id_hack_discard_pointers(ID *id_cow)
SPECIAL_CASE(ID_MA, Material, nodetree)
SPECIAL_CASE(ID_TE, Tex, nodetree)
SPECIAL_CASE(ID_WO, World, nodetree)
+ SPECIAL_CASE(ID_SIM, Simulation, nodetree)
SPECIAL_CASE(ID_CU, Curve, key)
SPECIAL_CASE(ID_LT, Lattice, key)
@@ -185,6 +187,7 @@ const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage
SPECIAL_CASE(ID_MA, Material, nodetree, material)
SPECIAL_CASE(ID_TE, Tex, nodetree, tex)
SPECIAL_CASE(ID_WO, World, nodetree, world)
+ SPECIAL_CASE(ID_SIM, Simulation, nodetree, simulation)
SPECIAL_CASE(ID_CU, Curve, key, curve)
SPECIAL_CASE(ID_LT, Lattice, key, lattice)
@@ -224,6 +227,7 @@ void nested_id_hack_restore_pointers(const ID *old_id, ID *new_id)
SPECIAL_CASE(ID_SCE, Scene, nodetree)
SPECIAL_CASE(ID_TE, Tex, nodetree)
SPECIAL_CASE(ID_WO, World, nodetree)
+ SPECIAL_CASE(ID_SIM, Simulation, nodetree)
SPECIAL_CASE(ID_CU, Curve, key)
SPECIAL_CASE(ID_LT, Lattice, key)
@@ -261,6 +265,7 @@ void ntree_hack_remap_pointers(const Depsgraph *depsgraph, ID *id_cow)
SPECIAL_CASE(ID_SCE, Scene, nodetree, bNodeTree)
SPECIAL_CASE(ID_TE, Tex, nodetree, bNodeTree)
SPECIAL_CASE(ID_WO, World, nodetree, bNodeTree)
+ SPECIAL_CASE(ID_SIM, Simulation, nodetree, bNodeTree)
SPECIAL_CASE(ID_CU, Curve, key, Key)
SPECIAL_CASE(ID_LT, Lattice, key, Key)
@@ -283,6 +288,14 @@ bool id_copy_inplace_no_main(const ID *id, ID *newid)
{
const ID *id_for_copy = id;
+ if (G.debug & G_DEBUG_DEPSGRAPH_UUID) {
+ const ID_Type id_type = GS(id_for_copy->name);
+ if (id_type == ID_OB) {
+ const Object *object = reinterpret_cast<const Object *>(id_for_copy);
+ BKE_pose_check_uuids_unique_and_report(object->pose);
+ }
+ }
+
#ifdef NESTED_ID_NASTY_WORKAROUND
NestedIDHackTempStorage id_hack_storage;
id_for_copy = nested_id_hack_get_discarded_pointers(&id_hack_storage, id);
@@ -306,6 +319,10 @@ bool scene_copy_inplace_no_main(const Scene *scene, Scene *new_scene)
{
const ID *id_for_copy = &scene->id;
+ if (G.debug & G_DEBUG_DEPSGRAPH_UUID) {
+ BKE_sequencer_check_uuids_unique_and_report(scene);
+ }
+
#ifdef NESTED_ID_NASTY_WORKAROUND
NestedIDHackTempStorage id_hack_storage;
id_for_copy = nested_id_hack_get_discarded_pointers(&id_hack_storage, &scene->id);
@@ -476,25 +493,6 @@ void scene_setup_view_layers_after_remap(const Depsgraph *depsgraph,
* Still not an excuse to have those. */
}
-void update_sequence_orig_pointers(const ListBase *sequences_orig, ListBase *sequences_cow)
-{
- Sequence *sequence_orig = reinterpret_cast<Sequence *>(sequences_orig->first);
- Sequence *sequence_cow = reinterpret_cast<Sequence *>(sequences_cow->first);
- while (sequence_orig != nullptr) {
- update_sequence_orig_pointers(&sequence_orig->seqbase, &sequence_cow->seqbase);
- sequence_cow->orig_sequence = sequence_orig;
- sequence_cow = sequence_cow->next;
- sequence_orig = sequence_orig->next;
- }
-}
-
-void update_scene_orig_pointers(const Scene *scene_orig, Scene *scene_cow)
-{
- if (scene_orig->ed != nullptr) {
- update_sequence_orig_pointers(&scene_orig->ed->seqbase, &scene_cow->ed->seqbase);
- }
-}
-
/* Check whether given ID is expanded or still a shallow copy. */
inline bool check_datablock_expanded(const ID *id_cow)
{
@@ -711,13 +709,6 @@ void update_modifiers_orig_pointers(const Object *object_orig, Object *object_co
&object_orig->modifiers, &object_cow->modifiers, &ModifierData::orig_modifier_data);
}
-void update_simulation_states_orig_pointers(const Simulation *simulation_orig,
- Simulation *simulation_cow)
-{
- update_list_orig_pointers(
- &simulation_orig->states, &simulation_cow->states, &SimulationState::orig_state);
-}
-
void update_nla_strips_orig_pointers(const ListBase *strips_orig, ListBase *strips_cow)
{
NlaStrip *strip_orig = reinterpret_cast<NlaStrip *>(strips_orig->first);
@@ -814,13 +805,6 @@ void update_id_after_copy(const Depsgraph *depsgraph,
scene_cow->toolsettings = scene_orig->toolsettings;
scene_cow->eevee.light_cache_data = scene_orig->eevee.light_cache_data;
scene_setup_view_layers_after_remap(depsgraph, id_node, reinterpret_cast<Scene *>(id_cow));
- update_scene_orig_pointers(scene_orig, scene_cow);
- break;
- }
- case ID_SIM: {
- Simulation *simulation_cow = (Simulation *)id_cow;
- const Simulation *simulation_orig = (const Simulation *)id_orig;
- update_simulation_states_orig_pointers(simulation_orig, simulation_cow);
break;
}
default:
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
index f2d9a87ca9d..934403674a9 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
@@ -41,7 +41,7 @@ bool operator==(const ModifierDataBackupID &a, const ModifierDataBackupID &b)
return a.modifier_data == b.modifier_data && a.type == b.type;
}
-uint32_t ModifierDataBackupID::hash() const
+uint64_t ModifierDataBackupID::hash() const
{
uintptr_t ptr = (uintptr_t)modifier_data;
return (ptr >> 4) ^ (uintptr_t)type;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
index dc16bdcc1b8..a5bdf2359ee 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
@@ -49,7 +49,7 @@ class ModifierDataBackupID {
friend bool operator==(const ModifierDataBackupID &a, const ModifierDataBackupID &b);
- uint32_t hash() const;
+ uint64_t hash() const;
ModifierData *modifier_data;
ModifierType type;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
index e0957a10cb1..88334e41192 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
@@ -85,11 +85,11 @@ void ObjectRuntimeBackup::backup_pose_channel_runtime_data(Object *object)
{
if (object->pose != nullptr) {
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- /* This is nullptr in Edit mode. */
- if (pchan->orig_pchan != nullptr) {
- pose_channel_runtime_data.add(pchan->orig_pchan, pchan->runtime);
- BKE_pose_channel_runtime_reset(&pchan->runtime);
- }
+ const SessionUUID &session_uuid = pchan->runtime.session_uuid;
+ BLI_assert(BLI_session_uuid_is_generated(&session_uuid));
+
+ pose_channel_runtime_data.add(session_uuid, pchan->runtime);
+ BKE_pose_channel_runtime_reset(&pchan->runtime);
}
}
}
@@ -171,13 +171,10 @@ void ObjectRuntimeBackup::restore_pose_channel_runtime_data(Object *object)
{
if (object->pose != nullptr) {
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- /* This is nullptr in Edit mode. */
- if (pchan->orig_pchan != nullptr) {
- optional<bPoseChannel_Runtime> runtime = pose_channel_runtime_data.pop_try(
- pchan->orig_pchan);
- if (runtime.has_value()) {
- pchan->runtime = *runtime;
- }
+ const SessionUUID &session_uuid = pchan->runtime.session_uuid;
+ optional<bPoseChannel_Runtime> runtime = pose_channel_runtime_data.pop_try(session_uuid);
+ if (runtime.has_value()) {
+ pchan->runtime = *runtime;
}
}
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h
index 04d7fb1bc22..a10f15634ce 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.h
@@ -24,6 +24,9 @@
#pragma once
#include "DNA_object_types.h"
+#include "DNA_session_uuid_types.h"
+
+#include "BLI_session_uuid.h"
#include "intern/eval/deg_eval_runtime_backup_modifier.h"
#include "intern/eval/deg_eval_runtime_backup_pose.h"
@@ -54,7 +57,7 @@ class ObjectRuntimeBackup {
short base_flag;
unsigned short base_local_view_bits;
ModifierRuntimeDataBackup modifier_runtime_data;
- Map<bPoseChannel *, bPoseChannel_Runtime> pose_channel_runtime_data;
+ Map<SessionUUID, bPoseChannel_Runtime> pose_channel_runtime_data;
};
} // namespace deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc
index 2780938fe05..ba7d20c0ba8 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc
@@ -26,6 +26,8 @@
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
+#include "BLI_assert.h"
+
#include "BKE_sequencer.h"
#include "BKE_sound.h"
@@ -43,7 +45,9 @@ void SequencerBackup::init_from_scene(Scene *scene)
SequenceBackup sequence_backup(depsgraph);
sequence_backup.init_from_sequence(sequence);
if (!sequence_backup.isEmpty()) {
- sequences_backup.add(sequence->orig_sequence, sequence_backup);
+ const SessionUUID &session_uuid = sequence->runtime.session_uuid;
+ BLI_assert(BLI_session_uuid_is_generated(&session_uuid));
+ sequences_backup.add(session_uuid, sequence_backup);
}
}
SEQ_END;
@@ -53,7 +57,9 @@ void SequencerBackup::restore_to_scene(Scene *scene)
{
Sequence *sequence;
SEQ_BEGIN (scene->ed, sequence) {
- SequenceBackup *sequence_backup = sequences_backup.lookup_ptr(sequence->orig_sequence);
+ const SessionUUID &session_uuid = sequence->runtime.session_uuid;
+ BLI_assert(BLI_session_uuid_is_generated(&session_uuid));
+ SequenceBackup *sequence_backup = sequences_backup.lookup_ptr(session_uuid);
if (sequence_backup != nullptr) {
sequence_backup->restore_to_sequence(sequence);
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h
index 9fe38ec270c..4419238da32 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.h
@@ -23,6 +23,10 @@
#pragma once
+#include "DNA_session_uuid_types.h"
+
+#include "BLI_session_uuid.h"
+
#include "intern/depsgraph_type.h"
#include "intern/eval/deg_eval_runtime_backup_sequence.h"
@@ -43,7 +47,7 @@ class SequencerBackup {
const Depsgraph *depsgraph;
- Map<Sequence *, SequenceBackup> sequences_backup;
+ Map<SessionUUID, SequenceBackup> sequences_backup;
};
} // namespace deg
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc
index 490598af8f9..cd82b7be050 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_component.cc
@@ -72,7 +72,7 @@ bool ComponentNode::OperationIDKey::operator==(const OperationIDKey &other) cons
return (opcode == other.opcode) && (STREQ(name, other.name)) && (name_tag == other.name_tag);
}
-uint32_t ComponentNode::OperationIDKey::hash() const
+uint64_t ComponentNode::OperationIDKey::hash() const
{
const int opcode_as_int = static_cast<int>(opcode);
return BLI_ghashutil_combine_hash(
@@ -98,9 +98,7 @@ void ComponentNode::init(const ID * /*id*/, const char * /*subdata*/)
ComponentNode::~ComponentNode()
{
clear_operations();
- if (operations_map != nullptr) {
- delete operations_map;
- }
+ delete operations_map;
}
string ComponentNode::identifier() const
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.h b/source/blender/depsgraph/intern/node/deg_node_component.h
index 3757a1dea5b..06582c88d8b 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.h
+++ b/source/blender/depsgraph/intern/node/deg_node_component.h
@@ -54,7 +54,7 @@ struct ComponentNode : public Node {
string identifier() const;
bool operator==(const OperationIDKey &other) const;
- uint32_t hash() const;
+ uint64_t hash() const;
};
/* Typedef for container of operations */
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc
index d0c23f326ce..8d19949adc8 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_id.cc
@@ -67,7 +67,7 @@ bool IDNode::ComponentIDKey::operator==(const ComponentIDKey &other) const
return type == other.type && STREQ(name, other.name);
}
-uint32_t IDNode::ComponentIDKey::hash() const
+uint64_t IDNode::ComponentIDKey::hash() const
{
const int type_as_int = static_cast<int>(type);
return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(type_as_int),
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h
index 9bd6130bbdc..04a9006ac10 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.h
+++ b/source/blender/depsgraph/intern/node/deg_node_id.h
@@ -51,7 +51,7 @@ const char *linkedStateAsString(eDepsNode_LinkedState_Type linked_state);
struct IDNode : public Node {
struct ComponentIDKey {
ComponentIDKey(NodeType type, const char *name = "");
- uint32_t hash() const;
+ uint64_t hash() const;
bool operator==(const ComponentIDKey &other) const;
NodeType type;
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc
index 680e7757ebb..a32a43e2905 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc
@@ -61,6 +61,8 @@ const char *operationCodeAsString(OperationCode opcode)
/* Scene related. */
case OperationCode::SCENE_EVAL:
return "SCENE_EVAL";
+ case OperationCode::AUDIO_ENTRY:
+ return "AUDIO_ENTRY";
case OperationCode::AUDIO_VOLUME:
return "AUDIO_VOLUME";
/* Object related. */
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h
index 87168fc3659..52b6c9a753b 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.h
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.h
@@ -61,6 +61,7 @@ enum class OperationCode {
/* Scene related. ------------------------------------------------------- */
SCENE_EVAL,
+ AUDIO_ENTRY,
AUDIO_VOLUME,
/* Object related. ------------------------------------------------------ */
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 1ddae11999b..f85b03dc517 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -64,6 +64,7 @@ set(SRC
intern/draw_color_management.c
intern/draw_common.c
intern/draw_debug.c
+ intern/draw_fluid.c
intern/draw_hair.c
intern/draw_instance_data.c
intern/draw_manager.c
@@ -143,12 +144,12 @@ set(SRC
engines/overlay/overlay_outline.c
engines/overlay/overlay_paint.c
engines/overlay/overlay_particle.c
- engines/overlay/overlay_pointcloud.c
engines/overlay/overlay_sculpt.c
engines/overlay/overlay_shader.c
engines/overlay/overlay_wireframe.c
DRW_engine.h
+ DRW_engine_types.h
DRW_select_buffer.h
intern/DRW_render.h
intern/draw_cache.h
@@ -186,11 +187,10 @@ set(LIB
)
data_to_c_simple(engines/eevee/shaders/ambient_occlusion_lib.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/concentric_samples_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/closure_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/common_uniforms_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/common_utiltex_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lights_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl SRC)
@@ -205,8 +205,8 @@ data_to_c_simple(engines/eevee/shaders/lightprobe_grid_display_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_grid_fill_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_display_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_display_vert.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/lookdev_world_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/closure_lit_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_bloom_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
@@ -230,7 +230,6 @@ data_to_c_simple(engines/eevee/shaders/object_motion_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_accum_frag.glsl SRC)
-
data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
@@ -241,9 +240,14 @@ data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/cubemap_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/renderpass_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/surface_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/surface_geom.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/surface_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/surface_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/update_noise_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_accum_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_lib.glsl SRC)
@@ -271,6 +275,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_material_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_merge_infront_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_prepass_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_prepass_hair_vert.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_prepass_vert.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_shader_interface_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_shadow_caps_geom.glsl SRC)
@@ -285,8 +290,11 @@ data_to_c_simple(engines/workbench/shaders/workbench_world_light_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_colormanagement_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_globals_lib.glsl SRC)
+data_to_c_simple(intern/shaders/common_pointcloud_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_hair_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_hair_refine_vert.glsl SRC)
+data_to_c_simple(intern/shaders/common_math_lib.glsl SRC)
+data_to_c_simple(intern/shaders/common_math_geom_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_view_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_fxaa_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_smaa_lib.glsl SRC)
@@ -386,8 +394,6 @@ data_to_c_simple(engines/overlay/shaders/paint_weight_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/paint_wire_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/particle_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/particle_frag.glsl SRC)
-data_to_c_simple(engines/overlay/shaders/pointcloud_vert.glsl SRC)
-data_to_c_simple(engines/overlay/shaders/pointcloud_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/sculpt_mask_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/sculpt_mask_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/volume_velocity_vert.glsl SRC)
@@ -398,6 +404,13 @@ data_to_c_simple(engines/overlay/shaders/xray_fade_frag.glsl SRC)
list(APPEND INC
)
+if(WITH_MOD_FLUID)
+ list(APPEND INC
+ ../../../intern/mantaflow/extern
+ )
+ add_definitions(-DWITH_FLUID)
+endif()
+
if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
endif()
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 6c835c6d7ae..6db3bb39643 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRW_ENGINE_H__
-#define __DRW_ENGINE_H__
+#pragma once
#include "BLI_sys_types.h" /* for bool */
@@ -43,6 +42,7 @@ struct GPUViewport;
struct ID;
struct Main;
struct Object;
+struct Render;
struct RenderEngine;
struct RenderEngineType;
struct Scene;
@@ -137,6 +137,9 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
struct DRWInstanceDataList *DRW_instance_data_list_create(void);
void DRW_instance_data_list_free(struct DRWInstanceDataList *idatalist);
+void DRW_render_context_enable(struct Render *render);
+void DRW_render_context_disable(struct Render *render);
+
void DRW_opengl_context_create(void);
void DRW_opengl_context_destroy(void);
void DRW_opengl_context_enable(void);
@@ -170,5 +173,3 @@ void DRW_drawdata_free(struct ID *id);
#ifdef __cplusplus
}
#endif
-
-#endif /* __DRW_ENGINE_H__ */
diff --git a/source/blender/draw/DRW_engine_types.h b/source/blender/draw/DRW_engine_types.h
index d31bab5a1b5..807f654f559 100644
--- a/source/blender/draw/DRW_engine_types.h
+++ b/source/blender/draw/DRW_engine_types.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRW_ENGINE_TYPES_H__
-#define __DRW_ENGINE_TYPES_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -50,5 +49,3 @@ typedef struct DefaultTextureList {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DRW_ENGINE_H__ */
diff --git a/source/blender/draw/DRW_select_buffer.h b/source/blender/draw/DRW_select_buffer.h
index 66dee3a9aa9..43d4005c3a9 100644
--- a/source/blender/draw/DRW_select_buffer.h
+++ b/source/blender/draw/DRW_select_buffer.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRW_SELECT_BUFFER_H__
-#define __DRW_SELECT_BUFFER_H__
+#pragma once
#include "BLI_sys_types.h" /* for bool and uint */
@@ -126,5 +125,3 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph,
void DRW_select_buffer_context_create(struct Base **bases,
const uint bases_len,
short select_mode);
-
-#endif /* __DRW_SELECT_BUFFER_H__ */
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index 0dd3cc14234..94c380b3b50 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -165,7 +165,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
return;
}
- bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
+ bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
const DRWContextState *draw_ctx = DRW_context_state_get();
if (ob != draw_ctx->object_edit) {
diff --git a/source/blender/draw/engines/basic/basic_engine.h b/source/blender/draw/engines/basic/basic_engine.h
index d17f1c24c37..8ace6f23cdc 100644
--- a/source/blender/draw/engines/basic/basic_engine.h
+++ b/source/blender/draw/engines/basic/basic_engine.h
@@ -20,9 +20,6 @@
* \ingroup draw_engine
*/
-#ifndef __BASIC_ENGINE_H__
-#define __BASIC_ENGINE_H__
+#pragma once
extern DrawEngineType draw_engine_basic_type;
-
-#endif /* __BASIC_ENGINE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 87948f403a0..c475e5287c2 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -28,6 +28,7 @@
#include "BLI_memblock.h"
#include "BKE_duplilist.h"
+#include "BKE_modifier.h"
#include "DEG_depsgraph_query.h"
@@ -147,28 +148,46 @@ EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *
return ob_step;
}
-EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb,
- Object *ob,
- bool hair)
+static EEVEE_GeometryMotionData *motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb,
+ void *key,
+ bool hair)
{
if (mb->geom == NULL) {
return NULL;
}
-
- /* Use original data as key to ensure matching accross update. */
- Object *ob_orig = DEG_get_original_object(ob);
-
- void *key = (char *)ob_orig->data + hair;
+ key = (char *)key + (int)hair;
EEVEE_GeometryMotionData *geom_step = BLI_ghash_lookup(mb->geom, key);
if (geom_step == NULL) {
geom_step = MEM_callocN(sizeof(EEVEE_GeometryMotionData), __func__);
- geom_step->type = (hair) ? EEVEE_HAIR_GEOM_MOTION_DATA : EEVEE_MESH_GEOM_MOTION_DATA;
+ geom_step->type = hair ? EEVEE_HAIR_GEOM_MOTION_DATA : EEVEE_MESH_GEOM_MOTION_DATA;
BLI_ghash_insert(mb->geom, key, geom_step);
}
-
return geom_step;
}
+EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb, Object *ob)
+{
+ /* Use original data as key to ensure matching accross update. */
+ return motion_blur_geometry_data_get(mb, DEG_get_original_object(ob)->data, false);
+}
+
+EEVEE_GeometryMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_MotionBlurData *mb,
+ Object *ob,
+ ModifierData *md)
+{
+ void *key;
+ if (md) {
+ /* Particle system. */
+ key = BKE_modifier_get_original(md);
+ }
+ else {
+ /* Hair object. */
+ key = DEG_get_original_object(ob)->data;
+ }
+
+ return motion_blur_geometry_data_get(mb, key, true);
+}
+
/* View Layer data. */
void EEVEE_view_layer_data_free(void *storage)
@@ -218,6 +237,11 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
return (EEVEE_ViewLayerData *)DRW_view_layer_engine_data_get(&draw_engine_eevee_type);
}
+static void eevee_view_layer_init(EEVEE_ViewLayerData *sldata)
+{
+ sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data), NULL);
+}
+
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer)
{
EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure_ex(
@@ -225,6 +249,7 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_laye
if (*sldata == NULL) {
*sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData");
+ eevee_view_layer_init(*sldata);
}
return *sldata;
@@ -237,6 +262,7 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void)
if (*sldata == NULL) {
*sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData");
+ eevee_view_layer_init(*sldata);
}
return *sldata;
diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
index 4a3cc36ddef..05cd6426911 100644
--- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c
+++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
@@ -54,24 +54,30 @@ extern char datatoc_common_view_lib_glsl[];
static void eevee_create_shader_depth_of_field(const bool use_alpha)
{
- char *frag = BLI_string_joinN(datatoc_common_view_lib_glsl, datatoc_effect_dof_frag_glsl);
- e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen(
- frag,
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_dof_frag_glsl,
+ lib,
use_alpha ? "#define USE_ALPHA_DOF\n"
"#define STEP_DOWNSAMPLE\n" :
"#define STEP_DOWNSAMPLE\n");
- e_data.dof_scatter_sh[use_alpha] = DRW_shader_create(datatoc_effect_dof_vert_glsl,
- NULL,
- frag,
- use_alpha ? "#define USE_ALPHA_DOF\n"
- "#define STEP_SCATTER\n" :
- "#define STEP_SCATTER\n");
- e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen(frag,
- use_alpha ?
- "#define USE_ALPHA_DOF\n"
- "#define STEP_RESOLVE\n" :
- "#define STEP_RESOLVE\n");
- MEM_freeN(frag);
+
+ e_data.dof_scatter_sh[use_alpha] = DRW_shader_create_with_shaderlib(
+ datatoc_effect_dof_vert_glsl,
+ NULL,
+ datatoc_effect_dof_frag_glsl,
+ lib,
+ use_alpha ? "#define USE_ALPHA_DOF\n"
+ "#define STEP_SCATTER\n" :
+ "#define STEP_SCATTER\n");
+
+ e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_dof_frag_glsl,
+ lib,
+ use_alpha ? "#define USE_ALPHA_DOF\n"
+ "#define STEP_RESOLVE\n" :
+ "#define STEP_RESOLVE\n");
}
int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata),
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 8c48ae65d9b..f6e74c6822c 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -486,7 +486,7 @@ void EEVEE_downsample_buffer(EEVEE_Data *vedata, GPUTexture *texture_src, int le
}
/**
- * Simple down-sampling algorithm for cubemap. Reconstruct mip chain up to mip level.
+ * Simple down-sampling algorithm for cube-map. Reconstruct mip chain up to mip level.
*/
void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, GPUTexture *texture_src, int level)
{
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index bac96ab1079..d77c6600026 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -32,6 +32,8 @@
#include "DNA_world_types.h"
+#include "IMB_imbuf.h"
+
#include "eevee_private.h"
#include "eevee_engine.h" /* own include */
@@ -79,11 +81,6 @@ static void eevee_engine_init(void *ved)
GPU_framebuffer_ensure_config(&fbl->main_color_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->color)});
- if (sldata->common_ubo == NULL) {
- sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
- &sldata->common_data);
- }
-
/* `EEVEE_renderpasses_init` will set the active render passes used by `EEVEE_effects_init`.
* `EEVEE_effects_init` needs to go second for TAA. */
EEVEE_renderpasses_init(vedata);
@@ -459,6 +456,9 @@ static void eevee_render_to_image(void *vedata,
}
EEVEE_PrivateData *g_data = ved->stl->g_data;
+ EEVEE_render_modules_init(vedata, engine, depsgraph);
+
+ int initial_frame = CFRA;
int steps = max_ii(1, scene->eevee.motion_blur_steps);
int time_steps_tot = (do_motion_blur) ? steps : 1;
g_data->render_tot_samples = divide_ceil_u(scene->eevee.taa_render_samples, time_steps_tot);
@@ -480,9 +480,10 @@ static void eevee_render_to_image(void *vedata,
}
else {
EEVEE_motion_blur_step_set(ved, MB_PREV);
- RE_engine_frame_set(engine, floorf(time_prev), fractf(time_prev));
+ DRW_render_set_time(engine, depsgraph, floorf(time_prev), fractf(time_prev));
+ EEVEE_render_modules_init(vedata, engine, depsgraph);
+ sldata = EEVEE_view_layer_data_ensure();
- EEVEE_render_view_sync(vedata, engine, depsgraph);
EEVEE_render_cache_init(sldata, vedata);
DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache);
@@ -496,9 +497,10 @@ static void eevee_render_to_image(void *vedata,
/* Next motion step. */
if (do_motion_blur_fx) {
EEVEE_motion_blur_step_set(ved, MB_NEXT);
- RE_engine_frame_set(engine, floorf(time_next), fractf(time_next));
+ DRW_render_set_time(engine, depsgraph, floorf(time_next), fractf(time_next));
+ EEVEE_render_modules_init(vedata, engine, depsgraph);
+ sldata = EEVEE_view_layer_data_ensure();
- EEVEE_render_view_sync(vedata, engine, depsgraph);
EEVEE_render_cache_init(sldata, vedata);
DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache);
@@ -512,10 +514,11 @@ static void eevee_render_to_image(void *vedata,
{
if (do_motion_blur) {
EEVEE_motion_blur_step_set(ved, MB_CURR);
- RE_engine_frame_set(engine, floorf(time_curr), fractf(time_curr));
+ DRW_render_set_time(engine, depsgraph, floorf(time_curr), fractf(time_curr));
+ EEVEE_render_modules_init(vedata, engine, depsgraph);
+ sldata = EEVEE_view_layer_data_ensure();
}
- EEVEE_render_view_sync(vedata, engine, depsgraph);
EEVEE_render_cache_init(sldata, vedata);
DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache);
@@ -558,6 +561,11 @@ static void eevee_render_to_image(void *vedata,
/* Restore original viewport size. */
DRW_render_viewport_size_set((int[2]){g_data->size_orig[0], g_data->size_orig[1]});
+
+ if (CFRA != initial_frame) {
+ /* Restore original frame number. This is because the render pipeline expects it. */
+ RE_engine_frame_set(engine, initial_frame, 0.0f);
+ }
}
static void eevee_engine_free(void)
@@ -601,7 +609,7 @@ RenderEngineType DRW_engine_viewport_eevee_type = {
NULL,
EEVEE_ENGINE,
N_("Eevee"),
- RE_INTERNAL | RE_USE_PREVIEW | RE_USE_STEREO_VIEWPORT,
+ RE_INTERNAL | RE_USE_PREVIEW | RE_USE_STEREO_VIEWPORT | RE_USE_GPU_CONTEXT,
NULL,
&DRW_render_to_image,
NULL,
diff --git a/source/blender/draw/engines/eevee/eevee_engine.h b/source/blender/draw/engines/eevee/eevee_engine.h
index b27d16aa7d8..40784e2980b 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.h
+++ b/source/blender/draw/engines/eevee/eevee_engine.h
@@ -20,9 +20,6 @@
* \ingroup DNA
*/
-#ifndef __EEVEE_ENGINE_H__
-#define __EEVEE_ENGINE_H__
+#pragma once
extern RenderEngineType DRW_engine_viewport_eevee_type;
-
-#endif /* __EEVEE_ENGINE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 78d50a02fc7..38f5536170e 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -53,9 +53,6 @@
#if defined(IRRADIANCE_SH_L2)
# define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
# define IRRADIANCE_SAMPLE_SIZE_Y 4 /* 3 in reality */
-#elif defined(IRRADIANCE_CUBEMAP)
-# define IRRADIANCE_SAMPLE_SIZE_X 8
-# define IRRADIANCE_SAMPLE_SIZE_Y 8
#elif defined(IRRADIANCE_HL2)
# define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
# define IRRADIANCE_SAMPLE_SIZE_Y 2
@@ -113,7 +110,7 @@ typedef struct EEVEE_LightBake {
float samples_ct, invsamples_ct;
/** Sampling bias during convolution step. */
float lod_factor;
- /** Max cubemap LOD to sample when convolving. */
+ /** Max cube-map LOD to sample when convolving. */
float lod_max;
/** Number of probes to render + world probe. */
int cube_len, grid_len;
@@ -121,7 +118,7 @@ typedef struct EEVEE_LightBake {
/* Irradiance grid */
/** Current probe being rendered (UBO data). */
EEVEE_LightGrid *grid;
- /** Target cubemap at MIP 0. */
+ /** Target cube-map at MIP 0. */
int irr_cube_res;
/** Size of the irradiance texture. */
int irr_size[3];
@@ -145,7 +142,7 @@ typedef struct EEVEE_LightBake {
/* Reflection probe */
/** Current probe being rendered (UBO data). */
EEVEE_LightProbe *cube;
- /** Target cubemap at MIP 0. */
+ /** Target cube-map at MIP 0. */
int ref_cube_res;
/** Index of the current cube. */
int cube_offset;
@@ -206,6 +203,21 @@ static bool eevee_lightcache_version_check(LightCache *lcache)
}
}
+static bool eevee_lightcache_can_be_saved(LightCache *lcache)
+{
+ if (lcache->grid_tx.data) {
+ if (MEM_allocN_len(lcache->grid_tx.data) >= INT_MAX) {
+ return false;
+ }
+ }
+ if (lcache->cube_tx.data) {
+ if (MEM_allocN_len(lcache->cube_tx.data) >= INT_MAX) {
+ return false;
+ }
+ }
+ return true;
+}
+
static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
{
int total_irr_samples = 0;
@@ -231,7 +243,14 @@ void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
BLI_strncpy(eevee->light_cache_info,
- TIP_("Error: Light cache is too big for your GPU to be loaded"),
+ TIP_("Error: Light cache is too big for the GPU to be loaded"),
+ sizeof(eevee->light_cache_info));
+ return;
+ }
+
+ if (lcache->flag & LIGHTCACHE_INVALID) {
+ BLI_strncpy(eevee->light_cache_info,
+ TIP_("Error: Light cache dimensions not supported by the GPU"),
sizeof(eevee->light_cache_info));
return;
}
@@ -242,6 +261,13 @@ void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
return;
}
+ if (!eevee_lightcache_can_be_saved(lcache)) {
+ BLI_strncpy(eevee->light_cache_info,
+ TIP_("Error: LightCache is too large and will not be saved to disk"),
+ sizeof(eevee->light_cache_info));
+ return;
+ }
+
char formatted_mem[15];
BLI_str_format_byte_unit(formatted_mem, eevee_lightcache_memsize_get(lcache), false);
@@ -284,7 +310,7 @@ static bool EEVEE_lightcache_validate(const LightCache *light_cache,
const int grid_len,
const int irr_size[3])
{
- if (light_cache) {
+ if (light_cache && !(light_cache->flag & LIGHTCACHE_INVALID)) {
/* See if we need the same amount of texture space. */
if ((irr_size[0] == light_cache->grid_tx.tex_size[0]) &&
(irr_size[1] == light_cache->grid_tx.tex_size[1]) &&
@@ -346,12 +372,18 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
light_cache->cube_mips = MEM_callocN(sizeof(LightCacheTexture) * light_cache->mips_len,
"LightCacheTexture");
- for (int mip = 0; mip < light_cache->mips_len; mip++) {
- GPU_texture_get_mipmap_size(
- light_cache->cube_tx.tex, mip + 1, light_cache->cube_mips[mip].tex_size);
+ if (light_cache->grid_tx.tex == NULL || light_cache->cube_tx.tex == NULL) {
+ /* We could not create the requested textures size. Stop baking and do not use the cache. */
+ light_cache->flag = LIGHTCACHE_INVALID;
}
+ else {
+ light_cache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
- light_cache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
+ for (int mip = 0; mip < light_cache->mips_len; mip++) {
+ GPU_texture_get_mipmap_size(
+ light_cache->cube_tx.tex, mip + 1, light_cache->cube_mips[mip].tex_size);
+ }
+ }
return light_cache;
}
@@ -379,6 +411,12 @@ static bool eevee_lightcache_static_load(LightCache *lcache)
0,
false,
NULL);
+
+ if (lcache->grid_tx.tex == NULL) {
+ lcache->flag |= LIGHTCACHE_NOT_USABLE;
+ return false;
+ }
+
GPU_texture_filter_mode(lcache->grid_tx.tex, true);
}
@@ -404,6 +442,11 @@ static bool eevee_lightcache_static_load(LightCache *lcache)
NULL);
}
+ if (lcache->cube_tx.tex == NULL) {
+ lcache->flag |= LIGHTCACHE_NOT_USABLE;
+ return false;
+ }
+
for (int mip = 0; mip < lcache->mips_len; mip++) {
GPU_texture_add_mipmap(
lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, mip + 1, lcache->cube_mips[mip].data);
@@ -423,6 +466,10 @@ bool EEVEE_lightcache_load(LightCache *lcache)
return false;
}
+ if (lcache->flag & (LIGHTCACHE_INVALID | LIGHTCACHE_NOT_USABLE)) {
+ return false;
+ }
+
switch (lcache->type) {
case LIGHTCACHE_TYPE_STATIC:
return eevee_lightcache_static_load(lcache);
@@ -484,6 +531,12 @@ void EEVEE_lightcache_free(LightCache *lcache)
static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
{
+ if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
+ GPU_context_main_lock();
+ DRW_opengl_context_enable();
+ return;
+ }
+
if (lbake->gl_context) {
DRW_opengl_render_context_enable(lbake->gl_context);
if (lbake->gpu_context == NULL) {
@@ -498,6 +551,12 @@ static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
{
+ if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
+ DRW_opengl_context_disable();
+ GPU_context_main_unlock();
+ return;
+ }
+
if (lbake->gl_context) {
DRW_gpu_render_context_disable(lbake->gpu_context);
DRW_opengl_render_context_disable(lbake->gl_context);
@@ -593,9 +652,7 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
if (lbake->lcache == NULL) {
lbake->lcache = EEVEE_lightcache_create(
lbake->grid_len, lbake->cube_len, lbake->ref_cube_res, lbake->vis_res, lbake->irr_size);
- lbake->lcache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE |
- LIGHTCACHE_UPDATE_GRID;
- lbake->lcache->vis_res = lbake->vis_res;
+
lbake->own_light_cache = true;
eevee->light_cache_data = lbake->lcache;
@@ -652,7 +709,7 @@ wmJob *EEVEE_lightbake_job_create(struct wmWindowManager *wm,
lbake->delay = delay;
lbake->frame = frame;
- if (lbake->gl_context == NULL) {
+ if (lbake->gl_context == NULL && !GPU_use_main_context_workaround()) {
lbake->gl_context = WM_opengl_context_create();
wm_window_reset_drawable();
}
@@ -697,7 +754,7 @@ void *EEVEE_lightbake_job_data_alloc(struct Main *bmain,
lbake->mutex = BLI_mutex_alloc();
lbake->frame = frame;
- if (run_as_job) {
+ if (run_as_job && !GPU_use_main_context_workaround()) {
lbake->gl_context = WM_opengl_context_create();
wm_window_reset_drawable();
}
@@ -804,11 +861,6 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
DRW_view_set_active(view);
}
- if (sldata->common_ubo == NULL) {
- sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
- &sldata->common_data);
- }
-
/* HACK: set txl->color but unset it before Draw Manager frees it. */
txl->color = lbake->rt_color;
int viewport_size[2] = {
@@ -969,9 +1021,8 @@ static void compute_cell_id(EEVEE_LightGrid *egrid,
if (visited_cells == cell_idx) {
return;
}
- else {
- visited_cells++;
- }
+
+ visited_cells++;
}
}
}
@@ -1272,6 +1323,17 @@ void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float
* We cannot do it in the main thread. */
eevee_lightbake_context_enable(lbake);
eevee_lightbake_create_resources(lbake);
+
+ /* Resource allocation can fail. Early exit in this case. */
+ if (lbake->lcache->flag & LIGHTCACHE_INVALID) {
+ *lbake->stop = 1;
+ *lbake->do_update = 1;
+ lbake->lcache->flag &= ~LIGHTCACHE_BAKING;
+ eevee_lightbake_context_disable(lbake);
+ eevee_lightbake_delete_resources(lbake);
+ return;
+ }
+
eevee_lightbake_create_render_target(lbake, lbake->rt_res);
eevee_lightbake_context_disable(lbake);
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.h b/source/blender/draw/engines/eevee/eevee_lightcache.h
index 0db36ce0c2e..834f0fc8a45 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.h
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.h
@@ -20,8 +20,7 @@
* \ingroup eevee
*/
-#ifndef __EEVEE_LIGHTCACHE_H__
-#define __EEVEE_LIGHTCACHE_H__
+#pragma once
#include "BLI_sys_types.h" /* for bool */
@@ -62,5 +61,3 @@ struct LightCache *EEVEE_lightcache_create(const int grid_len,
void EEVEE_lightcache_free(struct LightCache *lcache);
bool EEVEE_lightcache_load(struct LightCache *lcache);
void EEVEE_lightcache_info_update(struct SceneEEVEE *eevee);
-
-#endif /* __EEVEE_LIGHTCACHE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 71c8294d123..47a913640c7 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -23,6 +23,7 @@
#include "DRW_render.h"
#include "BLI_rand.h"
+#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "DNA_image_types.h"
@@ -161,6 +162,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
+ vedata->info[0] = '\0';
if (!e_data.hammersley) {
EEVEE_shaders_lightprobe_shaders_init();
@@ -176,11 +178,16 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
stl->g_data->light_cache = scene_eval->eevee.light_cache_data;
}
else {
+ if (scene_eval->eevee.light_cache_data &&
+ (scene_eval->eevee.light_cache_data->flag & LIGHTCACHE_NOT_USABLE)) {
+ /* Error message info. */
+ BLI_snprintf(
+ vedata->info, sizeof(vedata->info), "Error: LightCache cannot be loaded on this GPU");
+ }
+
if (!sldata->fallback_lightcache) {
#if defined(IRRADIANCE_SH_L2)
int grid_res = 4;
-#elif defined(IRRADIANCE_CUBEMAP)
- int grid_res = 8;
#elif defined(IRRADIANCE_HL2)
int grid_res = 4;
#endif
@@ -328,38 +335,28 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
{
DRW_PASS_CREATE(psl->probe_background, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
- struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = NULL;
+ EEVEE_lookdev_cache_init(vedata, sldata, psl->probe_background, pinfo, &grp);
- Scene *scene = draw_ctx->scene;
- World *wo = scene->world;
-
- /* LookDev */
- EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->probe_background, wo, pinfo);
+ if (grp == NULL) {
+ Scene *scene = draw_ctx->scene;
+ World *world = (scene->world) ? scene->world : EEVEE_world_default_get();
- if (!grp && wo) {
- struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, wo, VAR_WORLD_PROBE);
+ const int options = VAR_WORLD_BACKGROUND | VAR_WORLD_PROBE;
+ struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options);
grp = DRW_shgroup_material_create(gpumat, psl->probe_background);
DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
- /* TODO (fclem): remove those (need to clean the GLSL files). */
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
- DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
- DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
- DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
- DRW_shgroup_call(grp, geom, NULL);
}
- /* Fallback if shader fails or if not using nodetree. */
- if (grp == NULL) {
- grp = DRW_shgroup_create(EEVEE_shaders_probe_default_sh_get(), psl->probe_background);
- DRW_shgroup_uniform_vec3(grp, "color", G_draw.block.colorBackground, 1);
- DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
- DRW_shgroup_call(grp, geom, NULL);
- }
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
if (DRW_state_draw_support()) {
@@ -1114,9 +1111,6 @@ void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata,
/* NOTE : Keep in sync with load_irradiance_cell() */
#if defined(IRRADIANCE_SH_L2)
int size[2] = {3, 3};
-#elif defined(IRRADIANCE_CUBEMAP)
- int size[2] = {8, 8};
- pinfo->samples_len = 1024.0f;
#elif defined(IRRADIANCE_HL2)
int size[2] = {3, 2};
pinfo->samples_len = 1024.0f;
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index 18365d69514..403a8e2af55 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -97,19 +97,18 @@ static void eevee_lookdev_hdri_preview_init(EEVEE_Data *vedata, EEVEE_ViewLayerD
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
- DRWShadingGroup **r_grp,
DRWPass *pass,
- World *UNUSED(world),
- EEVEE_LightProbesInfo *pinfo)
+ EEVEE_LightProbesInfo *pinfo,
+ DRWShadingGroup **r_shgrp)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_PrivateData *g_data = stl->g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
- View3D *v3d = draw_ctx->v3d;
- View3DShading *shading = &v3d->shading;
- Scene *scene = draw_ctx->scene;
+ /* The view will be NULL when rendering previews. */
+ const View3D *v3d = draw_ctx->v3d;
+ const Scene *scene = draw_ctx->scene;
const bool probe_render = pinfo != NULL;
@@ -150,93 +149,91 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
}
if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) {
+ const View3DShading *shading = &v3d->shading;
StudioLight *sl = BKE_studiolight_find(shading->lookdev_light,
STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE);
- if (sl && (sl->flag & STUDIOLIGHT_TYPE_WORLD)) {
- GPUShader *shader = probe_render ? EEVEE_shaders_default_studiolight_sh_get() :
- EEVEE_shaders_background_studiolight_sh_get();
+ if (sl == NULL || (sl->flag & STUDIOLIGHT_TYPE_WORLD) == 0) {
+ return;
+ }
+
+ GPUShader *shader = probe_render ? EEVEE_shaders_studiolight_probe_sh_get() :
+ EEVEE_shaders_studiolight_background_sh_get();
- const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- int cube_res = scene_eval->eevee.gi_cubemap_resolution;
+ const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
+ int cube_res = scene_eval->eevee.gi_cubemap_resolution;
- /* If one of the component is missing we start from scratch. */
- if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
- (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) ||
- (g_data->light_cache && g_data->light_cache->ref_res != cube_res)) {
- eevee_lookdev_lightcache_delete(vedata);
- }
+ /* If one of the component is missing we start from scratch. */
+ if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
+ (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) ||
+ (g_data->light_cache && g_data->light_cache->ref_res != cube_res)) {
+ eevee_lookdev_lightcache_delete(vedata);
+ }
- if (stl->lookdev_lightcache == NULL) {
+ if (stl->lookdev_lightcache == NULL) {
#if defined(IRRADIANCE_SH_L2)
- int grid_res = 4;
-#elif defined(IRRADIANCE_CUBEMAP)
- int grid_res = 8;
+ int grid_res = 4;
#elif defined(IRRADIANCE_HL2)
- int grid_res = 4;
+ int grid_res = 4;
#endif
- stl->lookdev_lightcache = EEVEE_lightcache_create(
- 1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1});
-
- /* XXX: Fix memleak. TODO find out why. */
- MEM_SAFE_FREE(stl->lookdev_cube_mips);
-
- /* We do this to use a special light cache for lookdev.
- * This light-cache needs to be per viewport. But we need to
- * have correct freeing when the viewport is closed. So we
- * need to reference all textures to the txl and the memblocks
- * to the stl. */
- stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data;
- stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data;
- stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips;
- txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex;
- txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
- }
-
- g_data->light_cache = stl->lookdev_lightcache;
-
- DRWShadingGroup *grp = *r_grp = DRW_shgroup_create(shader, pass);
- axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z);
- DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix);
-
- if (probe_render) {
- DRW_shgroup_uniform_float_copy(
- grp, "studioLightIntensity", shading->studiolight_intensity);
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
- DRW_shgroup_uniform_texture(grp, "image", sl->equirect_radiance_gputexture);
- /* Do not fadeout when doing probe rendering, only when drawing the background */
- DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
- }
- else {
- float background_alpha = g_data->background_alpha * shading->studiolight_background;
- float studiolight_blur = powf(shading->studiolight_blur, 2.5f);
- DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha);
- DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur);
- DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
- DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
- }
-
- DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
-
- /* Do we need to recalc the lightprobes? */
- if (g_data->studiolight_index != sl->index ||
- g_data->studiolight_rot_z != shading->studiolight_rot_z ||
- g_data->studiolight_intensity != shading->studiolight_intensity ||
- g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution ||
- g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp ||
- g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) {
- stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
- g_data->studiolight_index = sl->index;
- g_data->studiolight_rot_z = shading->studiolight_rot_z;
- g_data->studiolight_intensity = shading->studiolight_intensity;
- g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution;
- g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp;
- g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality;
- }
+ stl->lookdev_lightcache = EEVEE_lightcache_create(
+ 1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1});
+
+ /* XXX: Fix memleak. TODO find out why. */
+ MEM_SAFE_FREE(stl->lookdev_cube_mips);
+
+ /* We do this to use a special light cache for lookdev.
+ * This light-cache needs to be per viewport. But we need to
+ * have correct freeing when the viewport is closed. So we
+ * need to reference all textures to the txl and the memblocks
+ * to the stl. */
+ stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data;
+ stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data;
+ stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips;
+ txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex;
+ txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
+ }
+
+ g_data->light_cache = stl->lookdev_lightcache;
+
+ DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
+ axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z);
+ DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix);
+
+ if (probe_render) {
+ /* Avoid artifact with equirectangular mapping. */
+ eGPUSamplerState state = (GPU_SAMPLER_FILTER | GPU_SAMPLER_REPEAT_S);
+ DRW_shgroup_uniform_float_copy(grp, "studioLightIntensity", shading->studiolight_intensity);
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
+ DRW_shgroup_uniform_texture_ex(grp, "studioLight", sl->equirect_radiance_gputexture, state);
+ /* Do not fadeout when doing probe rendering, only when drawing the background */
+ DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
+ }
+ else {
+ float background_alpha = g_data->background_alpha * shading->studiolight_background;
+ float studiolight_blur = powf(shading->studiolight_blur, 2.5f);
+ DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha);
+ DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur);
+ DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx);
+ }
+
+ /* Common UBOs are setup latter. */
+ *r_shgrp = grp;
+
+ /* Do we need to recalc the lightprobes? */
+ if (g_data->studiolight_index != sl->index ||
+ g_data->studiolight_rot_z != shading->studiolight_rot_z ||
+ g_data->studiolight_intensity != shading->studiolight_intensity ||
+ g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution ||
+ g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp ||
+ g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) {
+ stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
+ g_data->studiolight_index = sl->index;
+ g_data->studiolight_rot_z = shading->studiolight_rot_z;
+ g_data->studiolight_intensity = shading->studiolight_intensity;
+ g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution;
+ g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp;
+ g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality;
}
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_lut.h b/source/blender/draw/engines/eevee/eevee_lut.h
index 04049efd758..d5dbf8ce690 100644
--- a/source/blender/draw/engines/eevee/eevee_lut.h
+++ b/source/blender/draw/engines/eevee/eevee_lut.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __EEVEE_LUT_H__
-#define __EEVEE_LUT_H__
+#pragma once
extern const float ltc_mat_ggx[64 * 64 * 4];
extern const float ltc_mag_ggx[64 * 64 * 2];
@@ -30,5 +29,3 @@ extern const float bsdf_split_sum_ggx[64 * 64 * 2];
extern const float ltc_disk_integral[64 * 64];
extern const float btdf_split_sum_ggx[32][64 * 64];
extern const float blue_noise[64 * 64][4];
-
-#endif /* __EEVEE_LUT_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_lut_gen.c b/source/blender/draw/engines/eevee/eevee_lut_gen.c
index 5f20d6fbfb8..9b07a6908c3 100644
--- a/source/blender/draw/engines/eevee/eevee_lut_gen.c
+++ b/source/blender/draw/engines/eevee/eevee_lut_gen.c
@@ -31,6 +31,8 @@
#include "BLI_rand.h"
#include "BLI_string_utils.h"
+#include "eevee_private.h"
+
extern char datatoc_bsdf_lut_frag_glsl[];
extern char datatoc_btdf_lut_frag_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
@@ -45,15 +47,13 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
static float samples_len = 8192.0f;
static float inv_samples_len = 1.0f / 8192.0f;
- char *lib_str = BLI_string_joinN(datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
- struct GPUShader *sh = DRW_shader_create_with_lib(datatoc_lightprobe_vert_glsl,
- datatoc_lightprobe_geom_glsl,
- datatoc_bsdf_lut_frag_glsl,
- lib_str,
- "#define HAMMERSLEY_SIZE 8192\n"
- "#define BRDF_LUT_SIZE 64\n"
- "#define NOISE_SIZE 64\n");
+ struct GPUShader *sh = DRW_shader_create_with_shaderlib(datatoc_lightprobe_vert_glsl,
+ datatoc_lightprobe_geom_glsl,
+ datatoc_bsdf_lut_frag_glsl,
+ lib,
+ "#define HAMMERSLEY_SIZE 8192\n");
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
@@ -76,8 +76,7 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
DRW_draw_pass(pass);
float *data = MEM_mallocN(sizeof(float[3]) * w * h, "lut");
- glReadBuffer(GL_COLOR_ATTACHMENT0);
- glReadPixels(0, 0, w, h, GL_RGB, GL_FLOAT, data);
+ GPU_framebuffer_read_color(fb, 0, 0, w, h, 3, 0, GPU_DATA_FLOAT, data);
printf("{");
for (int i = 0; i < w * h * 3; i += 3) {
@@ -106,16 +105,10 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
static float a2 = 0.0f;
static float inv_samples_len = 1.0f / 8192.0f;
- char *frag_str = BLI_string_joinN(
- datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl, datatoc_btdf_lut_frag_glsl);
-
- struct GPUShader *sh = DRW_shader_create_fullscreen(frag_str,
- "#define HAMMERSLEY_SIZE 8192\n"
- "#define BRDF_LUT_SIZE 64\n"
- "#define NOISE_SIZE 64\n"
- "#define LUT_SIZE 64\n");
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
- MEM_freeN(frag_str);
+ struct GPUShader *sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_btdf_lut_frag_glsl, lib, "#define HAMMERSLEY_SIZE 8192\n");
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
@@ -195,4 +188,4 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
MEM_freeN(data);
return tex;
-} \ No newline at end of file
+}
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 8c17ecd3905..4f97fe99b27 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -56,37 +56,6 @@ static struct {
float noise_offsets[3];
} e_data = {NULL}; /* Engine data */
-extern char datatoc_lights_lib_glsl[];
-extern char datatoc_lightprobe_lib_glsl[];
-extern char datatoc_ambient_occlusion_lib_glsl[];
-extern char datatoc_prepass_frag_glsl[];
-extern char datatoc_prepass_vert_glsl[];
-extern char datatoc_default_frag_glsl[];
-extern char datatoc_default_world_frag_glsl[];
-extern char datatoc_ltc_lib_glsl[];
-extern char datatoc_bsdf_common_lib_glsl[];
-extern char datatoc_bsdf_sampling_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
-extern char datatoc_common_hair_lib_glsl[];
-extern char datatoc_common_view_lib_glsl[];
-extern char datatoc_irradiance_lib_glsl[];
-extern char datatoc_octahedron_lib_glsl[];
-extern char datatoc_cubemap_lib_glsl[];
-extern char datatoc_lit_surface_frag_glsl[];
-extern char datatoc_lit_surface_vert_glsl[];
-extern char datatoc_raytrace_lib_glsl[];
-extern char datatoc_ssr_lib_glsl[];
-extern char datatoc_shadow_vert_glsl[];
-extern char datatoc_lightprobe_geom_glsl[];
-extern char datatoc_lightprobe_vert_glsl[];
-extern char datatoc_background_vert_glsl[];
-extern char datatoc_update_noise_frag_glsl[];
-extern char datatoc_volumetric_vert_glsl[];
-extern char datatoc_volumetric_geom_glsl[];
-extern char datatoc_volumetric_frag_glsl[];
-extern char datatoc_volumetric_lib_glsl[];
-extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
-
typedef struct EeveeMaterialCache {
struct DRWShadingGroup *depth_grp;
struct DRWShadingGroup *shading_grp;
@@ -114,8 +83,8 @@ void EEVEE_material_bind_resources(DRWShadingGroup *shgrp,
GPUMaterial *gpumat,
EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- int *ssr_id,
- float *refract_depth,
+ const int *ssr_id,
+ const float *refract_depth,
bool use_ssrefraction,
bool use_alpha_blend)
{
@@ -238,46 +207,6 @@ void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const d
DRW_draw_pass(psl->update_noise_pass);
}
-void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4])
-{
- /* view vectors for the corners of the view frustum.
- * Can be used to recreate the world space position easily */
- float view_vecs[4][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},
- {-1.0f, -1.0f, 1.0f, 1.0f},
- };
-
- /* convert the view vectors to view space */
- const bool is_persp = (winmat[3][3] == 0.0f);
- for (int i = 0; i < 4; i++) {
- mul_project_m4_v3(invproj, view_vecs[i]);
- /* normalized trick see:
- * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
- if (is_persp) {
- /* Divide XY by Z. */
- mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
- }
- }
-
- /**
- * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and
- * view_vecs[1] is the vector going from the near-bottom-left corner to
- * the far-top-right corner.
- * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner
- * when Z = 1, and top-left corner if Z = 1.
- * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed)
- * distance from the near plane to the far clip plane.
- */
- copy_v4_v4(r_viewvecs[0], view_vecs[0]);
-
- /* we need to store the differences */
- r_viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
- r_viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
- r_viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
-}
-
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
EEVEE_StorageList *stl,
@@ -305,15 +234,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
}
{
- /* Update view_vecs */
- float invproj[4][4], winmat[4][4];
- DRW_view_winmat_get(NULL, winmat, false);
- DRW_view_winmat_get(NULL, invproj, true);
-
- EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
- }
-
- {
/* Update noise Framebuffer. */
GPU_framebuffer_ensure_config(
&fbl->update_noise_fb,
@@ -391,39 +311,28 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
DRW_PASS_CREATE(psl->background_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
- struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = NULL;
+ EEVEE_lookdev_cache_init(vedata, sldata, psl->background_ps, NULL, &grp);
- Scene *scene = draw_ctx->scene;
- World *wo = scene->world;
-
- EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->background_ps, wo, NULL);
+ if (grp == NULL) {
+ Scene *scene = draw_ctx->scene;
+ World *world = (scene->world) ? scene->world : EEVEE_world_default_get();
- if (!grp && wo) {
- struct GPUMaterial *gpumat = EEVEE_material_get(
- vedata, scene, NULL, wo, VAR_WORLD_BACKGROUND);
+ const int options = VAR_WORLD_BACKGROUND;
+ struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options);
grp = DRW_shgroup_material_create(gpumat, psl->background_ps);
DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
- /* TODO (fclem): remove those (need to clean the GLSL files). */
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
- DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
- DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
- DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
- DRW_shgroup_call(grp, geom, NULL);
}
- /* Fallback if shader fails or if not using nodetree. */
- if (grp == NULL) {
- GPUShader *sh = EEVEE_shaders_default_background_sh_get();
- grp = DRW_shgroup_create(sh, psl->background_ps);
- DRW_shgroup_uniform_vec3(grp, "color", G_draw.block.colorBackground, 1);
- DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
- DRW_shgroup_call(grp, geom, NULL);
- }
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
#define EEVEE_PASS_CREATE(pass, state) \
@@ -574,9 +483,8 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
if (BLI_ghash_ensure_p(pd->material_hash, key, (void ***)&emc_p)) {
return **emc_p;
}
- else {
- *emc_p = emc = BLI_memblock_alloc(sldata->material_cache);
- }
+
+ *emc_p = emc = BLI_memblock_alloc(sldata->material_cache);
material_shadow(vedata, sldata, ma, is_hair, emc);
diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c
index 1cedd334d67..d2f3a13eb7c 100644
--- a/source/blender/draw/engines/eevee/eevee_mist.c
+++ b/source/blender/draw/engines/eevee/eevee_mist.c
@@ -56,14 +56,10 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
if (e_data.mist_sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_effect_mist_frag_glsl);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
- e_data.mist_sh = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
-
- MEM_freeN(frag_str);
+ e_data.mist_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_mist_frag_glsl, lib, "#define FIRST_PASS\n");
}
/* Create FrameBuffer. */
@@ -98,11 +94,11 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
}
else {
- float near = -sldata->common_data.view_vecs[0][2];
- float range = sldata->common_data.view_vecs[1][2];
+ float near = DRW_view_near_distance_get(NULL);
+ float far = DRW_view_far_distance_get(NULL);
/* Fallback */
g_data->mist_start = near;
- g_data->mist_inv_dist = 1.0f / fabsf(range);
+ g_data->mist_inv_dist = 1.0f / fabsf(far - near);
g_data->mist_falloff = 1.0f;
}
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index 586ee780f1d..4e49136a6bc 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -37,6 +37,7 @@
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_particle_types.h"
+#include "DNA_rigidbody_types.h"
#include "DNA_screen_types.h"
#include "ED_screen.h"
@@ -68,27 +69,23 @@ extern char datatoc_common_view_lib_glsl[];
static void eevee_create_shader_motion_blur(void)
{
- e_data.motion_blur_sh = DRW_shader_create_fullscreen(
- datatoc_effect_motion_blur_frag_glsl,
- "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
- e_data.motion_blur_object_sh = DRW_shader_create_with_lib(datatoc_object_motion_vert_glsl,
- NULL,
- datatoc_object_motion_frag_glsl,
- datatoc_common_view_lib_glsl,
- NULL);
- e_data.velocity_tiles_sh = DRW_shader_create_fullscreen(
- datatoc_effect_velocity_tile_frag_glsl,
- "#define TILE_GATHER\n"
- "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
+#define TILE_SIZE_STR "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n"
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+ e_data.motion_blur_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_motion_blur_frag_glsl, lib, TILE_SIZE_STR);
+ e_data.motion_blur_object_sh = DRW_shader_create_with_shaderlib(
+ datatoc_object_motion_vert_glsl, NULL, datatoc_object_motion_frag_glsl, lib, NULL);
+
+ e_data.motion_blur_hair_sh = DRW_shader_create_with_shaderlib(datatoc_object_motion_vert_glsl,
+ NULL,
+ datatoc_object_motion_frag_glsl,
+ lib,
+ "#define HAIR\n");
+
+ e_data.velocity_tiles_sh = DRW_shader_create_fullscreen(datatoc_effect_velocity_tile_frag_glsl,
+ "#define TILE_GATHER\n" TILE_SIZE_STR);
e_data.velocity_tiles_expand_sh = DRW_shader_create_fullscreen(
- datatoc_effect_velocity_tile_frag_glsl,
- "#define TILE_EXPANSION\n"
- "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
-
- char *vert = BLI_string_joinN(datatoc_common_hair_lib_glsl, datatoc_object_motion_vert_glsl);
- e_data.motion_blur_hair_sh = DRW_shader_create_with_lib(
- vert, NULL, datatoc_object_motion_frag_glsl, datatoc_common_view_lib_glsl, "#define HAIR\n");
- MEM_freeN(vert);
+ datatoc_effect_velocity_tile_frag_glsl, "#define TILE_EXPANSION\n" TILE_SIZE_STR);
}
int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
@@ -288,8 +285,8 @@ void EEVEE_motion_blur_hair_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
/* Store transform */
DRW_hair_duplimat_get(ob, psys, md, mb_data->obmat[mb_step]);
- EEVEE_GeometryMotionData *mb_geom = EEVEE_motion_blur_geometry_data_get(
- &effects->motion_blur, ob, true);
+ EEVEE_GeometryMotionData *mb_geom = EEVEE_motion_blur_hair_data_get(
+ &effects->motion_blur, ob, md);
if (mb_step == MB_CURR) {
/* Fill missing matrices if the object was hidden in previous or next frame. */
@@ -329,10 +326,20 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
return;
}
- const bool is_dupli = (ob->base_flag & BASE_FROM_DUPLI) != 0;
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ /* active rigidbody objects only, as only those are affected by sim. */
+ const bool has_rigidbody = (rbo && (rbo->type == RBO_TYPE_ACTIVE));
+#if 0
/* For now we assume dupli objects are moving. */
- const bool object_moves = is_dupli || BKE_object_moves_in_time(ob, true);
- const bool is_deform = BKE_object_is_deform_modified(DRW_context_state_get()->scene, ob);
+ const bool is_dupli = (ob->base_flag & BASE_FROM_DUPLI) != 0;
+ const bool object_moves = is_dupli || has_rigidbody || BKE_object_moves_in_time(ob, true);
+#else
+ /* BKE_object_moves_in_time does not work in some cases. Better */
+ const bool object_moves = true;
+#endif
+ const bool is_deform = BKE_object_is_deform_modified(DRW_context_state_get()->scene, ob) ||
+ (has_rigidbody && (rbo->flag & RBO_FLAG_USE_DEFORM) != 0);
if (!(object_moves || is_deform)) {
return;
@@ -346,8 +353,8 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
/* Store transform */
copy_m4_m4(mb_data->obmat[mb_step], ob->obmat);
- EEVEE_GeometryMotionData *mb_geom = EEVEE_motion_blur_geometry_data_get(
- &effects->motion_blur, ob, false);
+ EEVEE_GeometryMotionData *mb_geom = EEVEE_motion_blur_geometry_data_get(&effects->motion_blur,
+ ob);
if (mb_step == MB_CURR) {
GPUBatch *batch = DRW_cache_object_surface_get(ob);
@@ -363,14 +370,6 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
copy_m4_m4(mb_data->obmat[MB_NEXT], mb_data->obmat[MB_CURR]);
}
- grp = DRW_shgroup_create(e_data.motion_blur_object_sh, psl->velocity_object);
- DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", mb_data->obmat[MB_PREV]);
- DRW_shgroup_uniform_mat4(grp, "currModelMatrix", mb_data->obmat[MB_CURR]);
- DRW_shgroup_uniform_mat4(grp, "nextModelMatrix", mb_data->obmat[MB_NEXT]);
- DRW_shgroup_uniform_bool(grp, "useDeform", &mb_geom->use_deform, 1);
-
- DRW_shgroup_call(grp, batch, ob);
-
if (mb_geom->use_deform) {
EEVEE_ObjectEngineData *oedata = EEVEE_object_data_ensure(ob);
if (!oedata->geom_update) {
@@ -386,6 +385,21 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata),
/* Keep to modify later (after init). */
mb_geom->batch = batch;
}
+
+ /* Avoid drawing object that has no motions since object_moves is always true. */
+ if (!mb_geom->use_deform && /* Object deformation can happen without transform. */
+ equals_m4m4(mb_data->obmat[MB_PREV], mb_data->obmat[MB_CURR]) &&
+ equals_m4m4(mb_data->obmat[MB_NEXT], mb_data->obmat[MB_CURR])) {
+ return;
+ }
+
+ grp = DRW_shgroup_create(e_data.motion_blur_object_sh, psl->velocity_object);
+ DRW_shgroup_uniform_mat4(grp, "prevModelMatrix", mb_data->obmat[MB_PREV]);
+ DRW_shgroup_uniform_mat4(grp, "currModelMatrix", mb_data->obmat[MB_CURR]);
+ DRW_shgroup_uniform_mat4(grp, "nextModelMatrix", mb_data->obmat[MB_NEXT]);
+ DRW_shgroup_uniform_bool(grp, "useDeform", &mb_geom->use_deform, 1);
+
+ DRW_shgroup_call(grp, batch, ob);
}
else if (is_deform) {
/* Store vertex position buffer. */
@@ -466,16 +480,15 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata)
GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_NEXT]);
break;
}
+
+ /* Modify the batch to include the previous & next position. */
+ if (i == MB_PREV) {
+ GPU_batch_vertbuf_add_ex(batch, vbo, true);
+ mb_geom->vbo[i] = NULL;
+ }
else {
- /* Modify the batch to include the previous & next position. */
- if (i == MB_PREV) {
- GPU_batch_vertbuf_add_ex(batch, vbo, true);
- mb_geom->vbo[i] = NULL;
- }
- else {
- /* This VBO can be reuse by next time step. Don't pass ownership. */
- GPU_batch_vertbuf_add_ex(batch, vbo, false);
- }
+ /* This VBO can be reuse by next time step. Don't pass ownership. */
+ GPU_batch_vertbuf_add_ex(batch, vbo, false);
}
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index a075210967c..1929bbb9b98 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -53,17 +53,14 @@ extern char datatoc_effect_gtao_frag_glsl[];
static void eevee_create_shader_occlusion(void)
{
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_ambient_occlusion_lib_glsl,
- datatoc_effect_gtao_frag_glsl);
-
- e_data.gtao_sh = DRW_shader_create_fullscreen(frag_str, NULL);
- e_data.gtao_layer_sh = DRW_shader_create_fullscreen(frag_str, "#define LAYERED_DEPTH\n");
- e_data.gtao_debug_sh = DRW_shader_create_fullscreen(frag_str, "#define DEBUG_AO\n");
-
- MEM_freeN(frag_str);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.gtao_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_gtao_frag_glsl, lib, NULL);
+ e_data.gtao_layer_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_gtao_frag_glsl, lib, "#define LAYERED_DEPTH\n");
+ e_data.gtao_debug_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_gtao_frag_glsl, lib, "#define DEBUG_AO\n");
}
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index a67593773ab..34cd22ad13c 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -20,8 +20,7 @@
* \ingroup DNA
*/
-#ifndef __EEVEE_PRIVATE_H__
-#define __EEVEE_PRIVATE_H__
+#pragma once
#include "DRW_render.h"
@@ -29,6 +28,8 @@
#include "DNA_lightprobe_types.h"
+#include "GPU_viewport.h"
+
#include "BKE_camera.h"
struct EEVEE_ShadowCasterBuffer;
@@ -53,14 +54,11 @@ extern struct DrawEngineType draw_engine_eevee_type;
/* Only define one of these. */
// #define IRRADIANCE_SH_L2
-// #define IRRADIANCE_CUBEMAP
#define IRRADIANCE_HL2
#define HAMMERSLEY_SIZE 1024
#if defined(IRRADIANCE_SH_L2)
# define SHADER_IRRADIANCE "#define IRRADIANCE_SH_L2\n"
-#elif defined(IRRADIANCE_CUBEMAP)
-# define SHADER_IRRADIANCE "#define IRRADIANCE_CUBEMAP\n"
#elif defined(IRRADIANCE_HL2)
# define SHADER_IRRADIANCE "#define IRRADIANCE_HL2\n"
#endif
@@ -166,7 +164,7 @@ enum {
VAR_MAT_MESH = (1 << 0),
VAR_MAT_VOLUME = (1 << 1),
VAR_MAT_HAIR = (1 << 2),
- VAR_MAT_PROBE = (1 << 3),
+ /* VAR_MAT_PROBE = (1 << 3), UNUSED */
VAR_MAT_BLEND = (1 << 4),
VAR_MAT_LOOKDEV = (1 << 5),
VAR_MAT_HOLDOUT = (1 << 6),
@@ -589,7 +587,7 @@ typedef struct EEVEE_ObjectKey {
/** Parent object for duplis */
struct Object *parent;
/** Dupli objects recursive unique identifier */
- int id[16]; /* 2*MAX_DUPLI_RECUR */
+ int id[8]; /* MAX_DUPLI_RECUR */
} EEVEE_ObjectKey;
typedef struct EEVEE_ObjectMotionData {
@@ -750,7 +748,6 @@ typedef struct EEVEE_EffectsInfo {
* - sizeof(bool) == sizeof(int) in GLSL so use int in C */
typedef struct EEVEE_CommonUniformBuffer {
float prev_persmat[4][4]; /* mat4 */
- float view_vecs[2][4]; /* vec4[2] */
float mip_ratio[10][4]; /* vec2[10] */
/* Ambient Occlusion */
/* -- 16 byte aligned -- */
@@ -894,6 +891,7 @@ typedef struct EEVEE_Data {
EEVEE_TextureList *txl;
EEVEE_PassList *psl;
EEVEE_StorageList *stl;
+ char info[GPU_INFO_SIZE];
} EEVEE_Data;
typedef struct EEVEE_PrivateData {
@@ -913,6 +911,7 @@ typedef struct EEVEE_PrivateData {
/* Render Matrices */
float studiolight_matrix[3][3];
float overscan, overscan_pixels;
+ float camtexcofac[4];
float size_orig[2];
/* Mist Settings */
@@ -971,8 +970,10 @@ EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *
Object *ob,
bool hair);
EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb,
- Object *ob,
- bool hair);
+ Object *ob);
+EEVEE_GeometryMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_MotionBlurData *mb,
+ Object *ob,
+ struct ModifierData *md);
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob);
EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob);
EEVEE_LightEngineData *EEVEE_light_data_get(Object *ob);
@@ -1004,7 +1005,6 @@ void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata,
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_materials_free(void);
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
-void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4]);
void EEVEE_material_renderpasses_init(EEVEE_Data *vedata);
void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -1012,8 +1012,8 @@ void EEVEE_material_bind_resources(DRWShadingGroup *shgrp,
struct GPUMaterial *gpumat,
EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- int *ssr_id,
- float *refract_depth,
+ const int *ssr_id,
+ const float *refract_depth,
bool use_ssrefraction,
bool use_alpha_blend);
/* eevee_lights.c */
@@ -1060,15 +1060,14 @@ void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4]);
/* eevee_shaders.c */
void EEVEE_shaders_lightprobe_shaders_init(void);
void EEVEE_shaders_material_shaders_init(void);
+struct DRWShaderLibrary *EEVEE_shader_lib_get(void);
struct GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void);
-struct GPUShader *EEVEE_shaders_probe_default_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_filter_visibility_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_grid_fill_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void);
-struct GPUShader *EEVEE_shaders_default_studiolight_sh_get(void);
-struct GPUShader *EEVEE_shaders_default_background_sh_get(void);
-struct GPUShader *EEVEE_shaders_background_studiolight_sh_get(void);
+struct GPUShader *EEVEE_shaders_studiolight_probe_sh_get(void);
+struct GPUShader *EEVEE_shaders_studiolight_background_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void);
@@ -1080,6 +1079,7 @@ struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo);
Material *EEVEE_material_default_diffuse_get(void);
Material *EEVEE_material_default_glossy_get(void);
Material *EEVEE_material_default_error_get(void);
+World *EEVEE_world_default_get(void);
struct GPUMaterial *EEVEE_material_default_get(struct Scene *scene, Material *ma, int options);
struct GPUMaterial *EEVEE_material_get(
EEVEE_Data *vedata, struct Scene *scene, Material *ma, World *wo, int options);
@@ -1283,6 +1283,9 @@ bool EEVEE_render_init(EEVEE_Data *vedata,
void EEVEE_render_view_sync(EEVEE_Data *vedata,
struct RenderEngine *engine,
struct Depsgraph *depsgraph);
+void EEVEE_render_modules_init(EEVEE_Data *vedata,
+ struct RenderEngine *engine,
+ struct Depsgraph *depsgraph);
void EEVEE_render_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_render_cache(void *vedata,
struct Object *ob,
@@ -1303,10 +1306,9 @@ void EEVEE_render_update_passes(struct RenderEngine *engine,
/** eevee_lookdev.c */
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
- DRWShadingGroup **grp,
DRWPass *pass,
- struct World *world,
- EEVEE_LightProbesInfo *pinfo);
+ EEVEE_LightProbesInfo *pinfo,
+ DRWShadingGroup **r_shgrp);
void EEVEE_lookdev_draw(EEVEE_Data *vedata);
/** eevee_engine.c */
@@ -1354,5 +1356,3 @@ static const float cubefacemat[6][4][4] = {
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}},
};
-
-#endif /* __EEVEE_PRIVATE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index f903fa905e8..b6b8833b1da 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -53,11 +53,9 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_FramebufferList *fbl = vedata->fbl;
- EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
Scene *scene = DEG_get_evaluated_scene(depsgraph);
const float *size_orig = DRW_viewport_size_get();
float size_final[2];
- float camtexcofac[4];
/* Init default FB and render targets:
* In render mode the default framebuffer is not generated
@@ -75,6 +73,7 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
g_data->valid_double_buffer = 0;
copy_v2_v2(g_data->size_orig, size_orig);
+ float *camtexcofac = g_data->camtexcofac;
if (scene->eevee.flag & SCE_EEVEE_OVERSCAN) {
g_data->overscan = scene->eevee.overscan / 100.0f;
g_data->overscan_pixels = roundf(max_ff(size_orig[0], size_orig[1]) * g_data->overscan);
@@ -125,19 +124,19 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
GPU_framebuffer_ensure_config(&fbl->main_color_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->color)});
- /* Alloc common ubo data. */
- if (sldata->common_ubo == NULL) {
- sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
- &sldata->common_data);
- }
-
- EEVEE_render_view_sync(vedata, engine, depsgraph);
+ return true;
+}
+void EEVEE_render_modules_init(EEVEE_Data *vedata,
+ RenderEngine *engine,
+ struct Depsgraph *depsgraph)
+{
+ EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
/* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
-
- DRWView *view = (DRWView *)DRW_view_default_get();
- DRW_view_camtexco_set(view, camtexcofac);
+ EEVEE_render_view_sync(vedata, engine, depsgraph);
/* `EEVEE_renderpasses_init` will set the active render passes used by `EEVEE_effects_init`.
* `EEVEE_effects_init` needs to go second for TAA. */
@@ -146,8 +145,6 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
EEVEE_materials_init(sldata, vedata, stl, fbl);
EEVEE_shadows_init(sldata);
EEVEE_lightprobes_init(sldata, vedata);
-
- return true;
}
void EEVEE_render_view_sync(EEVEE_Data *vedata, RenderEngine *engine, struct Depsgraph *depsgraph)
@@ -160,7 +157,7 @@ void EEVEE_render_view_sync(EEVEE_Data *vedata, RenderEngine *engine, struct Dep
struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
RE_GetCameraWindow(engine->re, ob_camera_eval, winmat);
- RE_GetCameraWindowWithOverscan(engine->re, winmat, g_data->overscan);
+ RE_GetCameraWindowWithOverscan(engine->re, g_data->overscan, winmat);
RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv);
invert_m4_m4(viewmat, viewinv);
@@ -169,10 +166,13 @@ void EEVEE_render_view_sync(EEVEE_Data *vedata, RenderEngine *engine, struct Dep
DRW_view_reset();
DRW_view_default_set(view);
DRW_view_set_active(view);
+
+ DRW_view_camtexco_set(view, g_data->camtexcofac);
}
void EEVEE_render_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
+ EEVEE_view_layer_data_ensure();
EEVEE_bloom_cache_init(sldata, vedata);
EEVEE_depth_of_field_cache_init(sldata, vedata);
EEVEE_effects_cache_init(sldata, vedata);
@@ -267,6 +267,7 @@ static void eevee_render_color_result(RenderLayer *rl,
BLI_rcti_size_y(rect),
num_channels,
0,
+ GPU_DATA_FLOAT,
rp->rect);
}
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index be771d7cf42..089d8b7a287 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -199,12 +199,10 @@ void EEVEE_renderpasses_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve
EEVEE_RENDERPASSES_WITH_POST_PROCESSING) > 0;
if (needs_post_processing) {
if (e_data.postprocess_sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_renderpass_postprocess_frag_glsl);
- e_data.postprocess_sh = DRW_shader_create_fullscreen(frag_str, NULL);
- MEM_freeN(frag_str);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.postprocess_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_renderpass_postprocess_frag_glsl, lib, NULL);
}
DRW_PASS_CREATE(psl->renderpass_pass, DRW_STATE_WRITE_COLOR);
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index 32d758dba4b..a1755e60c06 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -48,30 +48,12 @@ static struct {
struct GPUTexture *depth_src;
} e_data = {{NULL}}; /* Engine data */
-extern char datatoc_ambient_occlusion_lib_glsl[];
-extern char datatoc_common_view_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
-extern char datatoc_bsdf_common_lib_glsl[];
-extern char datatoc_bsdf_sampling_lib_glsl[];
-extern char datatoc_octahedron_lib_glsl[];
-extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_effect_ssr_frag_glsl[];
-extern char datatoc_lightprobe_lib_glsl[];
-extern char datatoc_raytrace_lib_glsl[];
static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
{
if (e_data.ssr_sh[options] == NULL) {
- char *ssr_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_ambient_occlusion_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_raytrace_lib_glsl,
- datatoc_effect_ssr_frag_glsl);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
DynStr *ds_defines = BLI_dynstr_new();
BLI_dynstr_append(ds_defines, SHADER_DEFINES);
@@ -91,9 +73,9 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines);
BLI_dynstr_free(ds_defines);
- e_data.ssr_sh[options] = DRW_shader_create_fullscreen(ssr_shader_str, ssr_define_str);
+ e_data.ssr_sh[options] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_ssr_frag_glsl, lib, ssr_define_str);
- MEM_freeN(ssr_shader_str);
MEM_freeN(ssr_define_str);
}
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index 09e74c84948..5f125d395d3 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -28,6 +28,8 @@
#include "BLI_dynstr.h"
#include "BLI_string_utils.h"
+#include "DNA_world_types.h"
+
#include "MEM_guardedalloc.h"
#include "GPU_material.h"
@@ -40,19 +42,17 @@
static const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
#if defined(IRRADIANCE_SH_L2)
- "#define IRRADIANCE_SH_L2\n"
-#elif defined(IRRADIANCE_CUBEMAP)
- "#define IRRADIANCE_CUBEMAP\n"
+ "#define IRRADIANCE_SH_L2\n";
#elif defined(IRRADIANCE_HL2)
- "#define IRRADIANCE_HL2\n"
+ "#define IRRADIANCE_HL2\n";
#endif
- "#define NOISE_SIZE 64\n";
static struct {
+ /* Lookdev */
+ struct GPUShader *studiolight_probe_sh;
+ struct GPUShader *studiolight_background_sh;
+
/* Probes */
- struct GPUShader *probe_default_sh;
- struct GPUShader *probe_default_studiolight_sh;
- struct GPUShader *probe_background_studiolight_sh;
struct GPUShader *probe_grid_display_sh;
struct GPUShader *probe_cube_display_sh;
struct GPUShader *probe_planar_display_sh;
@@ -70,17 +70,16 @@ static struct {
struct GPUShader *taa_resolve_reproject_sh;
/* General purpose Shaders. */
- struct GPUShader *default_background;
+ struct GPUShader *lookdev_background;
struct GPUShader *update_noise_sh;
/* Shader strings */
- char *frag_shader_lib;
- char *vert_shader_str;
- char *vert_shadow_shader_str;
- char *vert_background_shader_str;
- char *vert_volume_shader_str;
- char *geom_volume_shader_str;
- char *volume_shader_lib;
+ char *closure_lit_lib;
+ char *surface_lit_frag;
+ char *surface_prepass_frag;
+ char *surface_geom_barycentric;
+
+ DRWShaderLibrary *lib;
/* LookDev Materials */
Material *glossy_mat;
@@ -88,6 +87,8 @@ static struct {
Material *error_mat;
+ World *default_world;
+
/* Default Material */
struct {
bNodeTree *ntree;
@@ -103,16 +104,39 @@ static struct {
} world;
} e_data = {NULL}; /* Engine data */
-extern char datatoc_bsdf_common_lib_glsl[];
-extern char datatoc_bsdf_sampling_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
+extern char datatoc_common_hair_lib_glsl[];
+extern char datatoc_common_math_lib_glsl[];
+extern char datatoc_common_math_geom_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
+extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_background_vert_glsl[];
-extern char datatoc_common_hair_lib_glsl[];
+extern char datatoc_bsdf_common_lib_glsl[];
+extern char datatoc_bsdf_lut_frag_glsl[];
+extern char datatoc_bsdf_sampling_lib_glsl[];
+extern char datatoc_btdf_lut_frag_glsl[];
+extern char datatoc_closure_lib_glsl[];
+extern char datatoc_common_uniforms_lib_glsl[];
+extern char datatoc_common_utiltex_lib_glsl[];
extern char datatoc_cubemap_lib_glsl[];
-extern char datatoc_default_world_frag_glsl[];
+extern char datatoc_default_frag_glsl[];
+extern char datatoc_lookdev_world_frag_glsl[];
+extern char datatoc_effect_bloom_frag_glsl[];
+extern char datatoc_effect_dof_frag_glsl[];
+extern char datatoc_effect_dof_vert_glsl[];
+extern char datatoc_effect_downsample_cube_frag_glsl[];
+extern char datatoc_effect_downsample_frag_glsl[];
+extern char datatoc_effect_gtao_frag_glsl[];
+extern char datatoc_effect_minmaxz_frag_glsl[];
+extern char datatoc_effect_mist_frag_glsl[];
+extern char datatoc_effect_motion_blur_frag_glsl[];
+extern char datatoc_effect_ssr_frag_glsl[];
+extern char datatoc_effect_subsurface_frag_glsl[];
+extern char datatoc_effect_temporal_aa_glsl[];
+extern char datatoc_effect_translucency_frag_glsl[];
+extern char datatoc_effect_velocity_resolve_frag_glsl[];
+extern char datatoc_effect_velocity_tile_frag_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lightprobe_cube_display_frag_glsl[];
extern char datatoc_lightprobe_cube_display_vert_glsl[];
@@ -131,72 +155,111 @@ extern char datatoc_lightprobe_planar_downsample_geom_glsl[];
extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
extern char datatoc_lightprobe_vert_glsl[];
extern char datatoc_lights_lib_glsl[];
-extern char datatoc_lit_surface_frag_glsl[];
-extern char datatoc_lit_surface_vert_glsl[];
+extern char datatoc_closure_lit_lib_glsl[];
extern char datatoc_ltc_lib_glsl[];
+extern char datatoc_object_motion_frag_glsl[];
+extern char datatoc_object_motion_vert_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_prepass_frag_glsl[];
+extern char datatoc_prepass_vert_glsl[];
extern char datatoc_raytrace_lib_glsl[];
+extern char datatoc_renderpass_lib_glsl[];
+extern char datatoc_renderpass_postprocess_frag_glsl[];
+extern char datatoc_shadow_accum_frag_glsl[];
+extern char datatoc_shadow_frag_glsl[];
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_ssr_lib_glsl[];
+extern char datatoc_surface_frag_glsl[];
+extern char datatoc_surface_geom_glsl[];
+extern char datatoc_surface_lib_glsl[];
+extern char datatoc_surface_vert_glsl[];
extern char datatoc_update_noise_frag_glsl[];
+extern char datatoc_volumetric_accum_frag_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_geom_glsl[];
+extern char datatoc_volumetric_integration_frag_glsl[];
extern char datatoc_volumetric_lib_glsl[];
+extern char datatoc_volumetric_resolve_frag_glsl[];
+extern char datatoc_volumetric_scatter_frag_glsl[];
extern char datatoc_volumetric_vert_glsl[];
-/* Velocity Resolve */
-extern char datatoc_effect_velocity_resolve_frag_glsl[];
-
-/* Temporal Sampling */
-extern char datatoc_effect_temporal_aa_glsl[];
-
/* *********** FUNCTIONS *********** */
+static void eevee_shader_library_ensure(void)
+{
+ if (e_data.lib == NULL) {
+ e_data.lib = DRW_shader_library_create();
+ /* NOTE: Theses needs to be ordered by dependencies. */
+ DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_uniforms_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, renderpass_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, bsdf_common_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_utiltex_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, bsdf_sampling_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, cubemap_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, raytrace_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, ambient_occlusion_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, octahedron_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, irradiance_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, lightprobe_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, ltc_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, lights_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, surface_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, volumetric_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, closure_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, ssr_lib);
+
+ /* Add one for each Closure */
+ e_data.closure_lit_lib = BLI_string_joinN(datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl);
+
+ DRW_shader_library_add_file(e_data.lib, e_data.closure_lit_lib, "closure_lit_lib.glsl");
+
+ e_data.surface_lit_frag = DRW_shader_library_create_shader_string(e_data.lib,
+ datatoc_surface_frag_glsl);
+
+ e_data.surface_prepass_frag = DRW_shader_library_create_shader_string(
+ e_data.lib, datatoc_prepass_frag_glsl);
+
+ e_data.surface_geom_barycentric = DRW_shader_library_create_shader_string(
+ e_data.lib, datatoc_surface_geom_glsl);
+ }
+}
+
void EEVEE_shaders_lightprobe_shaders_init(void)
{
BLI_assert(e_data.probe_filter_glossy_sh == NULL);
- char *shader_str = NULL;
-
- shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_lightprobe_filter_glossy_frag_glsl);
-
- e_data.probe_filter_glossy_sh = DRW_shader_create(
- datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, shader_str, filter_defines);
-
- e_data.probe_default_sh = DRW_shader_create_with_lib(datatoc_background_vert_glsl,
- NULL,
- datatoc_default_world_frag_glsl,
- datatoc_common_view_lib_glsl,
- NULL);
- MEM_freeN(shader_str);
+ eevee_shader_library_ensure();
- shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_lightprobe_filter_diffuse_frag_glsl);
+ e_data.probe_filter_glossy_sh = DRW_shader_create_with_shaderlib(
+ datatoc_lightprobe_vert_glsl,
+ datatoc_lightprobe_geom_glsl,
+ datatoc_lightprobe_filter_glossy_frag_glsl,
+ e_data.lib,
+ filter_defines);
- e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen(shader_str, filter_defines);
+ e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_lightprobe_filter_diffuse_frag_glsl, e_data.lib, filter_defines);
- MEM_freeN(shader_str);
+ e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_lightprobe_filter_visibility_frag_glsl, e_data.lib, filter_defines);
- shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_lightprobe_filter_visibility_frag_glsl);
-
- e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen(shader_str, filter_defines);
-
- MEM_freeN(shader_str);
-
- e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen(datatoc_lightprobe_grid_fill_frag_glsl,
- filter_defines);
+ e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_lightprobe_grid_fill_frag_glsl, e_data.lib, filter_defines);
e_data.probe_planar_downsample_sh = DRW_shader_create(
datatoc_lightprobe_planar_downsample_vert_glsl,
@@ -207,70 +270,18 @@ void EEVEE_shaders_lightprobe_shaders_init(void)
void EEVEE_shaders_material_shaders_init(void)
{
- e_data.frag_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_ambient_occlusion_lib_glsl,
- datatoc_raytrace_lib_glsl,
- datatoc_ssr_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_irradiance_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_ltc_lib_glsl,
- datatoc_lights_lib_glsl,
- /* Add one for each Closure */
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_volumetric_lib_glsl);
-
- e_data.volume_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_ambient_occlusion_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_irradiance_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_ltc_lib_glsl,
- datatoc_lights_lib_glsl,
- datatoc_volumetric_lib_glsl,
- datatoc_volumetric_frag_glsl);
-
- e_data.vert_shader_str = BLI_string_joinN(
- datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_lit_surface_vert_glsl);
-
- e_data.vert_shadow_shader_str = BLI_string_joinN(
- datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_shadow_vert_glsl);
-
- e_data.vert_background_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_background_vert_glsl);
-
- e_data.vert_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_volumetric_vert_glsl);
-
- e_data.geom_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_volumetric_geom_glsl);
+ eevee_shader_library_ensure();
}
-GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void)
+DRWShaderLibrary *EEVEE_shader_lib_get(void)
{
- return e_data.probe_filter_glossy_sh;
+ eevee_shader_library_ensure();
+ return e_data.lib;
}
-GPUShader *EEVEE_shaders_probe_default_sh_get(void)
+GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void)
{
- return e_data.probe_default_sh;
+ return e_data.probe_filter_glossy_sh;
}
GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void)
@@ -293,59 +304,40 @@ GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void)
return e_data.probe_planar_downsample_sh;
}
-GPUShader *EEVEE_shaders_default_studiolight_sh_get(void)
+GPUShader *EEVEE_shaders_studiolight_probe_sh_get(void)
{
- if (e_data.probe_default_studiolight_sh == NULL) {
- e_data.probe_default_studiolight_sh = DRW_shader_create_with_lib(
- datatoc_background_vert_glsl,
- NULL,
- datatoc_default_world_frag_glsl,
- datatoc_common_view_lib_glsl,
- "#define LOOKDEV\n");
- }
- return e_data.probe_default_studiolight_sh;
+ if (e_data.studiolight_probe_sh == NULL) {
+ e_data.studiolight_probe_sh = DRW_shader_create_with_shaderlib(datatoc_background_vert_glsl,
+ NULL,
+ datatoc_lookdev_world_frag_glsl,
+ e_data.lib,
+ SHADER_DEFINES);
+ }
+ return e_data.studiolight_probe_sh;
}
-GPUShader *EEVEE_shaders_background_studiolight_sh_get(void)
+GPUShader *EEVEE_shaders_studiolight_background_sh_get(void)
{
- if (e_data.probe_background_studiolight_sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_default_world_frag_glsl);
-
- e_data.probe_background_studiolight_sh = DRW_shader_create_with_lib(
+ if (e_data.studiolight_background_sh == NULL) {
+ e_data.studiolight_background_sh = DRW_shader_create_with_shaderlib(
datatoc_background_vert_glsl,
NULL,
- frag_str,
- datatoc_common_view_lib_glsl,
+ datatoc_lookdev_world_frag_glsl,
+ e_data.lib,
"#define LOOKDEV_BG\n" SHADER_DEFINES);
-
- MEM_freeN(frag_str);
}
- return e_data.probe_background_studiolight_sh;
+ return e_data.studiolight_background_sh;
}
GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void)
{
if (e_data.probe_cube_display_sh == NULL) {
- char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_lightprobe_cube_display_frag_glsl);
-
- char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_lightprobe_cube_display_vert_glsl);
-
- e_data.probe_cube_display_sh = DRW_shader_create(vert_str, NULL, shader_str, SHADER_DEFINES);
-
- MEM_freeN(vert_str);
- MEM_freeN(shader_str);
+ e_data.probe_cube_display_sh = DRW_shader_create_with_shaderlib(
+ datatoc_lightprobe_cube_display_vert_glsl,
+ NULL,
+ datatoc_lightprobe_cube_display_frag_glsl,
+ e_data.lib,
+ SHADER_DEFINES);
}
return e_data.probe_cube_display_sh;
}
@@ -353,22 +345,12 @@ GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void)
GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void)
{
if (e_data.probe_grid_display_sh == NULL) {
- char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_irradiance_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_lightprobe_grid_display_frag_glsl);
-
- char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_lightprobe_grid_display_vert_glsl);
-
- e_data.probe_grid_display_sh = DRW_shader_create(vert_str, NULL, shader_str, filter_defines);
-
- MEM_freeN(vert_str);
- MEM_freeN(shader_str);
+ e_data.probe_grid_display_sh = DRW_shader_create_with_shaderlib(
+ datatoc_lightprobe_grid_display_vert_glsl,
+ NULL,
+ datatoc_lightprobe_grid_display_frag_glsl,
+ e_data.lib,
+ filter_defines);
}
return e_data.probe_grid_display_sh;
}
@@ -376,16 +358,12 @@ GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void)
GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void)
{
if (e_data.probe_planar_display_sh == NULL) {
- char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_lightprobe_planar_display_vert_glsl);
-
- char *shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_lightprobe_planar_display_frag_glsl);
-
- e_data.probe_planar_display_sh = DRW_shader_create(vert_str, NULL, shader_str, NULL);
-
- MEM_freeN(vert_str);
- MEM_freeN(shader_str);
+ e_data.probe_planar_display_sh = DRW_shader_create_with_shaderlib(
+ datatoc_lightprobe_planar_display_vert_glsl,
+ NULL,
+ datatoc_lightprobe_planar_display_frag_glsl,
+ e_data.lib,
+ NULL);
}
return e_data.probe_planar_display_sh;
}
@@ -393,34 +371,17 @@ GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void)
GPUShader *EEVEE_shaders_velocity_resolve_sh_get(void)
{
if (e_data.velocity_resolve_sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_common_uniforms_lib_glsl,
- datatoc_common_view_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_effect_velocity_resolve_frag_glsl);
-
- e_data.velocity_resolve_sh = DRW_shader_create_fullscreen(frag_str, NULL);
-
- MEM_freeN(frag_str);
+ e_data.velocity_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_velocity_resolve_frag_glsl, e_data.lib, NULL);
}
return e_data.velocity_resolve_sh;
}
-GPUShader *EEVEE_shaders_default_background_sh_get(void)
-{
- if (e_data.default_background == NULL) {
- e_data.default_background = DRW_shader_create_with_lib(datatoc_background_vert_glsl,
- NULL,
- datatoc_default_world_frag_glsl,
- datatoc_common_view_lib_glsl,
- NULL);
- }
- return e_data.default_background;
-}
-
GPUShader *EEVEE_shaders_update_noise_sh_get(void)
{
if (e_data.update_noise_sh == NULL) {
- e_data.update_noise_sh = DRW_shader_create_fullscreen(datatoc_update_noise_frag_glsl, NULL);
+ e_data.update_noise_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_update_noise_frag_glsl, e_data.lib, NULL);
}
return e_data.update_noise_sh;
}
@@ -437,13 +398,8 @@ GPUShader *EEVEE_shaders_taa_resolve_sh_get(EEVEE_EffectsFlag enabled_effects)
sh = &e_data.taa_resolve_sh;
}
if (*sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_common_uniforms_lib_glsl,
- datatoc_common_view_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_effect_temporal_aa_glsl);
-
- *sh = DRW_shader_create_fullscreen(frag_str, define);
- MEM_freeN(frag_str);
+ *sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_temporal_aa_glsl, e_data.lib, define);
}
return *sh;
@@ -583,6 +539,18 @@ struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo)
return e_data.world.ntree;
}
+World *EEVEE_world_default_get(void)
+{
+ if (e_data.default_world == NULL) {
+ e_data.default_world = BKE_id_new_nomain(ID_WO, "EEVEEE default world");
+ copy_v3_fl(&e_data.default_world->horr, 0.0f);
+ e_data.default_world->use_nodes = 0;
+ e_data.default_world->nodetree = NULL;
+ BLI_listbase_clear(&e_data.default_world->gpumaterial);
+ }
+ return e_data.default_world;
+}
+
static char *eevee_get_defines(int options)
{
char *str = NULL;
@@ -605,7 +573,7 @@ static char *eevee_get_defines(int options)
if ((options & VAR_MAT_HAIR) != 0) {
BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
}
- if ((options & (VAR_MAT_PROBE | VAR_WORLD_PROBE)) != 0) {
+ if ((options & VAR_WORLD_PROBE) != 0) {
BLI_dynstr_append(ds, "#define PROBE_CAPTURE\n");
}
if ((options & VAR_MAT_HASH) != 0) {
@@ -635,13 +603,13 @@ static char *eevee_get_vert(int options)
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
- str = BLI_strdup(e_data.vert_volume_shader_str);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_vert_glsl);
}
else if ((options & (VAR_WORLD_PROBE | VAR_WORLD_BACKGROUND)) != 0) {
- str = BLI_strdup(e_data.vert_background_shader_str);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_background_vert_glsl);
}
else {
- str = BLI_strdup(e_data.vert_shader_str);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_surface_vert_glsl);
}
return str;
@@ -652,7 +620,7 @@ static char *eevee_get_geom(int options)
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
- str = BLI_strdup(e_data.geom_volume_shader_str);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_geom_glsl);
}
return str;
@@ -663,18 +631,36 @@ static char *eevee_get_frag(int options)
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
- str = BLI_strdup(e_data.volume_shader_lib);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_frag_glsl);
}
else if ((options & VAR_MAT_DEPTH) != 0) {
- str = BLI_string_joinN(e_data.frag_shader_lib, datatoc_prepass_frag_glsl);
+ str = BLI_strdup(e_data.surface_prepass_frag);
}
else {
- str = BLI_strdup(e_data.frag_shader_lib);
+ str = BLI_strdup(e_data.surface_lit_frag);
}
return str;
}
+static void eevee_material_post_eval(GPUMaterial *mat,
+ int options,
+ const char **UNUSED(vert_code),
+ const char **geom_code,
+ const char **UNUSED(frag_lib),
+ const char **UNUSED(defines))
+{
+ const bool is_hair = (options & VAR_MAT_HAIR) != 0;
+ const bool is_mesh = (options & VAR_MAT_MESH) != 0;
+
+ /* Force geometry usage if GPU_BARYCENTRIC_DIST or GPU_BARYCENTRIC_TEXCO are used.
+ * Note: GPU_BARYCENTRIC_TEXCO only requires it if the shader is not drawing hairs. */
+ if (!is_hair && is_mesh && GPU_material_flag_get(mat, GPU_MATFLAG_BARYCENTRIC) &&
+ *geom_code == NULL) {
+ *geom_code = e_data.surface_geom_barycentric;
+ }
+}
+
static struct GPUMaterial *eevee_material_get_ex(
struct Scene *scene, Material *ma, World *wo, int options, bool deferred)
{
@@ -702,14 +688,16 @@ static struct GPUMaterial *eevee_material_get_ex(
char *frag = eevee_get_frag(options);
if (ma) {
+ GPUMaterialEvalCallbackFn cbfn = &eevee_material_post_eval;
+
bNodeTree *ntree = !is_default ? ma->nodetree : EEVEE_shader_default_surface_nodetree(ma);
mat = DRW_shader_create_from_material(
- scene, ma, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred);
+ scene, ma, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred, cbfn);
}
else {
bNodeTree *ntree = !is_default ? wo->nodetree : EEVEE_shader_default_world_nodetree(wo);
mat = DRW_shader_create_from_world(
- scene, wo, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred);
+ scene, wo, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred, NULL);
}
MEM_SAFE_FREE(defines);
@@ -764,30 +752,31 @@ struct GPUMaterial *EEVEE_material_get(
void EEVEE_shaders_free(void)
{
- MEM_SAFE_FREE(e_data.frag_shader_lib);
- MEM_SAFE_FREE(e_data.vert_shader_str);
- MEM_SAFE_FREE(e_data.vert_shadow_shader_str);
- MEM_SAFE_FREE(e_data.vert_background_shader_str);
- MEM_SAFE_FREE(e_data.vert_volume_shader_str);
- MEM_SAFE_FREE(e_data.geom_volume_shader_str);
- MEM_SAFE_FREE(e_data.volume_shader_lib);
- DRW_SHADER_FREE_SAFE(e_data.default_background);
+ MEM_SAFE_FREE(e_data.closure_lit_lib);
+ MEM_SAFE_FREE(e_data.surface_prepass_frag);
+ MEM_SAFE_FREE(e_data.surface_lit_frag);
+ MEM_SAFE_FREE(e_data.surface_geom_barycentric);
+ DRW_SHADER_FREE_SAFE(e_data.lookdev_background);
DRW_SHADER_FREE_SAFE(e_data.update_noise_sh);
- DRW_SHADER_FREE_SAFE(e_data.probe_default_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_visibility_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_grid_fill_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_planar_downsample_sh);
- DRW_SHADER_FREE_SAFE(e_data.probe_default_studiolight_sh);
- DRW_SHADER_FREE_SAFE(e_data.probe_background_studiolight_sh);
+ DRW_SHADER_FREE_SAFE(e_data.studiolight_probe_sh);
+ DRW_SHADER_FREE_SAFE(e_data.studiolight_background_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_grid_display_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_cube_display_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_planar_display_sh);
DRW_SHADER_FREE_SAFE(e_data.velocity_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_reproject_sh);
+ DRW_SHADER_LIB_FREE_SAFE(e_data.lib);
+ if (e_data.default_world) {
+ BKE_id_free(NULL, e_data.default_world);
+ e_data.default_world = NULL;
+ }
if (e_data.glossy_mat) {
BKE_id_free(NULL, e_data.glossy_mat);
e_data.glossy_mat = NULL;
diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c
index 8c50b26b45f..0da356b75ac 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows.c
@@ -42,11 +42,6 @@ static struct {
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_shadow_frag_glsl[];
extern char datatoc_shadow_accum_frag_glsl[];
-extern char datatoc_common_view_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
-extern char datatoc_bsdf_common_lib_glsl[];
-extern char datatoc_lights_lib_glsl[];
-extern char datatoc_raytrace_lib_glsl[];
void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh)
{
@@ -65,23 +60,13 @@ void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata)
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (!e_data.shadow_sh) {
- e_data.shadow_sh = DRW_shader_create_with_lib(datatoc_shadow_vert_glsl,
- NULL,
- datatoc_shadow_frag_glsl,
- datatoc_common_view_lib_glsl,
- NULL);
- }
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
- if (!e_data.shadow_accum_sh) {
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_raytrace_lib_glsl,
- datatoc_lights_lib_glsl,
- datatoc_shadow_accum_frag_glsl);
+ e_data.shadow_sh = DRW_shader_create_with_shaderlib(
+ datatoc_shadow_vert_glsl, NULL, datatoc_shadow_frag_glsl, lib, NULL);
- e_data.shadow_accum_sh = DRW_shader_create_fullscreen(frag_str, SHADER_DEFINES);
- MEM_freeN(frag_str);
+ e_data.shadow_accum_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_shadow_accum_frag_glsl, lib, SHADER_DEFINES);
}
if (!sldata->lights) {
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index ef4588f4aca..637c5201afc 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -38,41 +38,19 @@ static struct {
struct GPUShader *sss_sh[3];
} e_data = {{NULL}}; /* Engine data */
-extern char datatoc_common_view_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
-extern char datatoc_lights_lib_glsl[];
-extern char datatoc_raytrace_lib_glsl[];
-extern char datatoc_octahedron_lib_glsl[];
-extern char datatoc_cubemap_lib_glsl[];
-extern char datatoc_bsdf_sampling_lib_glsl[];
-extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_effect_subsurface_frag_glsl[];
extern char datatoc_effect_translucency_frag_glsl[];
static void eevee_create_shader_subsurface(void)
{
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_effect_subsurface_frag_glsl);
-
- /* TODO(fclem) remove some of these dependencies. */
- char *frag_translucent_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_raytrace_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_lights_lib_glsl,
- datatoc_effect_translucency_frag_glsl);
-
- e_data.sss_sh[0] = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
- e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n");
- e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_translucent_str,
- "#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES);
-
- MEM_freeN(frag_translucent_str);
- MEM_freeN(frag_str);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.sss_sh[0] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_subsurface_frag_glsl, lib, "#define FIRST_PASS\n");
+ e_data.sss_sh[1] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_subsurface_frag_glsl, lib, "#define SECOND_PASS\n");
+ e_data.sss_sh[2] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_translucency_frag_glsl, lib, "#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES);
}
void EEVEE_subsurface_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *UNUSED(vedata))
diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
index 714481c39f1..e184a80d2f6 100644
--- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
@@ -96,7 +96,7 @@ static void invert_cdf(const float cdf[FILTER_CDF_TABLE_SIZE],
}
/* Evaluate a discrete function table with linear interpolation. */
-static float eval_table(float *table, float x)
+static float eval_table(const float *table, float x)
{
CLAMP(x, 0.0f, 1.0f);
x = x * (FILTER_CDF_TABLE_SIZE - 1);
@@ -240,9 +240,9 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
view_is_valid = view_is_valid && (ED_screen_animation_no_scrub(wm) == NULL);
}
- effects->taa_total_sample = EEVEE_renderpasses_only_first_sample_pass_active(vedata) ?
- 1 :
- scene_eval->eevee.taa_samples;
+ const bool first_sample_only = EEVEE_renderpasses_only_first_sample_pass_active(vedata);
+ view_is_valid = view_is_valid && !first_sample_only;
+ effects->taa_total_sample = first_sample_only ? 1 : scene_eval->eevee.taa_samples;
MAX2(effects->taa_total_sample, 0);
DRW_view_persmat_get(NULL, persmat, false);
@@ -269,7 +269,14 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
}
}
else {
- effects->bypass_drawing = true;
+ const bool all_shaders_compiled = stl->g_data->queued_shaders_count_prev == 0;
+ /* Fix Texture painting (see T79370) and shader compilation (see T78520). */
+ if (DRW_state_is_navigating() || !all_shaders_compiled) {
+ effects->taa_current_sample = 1;
+ }
+ else {
+ effects->bypass_drawing = true;
+ }
}
return repro_flag | EFFECT_TAA | EFFECT_DOUBLE_BUFFER | EFFECT_DEPTH_DOUBLE_BUFFER |
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 300022e97a9..57d5e54290e 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -44,16 +44,12 @@
#include "DEG_depsgraph_query.h"
-#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
#include "GPU_texture.h"
#include "eevee_private.h"
static struct {
- char *volumetric_common_lib;
- char *volumetric_common_lights_lib;
-
struct GPUShader *volumetric_clear_sh;
struct GPUShader *scatter_sh;
struct GPUShader *scatter_with_lights_sh;
@@ -97,57 +93,48 @@ extern char datatoc_common_fullscreen_vert_glsl[];
static void eevee_create_shader_volumes(void)
{
- e_data.volumetric_common_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_volumetric_lib_glsl);
-
- e_data.volumetric_common_lights_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_irradiance_lib_glsl,
- datatoc_lights_lib_glsl,
- datatoc_volumetric_lib_glsl);
-
- e_data.volumetric_clear_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
- datatoc_volumetric_geom_glsl,
- datatoc_volumetric_frag_glsl,
- e_data.volumetric_common_lib,
- "#define VOLUMETRICS\n"
- "#define CLEAR\n");
- e_data.scatter_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
- datatoc_volumetric_geom_glsl,
- datatoc_volumetric_scatter_frag_glsl,
- e_data.volumetric_common_lights_lib,
- SHADER_DEFINES
- "#define VOLUMETRICS\n"
- "#define VOLUME_SHADOW\n");
- e_data.scatter_with_lights_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
- datatoc_volumetric_geom_glsl,
- datatoc_volumetric_scatter_frag_glsl,
- e_data.volumetric_common_lights_lib,
- SHADER_DEFINES
- "#define VOLUMETRICS\n"
- "#define VOLUME_LIGHTING\n"
- "#define VOLUME_SHADOW\n");
- e_data.volumetric_integration_sh = DRW_shader_create_with_lib(
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.volumetric_clear_sh = DRW_shader_create_with_shaderlib(datatoc_volumetric_vert_glsl,
+ datatoc_volumetric_geom_glsl,
+ datatoc_volumetric_frag_glsl,
+ lib,
+ SHADER_DEFINES
+ "#define VOLUMETRICS\n"
+ "#define CLEAR\n");
+
+ e_data.scatter_sh = DRW_shader_create_with_shaderlib(datatoc_volumetric_vert_glsl,
+ datatoc_volumetric_geom_glsl,
+ datatoc_volumetric_scatter_frag_glsl,
+ lib,
+ SHADER_DEFINES
+ "#define VOLUMETRICS\n"
+ "#define VOLUME_SHADOW\n");
+
+ e_data.scatter_with_lights_sh = DRW_shader_create_with_shaderlib(
+ datatoc_volumetric_vert_glsl,
+ datatoc_volumetric_geom_glsl,
+ datatoc_volumetric_scatter_frag_glsl,
+ lib,
+ SHADER_DEFINES
+ "#define VOLUMETRICS\n"
+ "#define VOLUME_LIGHTING\n"
+ "#define VOLUME_SHADOW\n");
+
+ e_data.volumetric_integration_sh = DRW_shader_create_with_shaderlib(
datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_integration_frag_glsl,
- e_data.volumetric_common_lib,
+ lib,
USE_VOLUME_OPTI ? "#extension GL_ARB_shader_image_load_store: enable\n"
"#extension GL_ARB_shading_language_420pack: enable\n"
- "#define USE_VOLUME_OPTI\n" :
- NULL);
- e_data.volumetric_resolve_sh = DRW_shader_create_with_lib(datatoc_common_fullscreen_vert_glsl,
- NULL,
- datatoc_volumetric_resolve_frag_glsl,
- e_data.volumetric_common_lib,
- NULL);
- e_data.volumetric_accum_sh = DRW_shader_create_fullscreen(datatoc_volumetric_accum_frag_glsl,
- NULL);
+ "#define USE_VOLUME_OPTI\n" SHADER_DEFINES :
+ SHADER_DEFINES);
+
+ e_data.volumetric_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_volumetric_resolve_frag_glsl, lib, SHADER_DEFINES);
+ e_data.volumetric_accum_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_volumetric_accum_frag_glsl, lib, SHADER_DEFINES);
const float density[4] = {1.0f, 1.0f, 1.0f, 1.0f};
e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, density);
@@ -259,17 +246,11 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->vol_shadow_steps = 0;
}
- /* Update view_vecs */
- float invproj[4][4], winmat[4][4];
- DRW_view_winmat_get(NULL, winmat, false);
- DRW_view_winmat_get(NULL, invproj, true);
- EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
-
if (DRW_view_is_persp_get(NULL)) {
float sample_distribution = scene_eval->eevee.volumetric_sample_distribution;
sample_distribution = 4.0f * (max_ff(1.0f - sample_distribution, 1e-2f));
- const float clip_start = common_data->view_vecs[0][2];
+ const float clip_start = DRW_view_near_distance_get(NULL);
/* Negate */
float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f);
float far = integration_end = min_ff(-integration_end, near - 1e-4f);
@@ -280,8 +261,8 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->vol_depth_param[2] = sample_distribution;
}
else {
- const float clip_start = common_data->view_vecs[0][2];
- const float clip_end = clip_start + common_data->view_vecs[1][2];
+ const float clip_start = DRW_view_near_distance_get(NULL);
+ const float clip_end = DRW_view_far_distance_get(NULL);
integration_start = min_ff(integration_end, clip_start);
integration_end = max_ff(-integration_end, clip_end);
@@ -504,12 +485,7 @@ static bool eevee_volume_object_mesh_init(Scene *scene,
#endif
if (fds->fluid && (fds->type == FLUID_DOMAIN_TYPE_GAS) /* && show_smoke */) {
- if (!(fds->flags & FLUID_DOMAIN_USE_NOISE)) {
- GPU_create_smoke(fmd, 0);
- }
- else if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
- GPU_create_smoke(fmd, 1);
- }
+ DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE);
BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(fmd));
}
@@ -841,16 +817,13 @@ void EEVEE_volumes_free_smoke_textures(void)
/* Free Smoke Textures after rendering */
LISTBASE_FOREACH (LinkData *, link, &e_data.smoke_domains) {
FluidModifierData *fmd = (FluidModifierData *)link->data;
- GPU_free_smoke(fmd);
+ DRW_smoke_free(fmd);
}
BLI_freelistN(&e_data.smoke_domains);
}
void EEVEE_volumes_free(void)
{
- MEM_SAFE_FREE(e_data.volumetric_common_lib);
- MEM_SAFE_FREE(e_data.volumetric_common_lights_lib);
-
DRW_TEXTURE_FREE_SAFE(e_data.dummy_scatter);
DRW_TEXTURE_FREE_SAFE(e_data.dummy_transmit);
diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
index 57b16418696..2f6f8327f58 100644
--- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
@@ -1,4 +1,7 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
+
/* Based on Practical Realtime Strategies for Accurate Indirect Occlusion
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx
@@ -24,12 +27,6 @@
#define MAX_SEARCH_ITER 32
#define MAX_LOD 6.0
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
uniform sampler2D horizonBuffer;
/* aoSettings flags */
@@ -243,6 +240,11 @@ float gtao_multibounce(float visibility, vec3 albedo)
return max(x, ((x * a + b) * x + c) * x);
}
+float specular_occlusion(float NV, float AO, float roughness)
+{
+ return saturate(pow(NV + AO, roughness) - 1.0 + AO);
+}
+
/* Use the right occlusion */
float occlusion_compute(vec3 N, vec3 vpos, float user_occlusion, vec4 rand, out vec3 bent_normal)
{
diff --git a/source/blender/draw/engines/eevee/shaders/background_vert.glsl b/source/blender/draw/engines/eevee/shaders/background_vert.glsl
index aff8e0857f6..ab5d9a7ebe4 100644
--- a/source/blender/draw/engines/eevee/shaders/background_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/background_vert.glsl
@@ -1,17 +1,17 @@
-in vec2 pos;
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
-out vec3 viewPosition;
+in vec2 pos;
-#ifndef VOLUMETRICS
-/* necessary for compilation*/
-out vec3 worldPosition;
-out vec3 worldNormal;
-out vec3 viewNormal;
-#endif
+RESOURCE_ID_VARYING
void main()
{
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+
+ PASS_RESOURCE_ID
+
gl_Position = vec4(pos, 1.0, 1.0);
viewPosition = vec3(pos, -1.0);
@@ -22,6 +22,6 @@ void main()
#endif
#ifdef USE_ATTR
- pass_attr(viewPosition);
+ pass_attr(viewPosition, NormalMatrix, ModelMatrixInverse);
#endif
}
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 a8b8566edec..deedde64194 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -1,487 +1,7 @@
-#define M_PI 3.14159265358979323846 /* pi */
-#define M_2PI 6.28318530717958647692 /* 2*pi */
-#define M_PI_2 1.57079632679489661923 /* pi/2 */
-#define M_1_PI 0.318309886183790671538 /* 1/pi */
-#define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */
-#define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */
-#define FLT_MAX 3.402823e+38
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
-#define LUT_SIZE 64
-
-/* Buffers */
-uniform sampler2D colorBuffer;
-uniform sampler2D depthBuffer;
-uniform sampler2D maxzBuffer;
-uniform sampler2D minzBuffer;
-uniform sampler2DArray planarDepth;
-
-#define cameraForward ViewMatrixInverse[2].xyz
-#define cameraPos ViewMatrixInverse[3].xyz
-#define cameraVec \
- ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
-#define viewCameraVec \
- ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0))
-
-/* ------- Structures -------- */
-
-/* ------ Lights ----- */
-struct LightData {
- vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */
- vec4 color_spec; /* w : Spec Intensity */
- vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */
- vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */
- vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */
- vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */
-};
-
-/* convenience aliases */
-#define l_color color_spec.rgb
-#define l_spec color_spec.a
-#define l_position position_influence.xyz
-#define l_influence position_influence.w
-#define l_sizex rightvec_sizex.w
-#define l_sizey upvec_sizey.w
-#define l_right rightvec_sizex.xyz
-#define l_up upvec_sizey.xyz
-#define l_forward forwardvec_type.xyz
-#define l_type forwardvec_type.w
-#define l_spot_size spotdata_radius_shadow.x
-#define l_spot_blend spotdata_radius_shadow.y
-#define l_radius spotdata_radius_shadow.z
-#define l_shadowid spotdata_radius_shadow.w
-
-/* ------ Shadows ----- */
-#ifndef MAX_CASCADE_NUM
-# define MAX_CASCADE_NUM 4
-#endif
-
-struct ShadowData {
- vec4 near_far_bias_id;
- vec4 contact_shadow_data;
-};
-
-struct ShadowCubeData {
- mat4 shadowmat;
- vec4 position;
-};
-
-struct ShadowCascadeData {
- mat4 shadowmat[MAX_CASCADE_NUM];
- vec4 split_start_distances;
- vec4 split_end_distances;
- vec4 shadow_vec_id;
-};
-
-/* convenience aliases */
-#define sh_near near_far_bias_id.x
-#define sh_far near_far_bias_id.y
-#define sh_bias near_far_bias_id.z
-#define sh_data_index near_far_bias_id.w
-#define sh_contact_dist contact_shadow_data.x
-#define sh_contact_offset contact_shadow_data.y
-#define sh_contact_spread contact_shadow_data.z
-#define sh_contact_thickness contact_shadow_data.w
-#define sh_shadow_vec shadow_vec_id.xyz
-#define sh_tex_index shadow_vec_id.w
-
-/* ------ Render Passes ----- */
-layout(std140) uniform renderpass_block
-{
- bool renderPassDiffuse;
- bool renderPassDiffuseLight;
- bool renderPassGlossy;
- bool renderPassGlossyLight;
- bool renderPassEmit;
- bool renderPassSSSColor;
- bool renderPassEnvironment;
-};
-
-vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light)
-{
- return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0);
-}
-
-vec3 render_pass_sss_mask(vec3 sss_color)
-{
- return renderPassSSSColor ? sss_color : vec3(0.0);
-}
-
-vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light)
-{
- return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0);
-}
-
-vec3 render_pass_emission_mask(vec3 emission_light)
-{
- return renderPassEmit ? emission_light : vec3(0.0);
-}
-
-/* ------- Convenience functions --------- */
-
-vec3 mul(mat3 m, vec3 v)
-{
- return m * v;
-}
-mat3 mul(mat3 m1, mat3 m2)
-{
- return m1 * m2;
-}
-vec3 transform_direction(mat4 m, vec3 v)
-{
- return mat3(m) * v;
-}
-vec3 transform_point(mat4 m, vec3 v)
-{
- return (m * vec4(v, 1.0)).xyz;
-}
-vec3 project_point(mat4 m, vec3 v)
-{
- vec4 tmp = m * vec4(v, 1.0);
- return tmp.xyz / tmp.w;
-}
-
-#define min3(a, b, c) min(a, min(b, c))
-#define min4(a, b, c, d) min(a, min3(b, c, d))
-#define min5(a, b, c, d, e) min(a, min4(b, c, d, e))
-#define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f))
-#define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g))
-#define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h))
-#define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i))
-
-#define max3(a, b, c) max(a, max(b, c))
-#define max4(a, b, c, d) max(a, max3(b, c, d))
-#define max5(a, b, c, d, e) max(a, max4(b, c, d, e))
-#define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f))
-#define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g))
-#define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h))
-#define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i))
-
-#define avg3(a, b, c) (a + b + c) * (1.0 / 3.0)
-#define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0)
-#define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0)
-#define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0)
-#define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0)
-#define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0)
-#define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0)
-
-float min_v2(vec2 v)
-{
- return min(v.x, v.y);
-}
-float min_v3(vec3 v)
-{
- return min(v.x, min(v.y, v.z));
-}
-float min_v4(vec4 v)
-{
- return min(min(v.x, v.y), min(v.z, v.w));
-}
-float max_v2(vec2 v)
-{
- return max(v.x, v.y);
-}
-float max_v3(vec3 v)
-{
- return max(v.x, max(v.y, v.z));
-}
-float max_v4(vec4 v)
-{
- return max(max(v.x, v.y), max(v.z, v.w));
-}
-
-float sum(vec2 v)
-{
- return dot(vec2(1.0), v);
-}
-float sum(vec3 v)
-{
- return dot(vec3(1.0), v);
-}
-float sum(vec4 v)
-{
- return dot(vec4(1.0), v);
-}
-
-float avg(vec2 v)
-{
- return dot(vec2(1.0 / 2.0), v);
-}
-float avg(vec3 v)
-{
- return dot(vec3(1.0 / 3.0), v);
-}
-float avg(vec4 v)
-{
- return dot(vec4(1.0 / 4.0), v);
-}
-
-float saturate(float a)
-{
- return clamp(a, 0.0, 1.0);
-}
-vec2 saturate(vec2 a)
-{
- return clamp(a, 0.0, 1.0);
-}
-vec3 saturate(vec3 a)
-{
- return clamp(a, 0.0, 1.0);
-}
-vec4 saturate(vec4 a)
-{
- return clamp(a, 0.0, 1.0);
-}
-
-float distance_squared(vec2 a, vec2 b)
-{
- a -= b;
- return dot(a, a);
-}
-float distance_squared(vec3 a, vec3 b)
-{
- a -= b;
- return dot(a, a);
-}
-float len_squared(vec3 a)
-{
- return dot(a, a);
-}
-
-float inverse_distance(vec3 V)
-{
- return max(1 / length(V), 1e-8);
-}
-
-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 */
-float fast_sqrt(float v)
-{
- return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
-}
-
-vec2 fast_sqrt(vec2 v)
-{
- return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
-}
-
-/* [Eberly2014] GPGPU Programming for Games and Science */
-float fast_acos(float v)
-{
- float res = -0.156583 * abs(v) + M_PI_2;
- res *= fast_sqrt(1.0 - abs(v));
- return (v >= 0) ? res : M_PI - res;
-}
-
-vec2 fast_acos(vec2 v)
-{
- vec2 res = -0.156583 * abs(v) + M_PI_2;
- res *= fast_sqrt(1.0 - abs(v));
- v.x = (v.x >= 0) ? res.x : M_PI - res.x;
- v.y = (v.y >= 0) ? res.y : M_PI - res.y;
- return v;
-}
-
-float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal)
-{
- return dot(planenormal, planeorigin - lineorigin);
-}
-
-float line_plane_intersect_dist(vec3 lineorigin,
- vec3 linedirection,
- vec3 planeorigin,
- vec3 planenormal)
-{
- return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
-}
-
-float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane)
-{
- vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz));
- vec3 h = lineorigin - plane_co;
- return -dot(plane.xyz, h) / dot(plane.xyz, linedirection);
-}
-
-vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
-{
- float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal);
- return lineorigin + linedirection * dist;
-}
-
-vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane)
-{
- float dist = line_plane_intersect_dist(lineorigin, linedirection, plane);
- return lineorigin + linedirection * dist;
-}
-
-float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
-{
- /* aligned plane normal */
- vec3 L = planeorigin - lineorigin;
- float diskdist = length(L);
- vec3 planenormal = -normalize(L);
- return -diskdist / dot(planenormal, linedirection);
-}
-
-vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
-{
- float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin);
- if (dist < 0) {
- /* if intersection is behind we fake the intersection to be
- * really far and (hopefully) not inside the radius of interest */
- dist = 1e16;
- }
- return lineorigin + linedirection * dist;
-}
-
-float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection)
-{
- float a = dot(linedirection, linedirection);
- float b = dot(linedirection, lineorigin);
- float c = dot(lineorigin, lineorigin) - 1;
-
- float dist = 1e15;
- float determinant = b * b - a * c;
- if (determinant >= 0) {
- dist = (sqrt(determinant) - b) / a;
- }
-
- return dist;
-}
-
-float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
-{
- /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
- */
- vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection;
- vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
- vec3 furthestplane = max(firstplane, secondplane);
-
- return min_v3(furthestplane);
-}
-
-/* Return texture coordinates to sample Surface LUT */
-vec2 lut_coords(float cosTheta, float roughness)
-{
- float theta = acos(cosTheta);
- vec2 coords = vec2(roughness, theta / M_PI_2);
-
- /* scale and bias coordinates, for correct filtered lookup */
- return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
-}
-
-vec2 lut_coords_ltc(float cosTheta, float roughness)
-{
- vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta));
-
- /* scale and bias coordinates, for correct filtered lookup */
- return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
-}
-
-/* -- Tangent Space conversion -- */
-vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B)
-{
- return T * vector.x + B * vector.y + N * vector.z;
-}
-
-vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B)
-{
- return vec3(dot(T, vector), dot(B, vector), dot(N, vector));
-}
-
-void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
-{
- vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
- T = normalize(cross(UpVector, N));
- B = cross(N, T);
-}
-
-/* ---- Opengl Depth conversion ---- */
-
-float linear_depth(bool is_persp, float z, float zf, float zn)
-{
- if (is_persp) {
- return (zn * zf) / (z * (zn - zf) + zf);
- }
- else {
- return (z * 2.0 - 1.0) * zf;
- }
-}
-
-float buffer_depth(bool is_persp, float z, float zf, float zn)
-{
- if (is_persp) {
- return (zf * (zn - z)) / (z * (zn - zf));
- }
- else {
- return (z / (zf * 2.0)) + 0.5;
- }
-}
-
-float get_view_z_from_depth(float depth)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- float d = 2.0 * depth - 1.0;
- return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
- }
- else {
- return viewVecs[0].z + depth * viewVecs[1].z;
- }
-}
-
-float get_depth_from_view_z(float z)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
- return d * 0.5 + 0.5;
- }
- else {
- return (z - viewVecs[0].z) / viewVecs[1].z;
- }
-}
-
-vec2 get_uvs_from_view(vec3 view)
-{
- vec3 ndc = project_point(ProjectionMatrix, view);
- return ndc.xy * 0.5 + 0.5;
-}
-
-vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth);
- }
- else {
- return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz;
- }
-}
-
-vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
-{
- return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz;
-}
-
-vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness)
+vec3 specular_dominant_dir(vec3 N, vec3 V, float roughness)
{
vec3 R = -reflect(V, N);
float smoothness = 1.0 - roughness;
@@ -489,13 +9,6 @@ vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness)
return normalize(mix(N, R, fac));
}
-float specular_occlusion(float NV, float AO, float roughness)
-{
- return saturate(pow(NV + AO, roughness) - 1.0 + AO);
-}
-
-/* --- Refraction utils --- */
-
float ior_from_f0(float f0)
{
float f = sqrt(f0);
@@ -508,7 +21,7 @@ float f0_from_ior(float eta)
return A * A;
}
-vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior)
+vec3 refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior)
{
/* TODO: This a bad approximation. Better approximation should fit
* the refracted vector and roughness into the best prefiltered reflection
@@ -527,128 +40,6 @@ vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float
return R;
}
-float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior)
-{
- const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE;
-
- vec3 coords;
- /* Try to compensate for the low resolution and interpolation error. */
- coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) +
- (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) :
- (0.9 + lut_scale_bias_texel_size.z) * ior * ior;
- coords.y = 1.0 - saturate(NV);
- coords.xy *= lut_scale_bias_texel_size.x;
- coords.xy += lut_scale_bias_texel_size.y;
-
- const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */
- const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */
-
- float mip = roughness * lut_lvl_scale;
- float mip_floor = floor(mip);
-
- coords.z = lut_lvl_ofs + mip_floor + 1.0;
- float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r;
-
- coords.z -= 1.0;
- float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r;
-
- float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z);
-
- return btdf;
-}
-
-/* ---- Encode / Decode Normal buffer data ---- */
-/* From http://aras-p.info/texts/CompactNormalStorage.html
- * Using Method #4: Spheremap Transform */
-vec2 normal_encode(vec3 n, vec3 view)
-{
- float p = sqrt(n.z * 8.0 + 8.0);
- return n.xy / p + 0.5;
-}
-
-vec3 normal_decode(vec2 enc, vec3 view)
-{
- vec2 fenc = enc * 4.0 - 2.0;
- float f = dot(fenc, fenc);
- float g = sqrt(1.0 - f / 4.0);
- vec3 n;
- n.xy = fenc * g;
- n.z = 1 - f / 2;
- return n;
-}
-
-/* ---- RGBM (shared multiplier) encoding ---- */
-/* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */
-
-/* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */
-#define RGBM_MAX_RANGE 512.0
-
-vec4 rgbm_encode(vec3 rgb)
-{
- float maxRGB = max_v3(rgb);
- float M = maxRGB / RGBM_MAX_RANGE;
- M = ceil(M * 255.0) / 255.0;
- return vec4(rgb / (M * RGBM_MAX_RANGE), M);
-}
-
-vec3 rgbm_decode(vec4 data)
-{
- return data.rgb * (data.a * RGBM_MAX_RANGE);
-}
-
-/* ---- RGBE (shared exponent) encoding ---- */
-vec4 rgbe_encode(vec3 rgb)
-{
- float maxRGB = max_v3(rgb);
- float fexp = ceil(log2(maxRGB));
- return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0);
-}
-
-vec3 rgbe_decode(vec4 data)
-{
- float fexp = data.a * 255.0 - 128.0;
- return data.rgb * exp2(fexp);
-}
-
-#if 1
-# define irradiance_encode rgbe_encode
-# define irradiance_decode rgbe_decode
-#else /* No ecoding (when using floating point format) */
-# define irradiance_encode(X) (X).rgbb
-# define irradiance_decode(X) (X).rgb
-#endif
-
-/* Irradiance Visibility Encoding */
-#if 1
-vec4 visibility_encode(vec2 accum, float range)
-{
- accum /= range;
-
- vec4 data;
- data.x = fract(accum.x);
- data.y = floor(accum.x) / 255.0;
- data.z = fract(accum.y);
- data.w = floor(accum.y) / 255.0;
-
- return data;
-}
-
-vec2 visibility_decode(vec4 data, float range)
-{
- return (data.xz + data.yw * 255.0) * range;
-}
-#else /* No ecoding (when using floating point format) */
-vec4 visibility_encode(vec2 accum, float range)
-{
- return accum.xyxy;
-}
-
-vec2 visibility_decode(vec4 data, float range)
-{
- return data.xy;
-}
-#endif
-
/* Fresnel monochromatic, perfect mirror */
float F_eta(float eta, float cos_theta)
{
@@ -766,265 +157,3 @@ float cone_cosine(float r)
/* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/
return exp2(-3.32193 * r * r);
}
-
-/* --------- Closure ---------- */
-
-#ifdef VOLUMETRICS
-
-struct Closure {
- vec3 absorption;
- vec3 scatter;
- vec3 emission;
- float anisotropy;
-};
-
-Closure nodetree_exec(void); /* Prototype */
-
-# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0)
-
-Closure closure_mix(Closure cl1, Closure cl2, float fac)
-{
- Closure cl;
- cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
- cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
- cl.emission = mix(cl1.emission, cl2.emission, fac);
- cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
- return cl;
-}
-
-Closure closure_add(Closure cl1, Closure cl2)
-{
- Closure cl;
- cl.absorption = cl1.absorption + cl2.absorption;
- cl.scatter = cl1.scatter + cl2.scatter;
- cl.emission = cl1.emission + cl2.emission;
- cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
- return cl;
-}
-
-Closure closure_emission(vec3 rgb)
-{
- Closure cl = CLOSURE_DEFAULT;
- cl.emission = rgb;
- return cl;
-}
-
-#else /* VOLUMETRICS */
-
-struct Closure {
- vec3 radiance;
- vec3 transmittance;
- float holdout;
-# ifdef USE_SSS
- vec3 sss_irradiance;
- vec3 sss_albedo;
- float sss_radius;
-# endif
- vec4 ssr_data;
- vec2 ssr_normal;
- int flag;
-};
-
-Closure nodetree_exec(void); /* Prototype */
-
-# define FLAG_TEST(flag, val) (((flag) & (val)) != 0)
-
-# define CLOSURE_SSR_FLAG 1
-# define CLOSURE_SSS_FLAG 2
-# define CLOSURE_HOLDOUT_FLAG 4
-
-# ifdef USE_SSS
-# define CLOSURE_DEFAULT \
- Closure(vec3(0.0), vec3(0.0), 0.0, vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0)
-# else
-# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0)
-# endif
-
-uniform int outputSsrId = 1;
-uniform int outputSssId = 1;
-
-void closure_load_ssr_data(
- vec3 ssr_spec, float roughness, vec3 N, vec3 viewVec, int ssr_id, inout Closure cl)
-{
- /* Still encode to avoid artifacts in the SSR pass. */
- vec3 vN = normalize(mat3(ViewMatrix) * N);
- cl.ssr_normal = normal_encode(vN, viewVec);
-
- if (ssr_id == outputSsrId) {
- cl.ssr_data = vec4(ssr_spec, roughness);
- cl.flag |= CLOSURE_SSR_FLAG;
- }
-}
-
-void closure_load_sss_data(
- float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl)
-{
-# ifdef USE_SSS
- if (sss_id == outputSssId) {
- cl.sss_irradiance = sss_irradiance;
- cl.sss_radius = radius;
- cl.sss_albedo = sss_albedo;
- cl.flag |= CLOSURE_SSS_FLAG;
- cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0));
- }
- else
-# endif
- {
- cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo);
- }
-}
-
-Closure closure_mix(Closure cl1, Closure cl2, float fac)
-{
- Closure cl;
- cl.holdout = mix(cl1.holdout, cl2.holdout, fac);
-
- if (FLAG_TEST(cl1.flag, CLOSURE_HOLDOUT_FLAG)) {
- fac = 1.0;
- }
- else if (FLAG_TEST(cl2.flag, CLOSURE_HOLDOUT_FLAG)) {
- fac = 0.0;
- }
-
- cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac);
- cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
- cl.flag = cl1.flag | cl2.flag;
- cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac);
- bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
- /* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz).*/
- cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
- cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
-
-# ifdef USE_SSS
- cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac);
- bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
- /* It also does not make sense to mix SSS radius or irradiance. */
- cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
- cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
-# endif
- return cl;
-}
-
-Closure closure_add(Closure cl1, Closure cl2)
-{
- Closure cl;
- cl.transmittance = cl1.transmittance + cl2.transmittance;
- cl.radiance = cl1.radiance + cl2.radiance;
- cl.holdout = cl1.holdout + cl2.holdout;
- cl.flag = cl1.flag | cl2.flag;
- cl.ssr_data = cl1.ssr_data + cl2.ssr_data;
- bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
- /* When mixing SSR don't blend roughness and normals.*/
- cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
- cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
-
-# ifdef USE_SSS
- cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo;
- bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
- /* It also does not make sense to mix SSS radius or irradiance. */
- cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
- cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
-# endif
- return cl;
-}
-
-Closure closure_emission(vec3 rgb)
-{
- Closure cl = CLOSURE_DEFAULT;
- cl.radiance = rgb;
- return cl;
-}
-
-/* Breaking this across multiple lines causes issues for some older GLSL compilers. */
-/* clang-format off */
-# if defined(MESH_SHADER) && !defined(DEPTH_SHADER)
-/* clang-format on */
-# ifndef USE_ALPHA_BLEND
-layout(location = 0) out vec4 outRadiance;
-layout(location = 1) out vec2 ssrNormals;
-layout(location = 2) out vec4 ssrData;
-# ifdef USE_SSS
-layout(location = 3) out vec3 sssIrradiance;
-layout(location = 4) out float sssRadius;
-layout(location = 5) out vec3 sssAlbedo;
-# endif
-# else /* USE_ALPHA_BLEND */
-/* Use dual source blending to be able to make a whole range of effects. */
-layout(location = 0, index = 0) out vec4 outRadiance;
-layout(location = 0, index = 1) out vec4 outTransmittance;
-# endif /* USE_ALPHA_BLEND */
-
-# if defined(USE_ALPHA_BLEND)
-/* Prototype because this file is included before volumetric_lib.glsl */
-void volumetric_resolve(vec2 frag_uvs,
- float frag_depth,
- out vec3 transmittance,
- out vec3 scattering);
-# endif
-
-# define NODETREE_EXEC
-void main()
-{
- Closure cl = nodetree_exec();
-
- float holdout = saturate(1.0 - cl.holdout);
- float transmit = saturate(avg(cl.transmittance));
- float alpha = 1.0 - transmit;
-
-# ifdef USE_ALPHA_BLEND
- vec2 uvs = gl_FragCoord.xy * volCoordScale.zw;
- vec3 vol_transmit, vol_scatter;
- volumetric_resolve(uvs, gl_FragCoord.z, vol_transmit, vol_scatter);
-
- /* Removes part of the volume scattering that have
- * already been added to the destination pixels.
- * Since we do that using the blending pipeline we need to account for material transmittance. */
- vol_scatter -= vol_scatter * cl.transmittance;
-
- cl.radiance = cl.radiance * holdout * vol_transmit + vol_scatter;
- outRadiance = vec4(cl.radiance, alpha * holdout);
- outTransmittance = vec4(cl.transmittance, transmit) * holdout;
-# else
- outRadiance = vec4(cl.radiance, holdout);
- ssrNormals = cl.ssr_normal;
- ssrData = cl.ssr_data;
-# ifdef USE_SSS
- sssIrradiance = cl.sss_irradiance;
- sssRadius = cl.sss_radius;
- sssAlbedo = cl.sss_albedo;
-# endif
-# endif
-
- /* For Probe capture */
-# ifdef USE_SSS
- float fac = float(!sssToggle);
-
- /* TODO(fclem) we shouldn't need this.
- * Just disable USE_SSS when USE_REFRACTION is enabled. */
-# ifdef USE_REFRACTION
- /* SSRefraction pass is done after the SSS pass.
- * In order to not loose the diffuse light totally we
- * need to merge the SSS radiance to the main radiance. */
- fac = 1.0;
-# endif
-
- outRadiance.rgb += cl.sss_irradiance.rgb * cl.sss_albedo.rgb * fac;
-# endif
-
-# ifdef LOOKDEV
- gl_FragDepth = 0.0;
-# endif
-
-# ifndef USE_ALPHA_BLEND
- float alpha_div = 1.0 / max(1e-8, alpha);
- outRadiance.rgb *= alpha_div;
- ssrData.rgb *= alpha_div;
-# ifdef USE_SSS
- sssAlbedo.rgb *= alpha_div;
-# endif
-# endif
-}
-
-# endif /* MESH_SHADER */
-
-#endif /* VOLUMETRICS */
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
index f05b3396428..2b2da884fde 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
@@ -1,3 +1,4 @@
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
out vec4 FragColor;
@@ -5,8 +6,8 @@ void main()
{
vec3 N, T, B, V;
- float NV = (1.0 - (clamp(gl_FragCoord.y / BRDF_LUT_SIZE, 1e-4, 0.9999)));
- float sqrtRoughness = clamp(gl_FragCoord.x / BRDF_LUT_SIZE, 1e-4, 0.9999);
+ float NV = (1.0 - (clamp(gl_FragCoord.y / b, 1e-4, 0.9999)));
+ float sqrtRoughness = clamp(gl_FragCoord.x / LUT_SIZE, 1e-4, 0.9999);
float a = sqrtRoughness * sqrtRoughness;
float a2 = a * a;
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
index 5f2b719095e..066ea58e2bf 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
@@ -1,6 +1,7 @@
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+
uniform sampler1D texHammersley;
-uniform sampler2D texJitter;
uniform float sampleCount;
uniform float invSampleCount;
@@ -8,8 +9,7 @@ vec2 jitternoise = vec2(0.0);
#ifndef UTIL_TEX
# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
+
#endif /* UTIL_TEX */
void setup_noise(void)
@@ -17,6 +17,11 @@ void setup_noise(void)
jitternoise = texelfetch_noise_tex(gl_FragCoord.xy).rg; /* Global variable */
}
+vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B)
+{
+ return T * vector.x + B * vector.y + N * vector.z;
+}
+
#ifdef HAMMERSLEY_SIZE
vec3 hammersley_3d(float i, float invsamplenbr)
{
diff --git a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
index 1389a9763c0..d815d9d4e6b 100644
--- a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
@@ -1,3 +1,4 @@
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
uniform float a2;
@@ -7,8 +8,8 @@ void main()
{
vec3 N, T, B, V;
- float x = gl_FragCoord.x / BRDF_LUT_SIZE;
- float y = gl_FragCoord.y / BRDF_LUT_SIZE;
+ float x = gl_FragCoord.x / LUT_SIZE;
+ float y = gl_FragCoord.y / LUT_SIZE;
/* There is little variation if ior > 1.0 so we
* maximize LUT precision for ior < 1.0 */
x = x * 1.1;
diff --git a/source/blender/draw/engines/eevee/shaders/closure_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_lib.glsl
new file mode 100644
index 00000000000..e572245ace9
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/closure_lib.glsl
@@ -0,0 +1,181 @@
+
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(renderpass_lib.glsl)
+
+#ifndef VOLUMETRICS
+
+uniform int outputSsrId = 1;
+uniform int outputSssId = 1;
+
+#endif
+
+struct Closure {
+#ifdef VOLUMETRICS
+ vec3 absorption;
+ vec3 scatter;
+ vec3 emission;
+ float anisotropy;
+
+#else /* SURFACE */
+ vec3 radiance;
+ vec3 transmittance;
+ float holdout;
+ vec4 ssr_data;
+ vec2 ssr_normal;
+ int flag;
+# ifdef USE_SSS
+ vec3 sss_irradiance;
+ vec3 sss_albedo;
+ float sss_radius;
+# endif
+
+#endif
+};
+
+/* Prototype */
+Closure nodetree_exec(void);
+
+/* clang-format off */
+/* Avoid multiline defines. */
+#ifdef VOLUMETRICS
+# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), vec3(0), 0.0)
+#elif !defined(USE_SSS)
+# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0)
+#else
+# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0, vec3(0), vec3(0), 0.0)
+#endif
+/* clang-format on */
+
+#define FLAG_TEST(flag, val) (((flag) & (val)) != 0)
+
+#define CLOSURE_SSR_FLAG 1
+#define CLOSURE_SSS_FLAG 2
+#define CLOSURE_HOLDOUT_FLAG 4
+
+#ifdef VOLUMETRICS
+Closure closure_mix(Closure cl1, Closure cl2, float fac)
+{
+ Closure cl;
+ cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
+ cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
+ cl.emission = mix(cl1.emission, cl2.emission, fac);
+ cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
+ return cl;
+}
+
+Closure closure_add(Closure cl1, Closure cl2)
+{
+ Closure cl;
+ cl.absorption = cl1.absorption + cl2.absorption;
+ cl.scatter = cl1.scatter + cl2.scatter;
+ cl.emission = cl1.emission + cl2.emission;
+ cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
+ return cl;
+}
+
+Closure closure_emission(vec3 rgb)
+{
+ Closure cl = CLOSURE_DEFAULT;
+ cl.emission = rgb;
+ return cl;
+}
+
+#else /* SURFACE */
+
+Closure closure_mix(Closure cl1, Closure cl2, float fac)
+{
+ Closure cl;
+ cl.holdout = mix(cl1.holdout, cl2.holdout, fac);
+
+ if (FLAG_TEST(cl1.flag, CLOSURE_HOLDOUT_FLAG)) {
+ fac = 1.0;
+ }
+ else if (FLAG_TEST(cl2.flag, CLOSURE_HOLDOUT_FLAG)) {
+ fac = 0.0;
+ }
+
+ cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac);
+ cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
+ cl.flag = cl1.flag | cl2.flag;
+ cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac);
+ bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
+ /* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz).*/
+ cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
+ cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
+
+# ifdef USE_SSS
+ cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac);
+ bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
+ /* It also does not make sense to mix SSS radius or irradiance. */
+ cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
+ cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
+# endif
+ return cl;
+}
+
+Closure closure_add(Closure cl1, Closure cl2)
+{
+ Closure cl;
+ cl.transmittance = cl1.transmittance + cl2.transmittance;
+ cl.radiance = cl1.radiance + cl2.radiance;
+ cl.holdout = cl1.holdout + cl2.holdout;
+ cl.flag = cl1.flag | cl2.flag;
+ cl.ssr_data = cl1.ssr_data + cl2.ssr_data;
+ bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
+ /* When mixing SSR don't blend roughness and normals.*/
+ cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
+ cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
+
+# ifdef USE_SSS
+ cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo;
+ bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
+ /* It also does not make sense to mix SSS radius or irradiance. */
+ cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
+ cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
+# endif
+ return cl;
+}
+
+Closure closure_emission(vec3 rgb)
+{
+ Closure cl = CLOSURE_DEFAULT;
+ cl.radiance = rgb;
+ return cl;
+}
+
+#endif
+
+#ifndef VOLUMETRICS
+
+void closure_load_ssr_data(
+ vec3 ssr_spec, float roughness, vec3 N, vec3 viewVec, int ssr_id, inout Closure cl)
+{
+ /* Still encode to avoid artifacts in the SSR pass. */
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ cl.ssr_normal = normal_encode(vN, viewVec);
+
+ if (ssr_id == outputSsrId) {
+ cl.ssr_data = vec4(ssr_spec, roughness);
+ cl.flag |= CLOSURE_SSR_FLAG;
+ }
+}
+
+void closure_load_sss_data(
+ float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl)
+{
+# ifdef USE_SSS
+ if (sss_id == outputSssId) {
+ cl.sss_irradiance = sss_irradiance;
+ cl.sss_radius = radius;
+ cl.sss_albedo = sss_albedo;
+ cl.flag |= CLOSURE_SSS_FLAG;
+ cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0));
+ }
+ else
+# endif
+ {
+ cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo);
+ }
+}
+
+#endif
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl
index bc7879763c3..bf33caf9854 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl
@@ -1,32 +1,8 @@
-#ifndef LIT_SURFACE_UNIFORM
-# define LIT_SURFACE_UNIFORM
-
-uniform float refractionDepth;
-
-# ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-# endif /* UTIL_TEX */
-
-in vec3 worldPosition;
-in vec3 viewPosition;
-
-in vec3 worldNormal;
-in vec3 viewNormal;
-
-# ifdef HAIR_SHADER
-in vec3 hairTangent; /* world space */
-in float hairThickTime;
-in float hairThickness;
-in float hairTime;
-flat in int hairStrandID;
-
-uniform int hairThicknessRes = 1;
-# endif
-
-#endif /* LIT_SURFACE_UNIFORM */
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl)
+#pragma BLENDER_REQUIRE(ssr_lib.glsl)
/**
* AUTO CONFIG
@@ -209,7 +185,7 @@ void CLOSURE_NAME(vec3 N
vec3 V = cameraVec;
- vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
+ vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
/* ---------------------------------------------------------------- */
/* -------------------- SCENE LIGHTS LIGHTING --------------------- */
@@ -328,11 +304,11 @@ void CLOSURE_NAME(vec3 N
# endif
# ifdef CLOSURE_GLOSSY
- vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
+ vec3 spec_dir = specular_dominant_dir(N, V, roughnessSquared);
# endif
# ifdef CLOSURE_CLEARCOAT
- vec3 C_spec_dir = get_specular_reflection_dominant_dir(C_N, V, C_roughnessSquared);
+ vec3 C_spec_dir = specular_dominant_dir(C_N, V, C_roughnessSquared);
# endif
# ifdef CLOSURE_REFRACTION
@@ -345,7 +321,7 @@ void CLOSURE_NAME(vec3 N
line_plane_intersect(
worldPosition, refr_V, worldPosition - N * refractionDepth, N) :
worldPosition;
- vec3 refr_dir = get_specular_refraction_dominant_dir(N, refr_V, roughness, final_ior);
+ vec3 refr_dir = refraction_dominant_dir(N, refr_V, roughness, final_ior);
# endif
# ifdef CLOSURE_REFRACTION
@@ -485,7 +461,7 @@ void CLOSURE_NAME(vec3 N
# endif
# ifdef CLOSURE_REFRACTION
- float btdf = get_btdf_lut(utilTex, NV, roughness, ior);
+ float btdf = get_btdf_lut(NV, roughness, ior);
out_refr += refr_accum.rgb * btdf;
# endif
diff --git a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
index 759b4098b37..a6c9eebaff2 100644
--- a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
@@ -2,7 +2,6 @@
layout(std140) uniform common_block
{
mat4 pastViewProjectionMatrix;
- vec4 viewVecs[2];
vec2 mipRatio[10]; /* To correct mip level texel misalignment */
/* Ambient Occlusion */
vec4 aoParameters[2];
@@ -70,3 +69,9 @@ layout(std140) uniform common_block
#define ssrQuality ssrParameters.x
#define ssrThickness ssrParameters.y
#define ssrPixelSize ssrParameters.zw
+
+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);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl
new file mode 100644
index 00000000000..95a585f0d9c
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl
@@ -0,0 +1,65 @@
+
+#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
+
+/* ---------------------------------------------------------------------- */
+/** \name Utiltex
+ *
+ * Utiltex is a sampler2DArray that stores a number of useful small utilitary textures and lookup
+ * tables.
+ * \{ */
+
+uniform sampler2DArray utilTex;
+
+#define LUT_SIZE 64
+
+#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
+
+/* Return texture coordinates to sample Surface LUT */
+vec2 lut_coords(float cosTheta, float roughness)
+{
+ float theta = acos(cosTheta);
+ vec2 coords = vec2(roughness, theta / M_PI_2);
+
+ /* scale and bias coordinates, for correct filtered lookup */
+ return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
+}
+
+vec2 lut_coords_ltc(float cosTheta, float roughness)
+{
+ vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta));
+
+ /* scale and bias coordinates, for correct filtered lookup */
+ return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
+}
+
+float get_btdf_lut(float NV, float roughness, float ior)
+{
+ const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE;
+
+ vec3 coords;
+ /* Try to compensate for the low resolution and interpolation error. */
+ coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) +
+ (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) :
+ (0.9 + lut_scale_bias_texel_size.z) * ior * ior;
+ coords.y = 1.0 - saturate(NV);
+ coords.xy *= lut_scale_bias_texel_size.x;
+ coords.xy += lut_scale_bias_texel_size.y;
+
+ const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */
+ const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */
+
+ float mip = roughness * lut_lvl_scale;
+ float mip_floor = floor(mip);
+
+ coords.z = lut_lvl_ofs + mip_floor + 1.0;
+ float btdf_high = textureLod(utilTex, coords, 0.0).r;
+
+ coords.z -= 1.0;
+ float btdf_low = textureLod(utilTex, coords, 0.0).r;
+
+ float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z);
+
+ return btdf;
+}
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/concentric_samples_lib.glsl b/source/blender/draw/engines/eevee/shaders/concentric_samples_lib.glsl
deleted file mode 100644
index 7e0e5945c54..00000000000
--- a/source/blender/draw/engines/eevee/shaders/concentric_samples_lib.glsl
+++ /dev/null
@@ -1,265 +0,0 @@
-/* Precomputed table of concentric samples.
- * Generated using this algorithm http://l2program.co.uk/900/concentric-disk-sampling
- * Sorted by radius then by rotation angle.
- * This way it's better for cache usage and for
- * easily restricting to a certain number of
- * sample while still having a circular kernel. */
-
-#define CONCENTRIC_SAMPLE_NUM 256
-const vec2 concentric[CONCENTRIC_SAMPLE_NUM] = vec2[CONCENTRIC_SAMPLE_NUM](
- vec2(0.0441941738242, 0.0441941738242),
- vec2(-0.0441941738242, -0.0441941738242),
- vec2(-0.0441941738242, 0.0441941738242),
- vec2(0.0441941738242, -0.0441941738242),
- vec2(0.181111092429, 0.0485285709567),
- vec2(0.132582521472, 0.132582521472),
- vec2(-0.181111092429, 0.0485285709567),
- vec2(0.0485285709567, 0.181111092429),
- vec2(-0.181111092429, -0.0485285709567),
- vec2(-0.0485285709567, 0.181111092429),
- vec2(-0.132582521472, -0.132582521472),
- vec2(-0.132582521472, 0.132582521472),
- vec2(-0.0485285709567, -0.181111092429),
- vec2(0.0485285709567, -0.181111092429),
- vec2(0.132582521472, -0.132582521472),
- vec2(0.181111092429, -0.0485285709567),
- vec2(0.308652606436, 0.0488857703251),
- vec2(0.278439538809, 0.141872031169),
- vec2(0.220970869121, 0.220970869121),
- vec2(-0.278439538809, 0.141872031169),
- vec2(0.141872031169, 0.278439538809),
- vec2(-0.308652606436, 0.0488857703251),
- vec2(0.0488857703251, 0.308652606436),
- vec2(-0.308652606436, -0.0488857703251),
- vec2(-0.0488857703251, 0.308652606436),
- vec2(-0.278439538809, -0.141872031169),
- vec2(-0.141872031169, 0.278439538809),
- vec2(-0.220970869121, -0.220970869121),
- vec2(-0.220970869121, 0.220970869121),
- vec2(-0.141872031169, -0.278439538809),
- vec2(-0.0488857703251, -0.308652606436),
- vec2(0.0488857703251, -0.308652606436),
- vec2(0.141872031169, -0.278439538809),
- vec2(0.220970869121, -0.220970869121),
- vec2(0.278439538809, -0.141872031169),
- vec2(0.308652606436, -0.0488857703251),
- vec2(0.434749091828, 0.0489844582952),
- vec2(0.41294895701, 0.144497089605),
- vec2(0.370441837162, 0.232764033475),
- vec2(0.309359216769, 0.309359216769),
- vec2(-0.370441837162, 0.232764033475),
- vec2(0.232764033475, 0.370441837162),
- vec2(-0.41294895701, 0.144497089605),
- vec2(0.144497089605, 0.41294895701),
- vec2(-0.434749091828, 0.0489844582952),
- vec2(0.0489844582952, 0.434749091828),
- vec2(-0.434749091828, -0.0489844582952),
- vec2(-0.0489844582952, 0.434749091828),
- vec2(-0.41294895701, -0.144497089605),
- vec2(-0.144497089605, 0.41294895701),
- vec2(-0.370441837162, -0.232764033475),
- vec2(-0.232764033475, 0.370441837162),
- vec2(-0.309359216769, -0.309359216769),
- vec2(-0.309359216769, 0.309359216769),
- vec2(-0.232764033475, -0.370441837162),
- vec2(-0.144497089605, -0.41294895701),
- vec2(-0.0489844582952, -0.434749091828),
- vec2(0.0489844582952, -0.434749091828),
- vec2(0.144497089605, -0.41294895701),
- vec2(0.232764033475, -0.370441837162),
- vec2(0.309359216769, -0.309359216769),
- vec2(0.370441837162, -0.232764033475),
- vec2(0.41294895701, -0.144497089605),
- vec2(0.434749091828, -0.0489844582952),
- vec2(0.560359517677, 0.0490251052956),
- vec2(0.543333277288, 0.14558571287),
- vec2(0.509798130208, 0.237722772229),
- vec2(0.460773024913, 0.322636745447),
- vec2(0.397747564417, 0.397747564417),
- vec2(-0.460773024913, 0.322636745447),
- vec2(0.322636745447, 0.460773024913),
- vec2(-0.509798130208, 0.237722772229),
- vec2(0.237722772229, 0.509798130208),
- vec2(-0.543333277288, 0.14558571287),
- vec2(0.14558571287, 0.543333277288),
- vec2(-0.560359517677, 0.0490251052956),
- vec2(0.0490251052956, 0.560359517677),
- vec2(-0.560359517677, -0.0490251052956),
- vec2(-0.0490251052956, 0.560359517677),
- vec2(-0.543333277288, -0.14558571287),
- vec2(-0.14558571287, 0.543333277288),
- vec2(-0.509798130208, -0.237722772229),
- vec2(-0.237722772229, 0.509798130208),
- vec2(-0.460773024913, -0.322636745447),
- vec2(-0.322636745447, 0.460773024913),
- vec2(-0.397747564417, -0.397747564417),
- vec2(-0.397747564417, 0.397747564417),
- vec2(-0.322636745447, -0.460773024913),
- vec2(-0.237722772229, -0.509798130208),
- vec2(-0.14558571287, -0.543333277288),
- vec2(-0.0490251052956, -0.560359517677),
- vec2(0.0490251052956, -0.560359517677),
- vec2(0.14558571287, -0.543333277288),
- vec2(0.237722772229, -0.509798130208),
- vec2(0.322636745447, -0.460773024913),
- vec2(0.397747564417, -0.397747564417),
- vec2(0.460773024913, -0.322636745447),
- vec2(0.509798130208, -0.237722772229),
- vec2(0.543333277288, -0.14558571287),
- vec2(0.560359517677, -0.0490251052956),
- vec2(0.685748328795, 0.0490456884495),
- vec2(0.671788470355, 0.146138636568),
- vec2(0.644152935937, 0.240256623474),
- vec2(0.603404305327, 0.32948367837),
- vec2(0.550372103135, 0.412003395727),
- vec2(0.486135912066, 0.486135912066),
- vec2(-0.550372103135, 0.412003395727),
- vec2(0.412003395727, 0.550372103135),
- vec2(-0.603404305327, 0.32948367837),
- vec2(0.32948367837, 0.603404305327),
- vec2(-0.644152935937, 0.240256623474),
- vec2(0.240256623474, 0.644152935937),
- vec2(-0.671788470355, 0.146138636568),
- vec2(0.146138636568, 0.671788470355),
- vec2(-0.685748328795, 0.0490456884495),
- vec2(0.0490456884495, 0.685748328795),
- vec2(-0.685748328795, -0.0490456884495),
- vec2(-0.0490456884495, 0.685748328795),
- vec2(-0.671788470355, -0.146138636568),
- vec2(-0.146138636568, 0.671788470355),
- vec2(-0.644152935937, -0.240256623474),
- vec2(-0.240256623474, 0.644152935937),
- vec2(-0.603404305327, -0.32948367837),
- vec2(-0.32948367837, 0.603404305327),
- vec2(-0.550372103135, -0.412003395727),
- vec2(-0.412003395727, 0.550372103135),
- vec2(-0.486135912066, -0.486135912066),
- vec2(-0.486135912066, 0.486135912066),
- vec2(-0.412003395727, -0.550372103135),
- vec2(-0.32948367837, -0.603404305327),
- vec2(-0.240256623474, -0.644152935937),
- vec2(-0.146138636568, -0.671788470355),
- vec2(-0.0490456884495, -0.685748328795),
- vec2(0.0490456884495, -0.685748328795),
- vec2(0.146138636568, -0.671788470355),
- vec2(0.240256623474, -0.644152935937),
- vec2(0.32948367837, -0.603404305327),
- vec2(0.412003395727, -0.550372103135),
- vec2(0.486135912066, -0.486135912066),
- vec2(0.550372103135, -0.412003395727),
- vec2(0.603404305327, -0.32948367837),
- vec2(0.644152935937, -0.240256623474),
- vec2(0.671788470355, -0.146138636568),
- vec2(0.685748328795, -0.0490456884495),
- vec2(0.811017637806, 0.0490575291556),
- vec2(0.799191174395, 0.146457218224),
- vec2(0.775710704038, 0.241721231257),
- vec2(0.740918624869, 0.33346040443),
- vec2(0.695322283745, 0.420336974019),
- vec2(0.639586577995, 0.501084084011),
- vec2(0.574524259714, 0.574524259714),
- vec2(-0.639586577995, 0.501084084011),
- vec2(0.501084084011, 0.639586577995),
- vec2(-0.695322283745, 0.420336974019),
- vec2(0.420336974019, 0.695322283745),
- vec2(-0.740918624869, 0.33346040443),
- vec2(0.33346040443, 0.740918624869),
- vec2(-0.775710704038, 0.241721231257),
- vec2(0.241721231257, 0.775710704038),
- vec2(-0.799191174395, 0.146457218224),
- vec2(0.146457218224, 0.799191174395),
- vec2(-0.811017637806, 0.0490575291556),
- vec2(0.0490575291556, 0.811017637806),
- vec2(-0.811017637806, -0.0490575291556),
- vec2(-0.0490575291556, 0.811017637806),
- vec2(-0.799191174395, -0.146457218224),
- vec2(-0.146457218224, 0.799191174395),
- vec2(-0.775710704038, -0.241721231257),
- vec2(-0.241721231257, 0.775710704038),
- vec2(-0.740918624869, -0.33346040443),
- vec2(-0.33346040443, 0.740918624869),
- vec2(-0.695322283745, -0.420336974019),
- vec2(-0.420336974019, 0.695322283745),
- vec2(-0.639586577995, -0.501084084011),
- vec2(-0.501084084011, 0.639586577995),
- vec2(-0.574524259714, -0.574524259714),
- vec2(-0.574524259714, 0.574524259714),
- vec2(-0.501084084011, -0.639586577995),
- vec2(-0.420336974019, -0.695322283745),
- vec2(-0.33346040443, -0.740918624869),
- vec2(-0.241721231257, -0.775710704038),
- vec2(-0.146457218224, -0.799191174395),
- vec2(-0.0490575291556, -0.811017637806),
- vec2(0.0490575291556, -0.811017637806),
- vec2(0.146457218224, -0.799191174395),
- vec2(0.241721231257, -0.775710704038),
- vec2(0.33346040443, -0.740918624869),
- vec2(0.420336974019, -0.695322283745),
- vec2(0.501084084011, -0.639586577995),
- vec2(0.574524259714, -0.574524259714),
- vec2(0.639586577995, -0.501084084011),
- vec2(0.695322283745, -0.420336974019),
- vec2(0.740918624869, -0.33346040443),
- vec2(0.775710704038, -0.241721231257),
- vec2(0.799191174395, -0.146457218224),
- vec2(0.811017637806, -0.0490575291556),
- vec2(0.936215188832, 0.0490649589778),
- vec2(0.925957819308, 0.146657310975),
- vec2(0.905555462146, 0.242642854784),
- vec2(0.875231649841, 0.335969952699),
- vec2(0.835318616427, 0.425616093506),
- vec2(0.786253657449, 0.510599095327),
- vec2(0.728574338866, 0.589987866609),
- vec2(0.662912607362, 0.662912607362),
- vec2(-0.728574338866, 0.589987866609),
- vec2(0.589987866609, 0.728574338866),
- vec2(-0.786253657449, 0.510599095327),
- vec2(0.510599095327, 0.786253657449),
- vec2(-0.835318616427, 0.425616093506),
- vec2(0.425616093506, 0.835318616427),
- vec2(-0.875231649841, 0.335969952699),
- vec2(0.335969952699, 0.875231649841),
- vec2(-0.905555462146, 0.242642854784),
- vec2(0.242642854784, 0.905555462146),
- vec2(-0.925957819308, 0.146657310975),
- vec2(0.146657310975, 0.925957819308),
- vec2(-0.936215188832, 0.0490649589778),
- vec2(0.0490649589778, 0.936215188832),
- vec2(-0.936215188832, -0.0490649589778),
- vec2(-0.0490649589778, 0.936215188832),
- vec2(-0.925957819308, -0.146657310975),
- vec2(-0.146657310975, 0.925957819308),
- vec2(-0.905555462146, -0.242642854784),
- vec2(-0.242642854784, 0.905555462146),
- vec2(-0.875231649841, -0.335969952699),
- vec2(-0.335969952699, 0.875231649841),
- vec2(-0.835318616427, -0.425616093506),
- vec2(-0.425616093506, 0.835318616427),
- vec2(-0.786253657449, -0.510599095327),
- vec2(-0.510599095327, 0.786253657449),
- vec2(-0.728574338866, -0.589987866609),
- vec2(-0.589987866609, 0.728574338866),
- vec2(-0.662912607362, -0.662912607362),
- vec2(-0.662912607362, 0.662912607362),
- vec2(-0.589987866609, -0.728574338866),
- vec2(-0.510599095327, -0.786253657449),
- vec2(-0.425616093506, -0.835318616427),
- vec2(-0.335969952699, -0.875231649841),
- vec2(-0.242642854784, -0.905555462146),
- vec2(-0.146657310975, -0.925957819308),
- vec2(-0.0490649589778, -0.936215188832),
- vec2(0.0490649589778, -0.936215188832),
- vec2(0.146657310975, -0.925957819308),
- vec2(0.242642854784, -0.905555462146),
- vec2(0.335969952699, -0.875231649841),
- vec2(0.425616093506, -0.835318616427),
- vec2(0.510599095327, -0.786253657449),
- vec2(0.589987866609, -0.728574338866),
- vec2(0.662912607362, -0.662912607362),
- vec2(0.728574338866, -0.589987866609),
- vec2(0.786253657449, -0.510599095327),
- vec2(0.835318616427, -0.425616093506),
- vec2(0.875231649841, -0.335969952699),
- vec2(0.905555462146, -0.242642854784),
- vec2(0.925957819308, -0.146657310975),
- vec2(0.936215188832, -0.0490649589778));
diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
deleted file mode 100644
index 1014b25033a..00000000000
--- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-
-uniform vec3 basecol;
-uniform float metallic;
-uniform float specular;
-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 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
- vec3 out_diff, out_spec, ssr_spec;
- eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, true, out_diff, out_spec, ssr_spec);
-
- Closure cl = CLOSURE_DEFAULT;
- cl.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) +
- render_pass_diffuse_mask(albedo, out_diff * albedo);
- closure_load_ssr_data(ssr_spec, roughness, N, viewCameraVec, 1, cl);
-
-#ifdef LOOKDEV
- gl_FragDepth = 0.0;
-#endif
-
-#ifdef HOLDOUT
- cl = CLOSURE_DEFAULT;
- cl.holdout = 1.0;
-#endif
-
- return cl;
-}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
index d56890769a7..9c1ca17f87c 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
@@ -1,4 +1,8 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
@@ -18,9 +22,6 @@ uniform vec4 bokehParams[2];
uniform vec2 nearFar; /* Near & far view depths values */
-#define M_PI 3.1415926535897932384626433832795
-#define M_2PI 6.2831853071795864769252868
-
/* -------------- Utils ------------- */
/* divide by sensor size to get the normalized size */
@@ -34,11 +35,6 @@ uniform vec2 nearFar; /* Near & far view depths values */
#define weighted_sum(a, b, c, d, e) \
(a * e.x + b * e.y + c * e.z + d * e.w) / max(1e-6, dot(e, vec4(1.0)));
-float max_v4(vec4 v)
-{
- return max(max(v.x, v.y), max(v.z, v.w));
-}
-
vec4 safe_color(vec4 c)
{
/* Clamp to avoid black square artifacts if a pixel goes NaN. */
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
index d83b410125a..6e35d4a54ae 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
uniform vec4 bokehParams[2];
#define bokeh_rotation bokehParams[0].x
@@ -15,8 +17,6 @@ flat out float smoothFac;
flat out ivec2 edge;
out vec2 particlecoord;
-#define M_PI 3.1415926535897932384626433832795
-
/* Scatter pass, calculate a triangle covering the CoC. */
void main()
{
diff --git a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
index eea0ce0aae2..47fe21928b3 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
@@ -1,14 +1,34 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl)
+
/**
* This shader only compute maximum horizon angles for each directions.
* The final integration is done at the resolve stage with the shading normal.
*/
-uniform float rotationOffset;
-
out vec4 FragColor;
-#ifdef DEBUG_AO
uniform sampler2D normalBuffer;
+#ifdef LAYERED_DEPTH
+uniform sampler2DArray depthBufferLayered;
+uniform int layer;
+# define gtao_depthBuffer depthBufferLayered
+# define gtao_textureLod(a, b, c) textureLod(a, vec3(b, layer), c)
+
+#else
+uniform sampler2D depthBuffer;
+# define gtao_depthBuffer depthBuffer
+# define gtao_textureLod(a, b, c) textureLod(a, b, c)
+
+#endif
+
+uniform float rotationOffset;
+
+#ifdef DEBUG_AO
void main()
{
@@ -34,18 +54,6 @@ void main()
#else
-# ifdef LAYERED_DEPTH
-uniform sampler2DArray depthBufferLayered;
-uniform int layer;
-# define gtao_depthBuffer depthBufferLayered
-# define gtao_textureLod(a, b, c) textureLod(a, vec3(b, layer), c)
-
-# else
-# define gtao_depthBuffer depthBuffer
-# define gtao_textureLod(a, b, c) textureLod(a, b, c)
-
-# endif
-
void main()
{
vec2 uvs = saturate(gl_FragCoord.xy / vec2(textureSize(gtao_depthBuffer, 0).xy));
diff --git a/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl
index edee55a07e0..7331f92ba6d 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl
@@ -1,5 +1,10 @@
+
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
/* Convert depth to Mist factor */
uniform vec3 mistSettings;
+uniform sampler2D depthBuffer;
#define mistStart mistSettings.x
#define mistInvDistance mistSettings.y
diff --git a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
index fbf507a2e40..3501a4448c5 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+
/*
* Based on:
* A Fast and Stable Feature-Aware Motion Blur Filter
@@ -15,11 +17,6 @@ uniform sampler2D tileMaxBuffer;
#define KERNEL 8
-/* TODO(fclem) deduplicate this code. */
-uniform sampler2DArray utilTex;
-#define LUT_SIZE 64
-#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-
uniform float depthScale;
uniform ivec2 tileBufferSize;
uniform vec2 viewportSize;
diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
index 598cc3e5183..f8dccb7511a 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
@@ -1,4 +1,11 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+#pragma BLENDER_REQUIRE(ssr_lib.glsl)
+
/* Based on Stochastic Screen Space Reflections
* https://www.ea.com/frostbite/news/stochastic-screen-space-reflections */
@@ -131,7 +138,7 @@ void main()
return;
}
- vec4 rand = texelFetch(utilTex, ivec3(halfres_texel % LUT_SIZE, 2), 0);
+ vec4 rand = texelfetch_noise_tex(halfres_texel);
/* Gives *perfect* reflection for very small roughness */
if (roughness < 0.04) {
diff --git a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
index e9da49c9eb9..2a53a4f119f 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
@@ -1,4 +1,9 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+
/* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */
#define MAX_SSS_SAMPLES 65
@@ -14,36 +19,16 @@ uniform sampler2D sssIrradiance;
uniform sampler2D sssRadius;
uniform sampler2D sssAlbedo;
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
layout(location = 0) out vec4 sssRadiance;
-float get_view_z_from_depth(float depth)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- float d = 2.0 * depth - 1.0;
- return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
- }
- else {
- return viewVecs[0].z + depth * viewVecs[1].z;
- }
-}
-
-#define LUT_SIZE 64
-#define M_PI_2 1.5707963267948966 /* pi/2 */
-#define M_2PI 6.2831853071795865 /* 2*pi */
-
void main(void)
{
vec2 pixel_size = 1.0 / vec2(textureSize(depthBuffer, 0).xy); /* TODO precompute */
vec2 uvs = gl_FragCoord.xy * pixel_size;
vec3 sss_irradiance = texture(sssIrradiance, uvs).rgb;
float sss_radius = texture(sssRadius, uvs).r;
- float depth_view = get_view_z_from_depth(texture(depthBuffer, uvs).r);
+ float depth = texture(depthBuffer, uvs).r;
+ float depth_view = get_view_z_from_depth(depth);
float rand = texelfetch_noise_tex(gl_FragCoord.xy).r;
#ifdef FIRST_PASS
diff --git a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl
index b44645174bd..28947e971d2 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl
@@ -1,5 +1,11 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+uniform sampler2D colorBuffer;
+uniform sampler2D depthBuffer;
uniform sampler2D colorHistoryBuffer;
+
uniform mat4 prevViewProjectionMatrix;
out vec4 FragColor;
diff --git a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl
index 6531ceb8dbe..c85eff92e37 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl
@@ -1,11 +1,16 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(lights_lib.glsl)
+
in vec4 uvcoordsvar;
out vec4 FragColor;
+uniform sampler2D depthBuffer;
uniform sampler1D sssTexProfile;
uniform sampler2D sssRadius;
-
uniform sampler2DArray sssShadowCubes;
uniform sampler2DArray sssShadowCascades;
@@ -27,12 +32,6 @@ vec3 sss_profile(float s)
return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb;
}
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
float light_translucent_power_with_falloff(LightData ld, vec3 N, vec4 l_vector)
{
float power, falloff;
diff --git a/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
index d927fd78d30..145939cefb2 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
@@ -1,4 +1,8 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
+uniform sampler2D depthBuffer;
+
uniform mat4 prevViewProjMatrix;
uniform mat4 currViewProjMatrixInv;
uniform mat4 nextViewProjMatrix;
diff --git a/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl
index 0eb598521af..f52acaf6f7f 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl
@@ -148,4 +148,4 @@ void main()
tileMaxVelocity = encode_velocity(max_motion);
}
-#endif \ No newline at end of file
+#endif
diff --git a/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl b/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl
index b1d4de1c682..2274bf8b950 100644
--- a/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl
@@ -1,44 +1,76 @@
-uniform sampler2DArray irradianceGrid;
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+#pragma BLENDER_REQUIRE(octahedron_lib.glsl)
#define IRRADIANCE_LIB
-#ifdef IRRADIANCE_CUBEMAP
-struct IrradianceData {
- vec3 color;
-};
-#elif defined(IRRADIANCE_SH_L2)
+/* ---------------------------------------------------------------------- */
+/** \name Structure
+ * \{ */
+
+#if defined(IRRADIANCE_SH_L2)
struct IrradianceData {
vec3 shcoefs[9];
};
+
#else /* defined(IRRADIANCE_HL2) */
struct IrradianceData {
vec3 cubesides[3];
};
+
#endif
-IrradianceData load_irradiance_cell(int cell, vec3 N)
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Resources
+ * \{ */
+
+uniform sampler2DArray irradianceGrid;
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Functions
+ * \{ */
+
+vec4 irradiance_encode(vec3 rgb)
{
- /* Keep in sync with diffuse_filter_probe() */
+ float maxRGB = max_v3(rgb);
+ float fexp = ceil(log2(maxRGB));
+ return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0);
+}
-#if defined(IRRADIANCE_CUBEMAP)
+vec3 irradiance_decode(vec4 data)
+{
+ float fexp = data.a * 255.0 - 128.0;
+ return data.rgb * exp2(fexp);
+}
-# define AMBIANT_CUBESIZE 8
- ivec2 cell_co = ivec2(AMBIANT_CUBESIZE);
- int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x;
- cell_co.x *= cell % cell_per_row;
- cell_co.y *= cell / cell_per_row;
+vec4 visibility_encode(vec2 accum, float range)
+{
+ accum /= range;
- vec2 texelSize = 1.0 / vec2(AMBIANT_CUBESIZE);
+ vec4 data;
+ data.x = fract(accum.x);
+ data.y = floor(accum.x) / 255.0;
+ data.z = fract(accum.y);
+ data.w = floor(accum.y) / 255.0;
- vec2 uvs = mapping_octahedron(N, texelSize);
- uvs *= vec2(AMBIANT_CUBESIZE) / vec2(textureSize(irradianceGrid, 0));
- uvs += vec2(cell_co) / vec2(textureSize(irradianceGrid, 0));
+ return data;
+}
- IrradianceData ir;
- ir.color = texture(irradianceGrid, vec3(uvs, 0.0)).rgb;
+vec2 visibility_decode(vec4 data, float range)
+{
+ return (data.xz + data.yw * 255.0) * range;
+}
-#elif defined(IRRADIANCE_SH_L2)
+IrradianceData load_irradiance_cell(int cell, vec3 N)
+{
+ /* Keep in sync with diffuse_filter_probe() */
+
+#if defined(IRRADIANCE_SH_L2)
ivec2 cell_co = ivec2(3, 3);
int cell_per_row = textureSize(irradianceGrid, 0).x / cell_co.x;
@@ -164,9 +196,7 @@ vec3 hl2_basis(vec3 N, vec3 cubesides[3])
vec3 compute_irradiance(vec3 N, IrradianceData ird)
{
-#if defined(IRRADIANCE_CUBEMAP)
- return ird.color;
-#elif defined(IRRADIANCE_SH_L2)
+#if defined(IRRADIANCE_SH_L2)
return spherical_harmonics_L2(N, ird.shcoefs);
#else /* defined(IRRADIANCE_HL2) */
return hl2_basis(N, ird.cubesides);
@@ -178,3 +208,5 @@ vec3 irradiance_from_cell_get(int cell, vec3 ir_dir)
IrradianceData ir_data = load_irradiance_cell(cell, ir_dir);
return compute_irradiance(ir_dir, ir_data);
}
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
index 96fe94fc41e..b0da4274a13 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
@@ -1,4 +1,7 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+
flat in int pid;
in vec2 quadCoord;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl
index db780714091..d06ad553ca4 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
/* XXX TODO fix code duplication */
struct CubeData {
vec4 position_type;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
index 296c1581545..bf45169ebaa 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
@@ -1,4 +1,8 @@
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
+
uniform samplerCube probeHdr;
uniform int probeSize;
uniform float lodFactor;
@@ -111,32 +115,7 @@ void main()
FragColor = vec4(sh, 1.0);
#else
-# if defined(IRRADIANCE_CUBEMAP)
- /* Downside: Need lots of memory for storage, distortion due to octahedral mapping */
- const vec2 map_size = vec2(16.0);
- const vec2 texelSize = 1.0 / map_size;
- vec2 uvs = mod(gl_FragCoord.xy, map_size) * texelSize;
- const float paddingSize = 1.0;
-
- /* Add a N pixel border to ensure filtering is correct
- * for N mipmap levels. */
- uvs = (uvs - texelSize * paddingSize) / (1.0 - 2.0 * texelSize * paddingSize);
-
- /* edge mirroring : only mirror if directly adjacent
- * (not diagonally adjacent) */
- vec2 m = abs(uvs - 0.5) + 0.5;
- vec2 f = floor(m);
- if (f.x - f.y != 0.0) {
- uvs = 1.0 - uvs;
- }
-
- /* clamp to [0-1] */
- uvs = fract(uvs);
-
- /* get cubemap vector */
- vec3 cubevec = octahedral_to_cubemap_proj(uvs);
-
-# elif defined(IRRADIANCE_HL2)
+# if defined(IRRADIANCE_HL2)
/* Downside: very very low resolution (6 texels), bleed lighting because of interpolation */
int x = int(gl_FragCoord.x) % 3;
int y = int(gl_FragCoord.y) % 2;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
index 00eb3c7e200..ccb77427ed2 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
@@ -1,4 +1,7 @@
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+
uniform samplerCube probeHdr;
uniform float roughnessSquared;
uniform float texelSize;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
index 5d8af21032a..8d7c58a93d5 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
@@ -1,4 +1,8 @@
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
+
uniform samplerCube probeDepth;
uniform int outputSize;
uniform float lodFactor;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
index f8bc1703c66..009ccf6535e 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
@@ -40,9 +40,6 @@ void main()
for (int v = 0; v < 3; v++) {
gl_Position = vPos[v];
worldPosition = x_axis[fFace] * vPos[v].x + y_axis[fFace] * vPos[v].y + maj_axes[fFace];
-#ifdef USE_ATTR
- pass_attr(v);
-#endif
EmitVertex();
}
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl
index f9bcc718a1e..dc5ec1e40f5 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl
@@ -1,3 +1,5 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
flat in int cellOffset;
in vec2 quadCoord;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl
index 4e500db827e..6fefe1319bd 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
uniform float sphere_size;
uniform int offset;
uniform ivec3 grid_resolution;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_fill_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_fill_frag.glsl
index 7cab5146b09..71e4d6e2c4a 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_fill_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_fill_frag.glsl
@@ -6,8 +6,6 @@ void main()
{
#if defined(IRRADIANCE_SH_L2)
const ivec2 data_size = ivec2(3, 3);
-#elif defined(IRRADIANCE_CUBEMAP)
- const ivec2 data_size = ivec2(8, 8);
#elif defined(IRRADIANCE_HL2)
const ivec2 data_size = ivec2(3, 2);
#endif
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
index 6c6db88139b..a2e25b83532 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
@@ -1,3 +1,12 @@
+
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+#pragma BLENDER_REQUIRE(cubemap_lib.glsl)
+#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
+
/* ----------- Uniforms --------- */
uniform sampler2DArray probePlanars;
@@ -73,12 +82,6 @@ struct GridData {
# define MAX_PLANAR 1
#endif
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
layout(std140) uniform probe_block
{
CubeData probes_data[MAX_PROBE];
@@ -218,7 +221,7 @@ void fallback_cubemap(vec3 N,
inout vec4 spec_accum)
{
/* Specular probes */
- vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
+ vec3 spec_dir = specular_dominant_dir(N, V, roughnessSquared);
#ifdef SSR_AO
vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
@@ -246,7 +249,6 @@ void fallback_cubemap(vec3 N,
}
}
-#ifdef IRRADIANCE_LIB
vec3 probe_evaluate_grid(GridData gd, vec3 W, vec3 N, vec3 localpos)
{
localpos = localpos * 0.5 + 0.5;
@@ -308,5 +310,3 @@ vec3 probe_evaluate_world_diff(vec3 N)
{
return irradiance_from_cell_get(0, N);
}
-
-#endif /* IRRADIANCE_LIB */
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
index 2807488db6c..0a53abcb04a 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
uniform sampler2DArray probePlanars;
in vec3 worldPosition;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl
index 65506e5c7b1..6759c060259 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
in vec3 pos;
in int probe_id;
diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
index 3b9d0a8f2bc..949e4d8f04f 100644
--- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
@@ -1,8 +1,76 @@
-uniform sampler2DArrayShadow shadowCubeTexture;
-uniform sampler2DArrayShadow shadowCascadeTexture;
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
+#pragma BLENDER_REQUIRE(ltc_lib.glsl)
+
+#ifndef MAX_CASCADE_NUM
+# define MAX_CASCADE_NUM 4
+#endif
+
+/* ---------------------------------------------------------------------- */
+/** \name Structure
+ * \{ */
+
+struct LightData {
+ vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */
+ vec4 color_spec; /* w : Spec Intensity */
+ vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */
+ vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */
+ vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */
+ vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */
+};
+
+/* convenience aliases */
+#define l_color color_spec.rgb
+#define l_spec color_spec.a
+#define l_position position_influence.xyz
+#define l_influence position_influence.w
+#define l_sizex rightvec_sizex.w
+#define l_sizey upvec_sizey.w
+#define l_right rightvec_sizex.xyz
+#define l_up upvec_sizey.xyz
+#define l_forward forwardvec_type.xyz
+#define l_type forwardvec_type.w
+#define l_spot_size spotdata_radius_shadow.x
+#define l_spot_blend spotdata_radius_shadow.y
+#define l_radius spotdata_radius_shadow.z
+#define l_shadowid spotdata_radius_shadow.w
+
+struct ShadowData {
+ vec4 near_far_bias_id;
+ vec4 contact_shadow_data;
+};
+
+struct ShadowCubeData {
+ mat4 shadowmat;
+ vec4 position;
+};
+
+struct ShadowCascadeData {
+ mat4 shadowmat[MAX_CASCADE_NUM];
+ vec4 split_start_distances;
+ vec4 split_end_distances;
+ vec4 shadow_vec_id;
+};
+
+/* convenience aliases */
+#define sh_near near_far_bias_id.x
+#define sh_far near_far_bias_id.y
+#define sh_bias near_far_bias_id.z
+#define sh_data_index near_far_bias_id.w
+#define sh_contact_dist contact_shadow_data.x
+#define sh_contact_offset contact_shadow_data.y
+#define sh_contact_spread contact_shadow_data.z
+#define sh_contact_thickness contact_shadow_data.w
+#define sh_shadow_vec shadow_vec_id.xyz
+#define sh_tex_index shadow_vec_id.w
+
+/** \} */
-#define LAMPS_LIB
+/* ---------------------------------------------------------------------- */
+/** \name Resources
+ * \{ */
layout(std140) uniform shadow_block
{
@@ -16,6 +84,15 @@ layout(std140) uniform light_block
LightData lights_data[MAX_LIGHT];
};
+uniform sampler2DArrayShadow shadowCubeTexture;
+uniform sampler2DArrayShadow shadowCascadeTexture;
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Shadow Functions
+ * \{ */
+
/* type */
#define POINT 0.0
#define SUN 1.0
@@ -133,9 +210,11 @@ float sample_cascade_shadow(int shadow_id, vec3 W)
#undef scube
#undef scsmd
-/* ----------------------------------------------------------- */
-/* --------------------- Light Functions --------------------- */
-/* ----------------------------------------------------------- */
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Light Functions
+ * \{ */
/* From Frostbite PBR Course
* Distance based attenuation
@@ -258,7 +337,6 @@ float light_visibility(LightData ld,
l_atten);
}
-#ifdef USE_LTC
float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
{
if (ld.l_type == AREA_RECT) {
@@ -321,4 +399,5 @@ float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector)
return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points);
}
}
-#endif
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl b/source/blender/draw/engines/eevee/shaders/lookdev_world_frag.glsl
index 8c876cf582c..9077b414026 100644
--- a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lookdev_world_frag.glsl
@@ -1,20 +1,17 @@
-uniform float backgroundAlpha;
-uniform vec3 color;
-
-out vec4 FragColor;
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
-#if defined(LOOKDEV_BG) || defined(LOOKDEV)
+uniform sampler2D studioLight;
+uniform float backgroundAlpha;
uniform mat3 StudioLightMatrix;
-uniform sampler2D image;
uniform float studioLightIntensity = 1.0;
uniform float studioLightBlur = 0.0;
-in vec3 viewPosition;
-# ifndef M_PI
-# define M_PI 3.14159265358979323846
-# endif
+out vec4 FragColor;
vec3 background_transform_to_world(vec3 viewvec)
{
@@ -35,36 +32,20 @@ vec4 node_tex_environment_equirectangular(vec3 co, sampler2D ima)
vec3 nco = normalize(co);
float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
-
- /* Fix pole bleeding */
- float width = float(textureSize(ima, 0).x);
- float texel_width = 1.0 / width;
- v = clamp(v, texel_width, 1.0 - texel_width);
-
- /* Fix u = 0 seam */
- /* This is caused by texture filtering, since uv don't have smooth derivatives
- * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
- * texels. So we force the highest mipmap and don't do anisotropic filtering. */
return textureLod(ima, vec2(u, v), 0.0);
}
-#endif
void main()
{
- vec3 background_color;
+ vec3 worldvec = background_transform_to_world(viewPosition);
+ vec3 background_color;
#if defined(LOOKDEV_BG)
- vec3 worldvec = background_transform_to_world(viewPosition);
background_color = probe_evaluate_world_spec(worldvec, studioLightBlur).rgb;
- background_color *= studioLightIntensity;
-
-#elif defined(LOOKDEV)
- vec3 worldvec = background_transform_to_world(viewPosition);
- background_color = node_tex_environment_equirectangular(StudioLightMatrix * worldvec, image).rgb;
- background_color *= studioLightIntensity;
-
#else
- background_color = color;
+ worldvec = StudioLightMatrix * worldvec;
+ background_color = node_tex_environment_equirectangular(worldvec, studioLight).rgb;
+ background_color *= studioLightIntensity;
#endif
FragColor = vec4(clamp(background_color, vec3(0.0), vec3(1e10)), 1.0) * backgroundAlpha;
diff --git a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
index dbfc7ad5a71..2750d42a74a 100644
--- a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
@@ -8,12 +8,6 @@
#define USE_LTC
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
/* Diffuse *clipped* sphere integral. */
float diffuse_sphere_integral(float avg_dir_z, float form_factor)
{
diff --git a/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl b/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl
index 95cd69ba310..ef96bcbaedb 100644
--- a/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl
@@ -1,4 +1,7 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+
uniform mat4 currModelMatrix;
uniform mat4 prevModelMatrix;
uniform mat4 nextModelMatrix;
@@ -19,6 +22,8 @@ out vec3 nextWorldPos;
void main()
{
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+
#ifdef HAIR
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
float time, thick_time, thickness;
diff --git a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
index 9acd8f998f6..34999076f9c 100644
--- a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
@@ -1,4 +1,14 @@
+/* Required by some nodes. */
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+#pragma BLENDER_REQUIRE(closure_lib.glsl)
+#pragma BLENDER_REQUIRE(closure_lit_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
#ifdef USE_ALPHA_HASH
/* From the paper "Hashed Alpha Testing" by Chris Wyman and Morgan McGuire */
@@ -56,8 +66,6 @@ float hashed_alpha_threshold(vec3 co)
#endif
-#define NODETREE_EXEC
-
void main()
{
#if defined(USE_ALPHA_HASH)
@@ -66,11 +74,9 @@ void main()
float opacity = saturate(1.0 - avg(cl.transmittance));
-# if defined(USE_ALPHA_HASH)
/* Hashed Alpha Testing */
if (opacity < hashed_alpha_threshold(worldPosition)) {
discard;
}
-# endif
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
index 2c7e0aca3fb..f650e2eeb8c 100644
--- a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
@@ -1,16 +1,14 @@
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
#ifndef HAIR_SHADER
in vec3 pos;
#endif
void main()
{
-#ifdef GPU_INTEL
- /* Due to some shader compiler bug, we somewhat
- * need to access gl_VertexID to make it work. even
- * if it's actually dead code. */
- gl_Position.x = float(gl_VertexID);
-#endif
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
#ifdef HAIR_SHADER
float time, thick_time, thickness;
@@ -34,5 +32,4 @@ void main()
#ifdef CLIP_PLANES
gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), clipPlanes[0]);
#endif
- /* TODO motion vectors */
}
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index f88cfdf3787..39db39f8756 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -1,3 +1,11 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+
+uniform sampler2D maxzBuffer;
+uniform sampler2DArray planarDepth;
+
#define MAX_STEP 256
float sample_depth(vec2 uv, int index, float lod)
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
new file mode 100644
index 00000000000..36cf3cecf40
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
@@ -0,0 +1,43 @@
+
+/* ---------------------------------------------------------------------- */
+/** \name Resources
+ * \{ */
+
+layout(std140) uniform renderpass_block
+{
+ bool renderPassDiffuse;
+ bool renderPassDiffuseLight;
+ bool renderPassGlossy;
+ bool renderPassGlossyLight;
+ bool renderPassEmit;
+ bool renderPassSSSColor;
+ bool renderPassEnvironment;
+};
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Functions
+ * \{ */
+
+vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light)
+{
+ return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0);
+}
+
+vec3 render_pass_sss_mask(vec3 sss_color)
+{
+ return renderPassSSSColor ? sss_color : vec3(0.0);
+}
+
+vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light)
+{
+ return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0);
+}
+
+vec3 render_pass_emission_mask(vec3 emission_light)
+{
+ return renderPassEmit ? emission_light : vec3(0.0);
+}
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
index 361963d5ac3..89a411bc7cb 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -1,3 +1,7 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+
#define PASS_POST_UNDEFINED 0
#define PASS_POST_ACCUMULATED_COLOR 1
#define PASS_POST_ACCUMULATED_LIGHT 2
@@ -9,6 +13,8 @@
uniform int postProcessType;
uniform int currentSample;
+
+uniform sampler2D depthBuffer;
uniform sampler2D inputBuffer;
uniform sampler2D inputSecondLightBuffer;
uniform sampler2D inputColorBuffer;
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
index 860ec9e1727..e0b9d4a60db 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
@@ -1,11 +1,11 @@
-out vec4 fragColor;
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(lights_lib.glsl)
+
+uniform sampler2D depthBuffer;
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
+out vec4 fragColor;
void main()
{
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
index c42f905cf7e..0e342938396 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
@@ -1,39 +1,23 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
in vec3 pos;
in vec3 nor;
-#ifdef MESH_SHADER
-out vec3 worldPosition;
-out vec3 viewPosition;
-out vec3 worldNormal;
-out vec3 viewNormal;
-#endif
-
-#ifdef HAIR_SHADER
-out vec3 hairTangent;
-out float hairThickTime;
-out float hairThickness;
-out float hairTime;
-flat out int hairStrandID;
-#endif
-
void main()
{
-#ifdef GPU_INTEL
- /* Due to some shader compiler bug, we somewhat
- * need to access gl_VertexID to make it work. even
- * if it's actually dead code. */
- gl_Position.x = float(gl_VertexID);
-#endif
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
#ifdef HAIR_SHADER
hairStrandID = hair_get_strand_id();
- vec3 world_pos, binor;
+ vec3 pos, binor;
hair_get_pos_tan_binor_time((ProjectionMatrix[3][3] == 0.0),
ModelMatrixInverse,
ViewMatrixInverse[3].xyz,
ViewMatrixInverse[2].xyz,
- world_pos,
+ pos,
hairTangent,
binor,
hairTime,
@@ -41,6 +25,7 @@ void main()
hairThickTime);
worldNormal = cross(hairTangent, binor);
+ vec3 world_pos = pos;
#else
vec3 world_pos = point_object_to_world(pos);
#endif
@@ -57,7 +42,10 @@ void main()
/* No need to normalize since this is just a rotation. */
viewNormal = normal_world_to_view(worldNormal);
# ifdef USE_ATTR
- pass_attr(pos);
+# ifdef HAIR_SHADER
+ pos = hair_get_strand_pos();
+# endif
+ pass_attr(pos, NormalMatrix, ModelMatrixInverse);
# endif
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
index 0591b247541..29495e98355 100644
--- a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
@@ -1,3 +1,10 @@
+
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
+#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
/* ------------ Refraction ------------ */
#define BTDF_BIAS 0.85
diff --git a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl
new file mode 100644
index 00000000000..e746acfdfa3
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl
@@ -0,0 +1,89 @@
+
+/* Required by some nodes. */
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+
+#pragma BLENDER_REQUIRE(closure_lib.glsl)
+#pragma BLENDER_REQUIRE(closure_lit_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+
+#ifdef USE_ALPHA_BLEND
+/* Use dual source blending to be able to make a whole range of effects. */
+layout(location = 0, index = 0) out vec4 outRadiance;
+layout(location = 0, index = 1) out vec4 outTransmittance;
+
+#else /* OPAQUE */
+layout(location = 0) out vec4 outRadiance;
+layout(location = 1) out vec2 ssrNormals;
+layout(location = 2) out vec4 ssrData;
+# ifdef USE_SSS
+layout(location = 3) out vec3 sssIrradiance;
+layout(location = 4) out float sssRadius;
+layout(location = 5) out vec3 sssAlbedo;
+# endif
+
+#endif
+
+void main()
+{
+ Closure cl = nodetree_exec();
+
+ float holdout = saturate(1.0 - cl.holdout);
+ float transmit = saturate(avg(cl.transmittance));
+ float alpha = 1.0 - transmit;
+
+#ifdef USE_ALPHA_BLEND
+ vec2 uvs = gl_FragCoord.xy * volCoordScale.zw;
+ vec3 vol_transmit, vol_scatter;
+ volumetric_resolve(uvs, gl_FragCoord.z, vol_transmit, vol_scatter);
+
+ /* Removes part of the volume scattering that have
+ * already been added to the destination pixels.
+ * Since we do that using the blending pipeline we need to account for material transmittance. */
+ vol_scatter -= vol_scatter * cl.transmittance;
+
+ cl.radiance = cl.radiance * holdout * vol_transmit + vol_scatter;
+ outRadiance = vec4(cl.radiance, alpha * holdout);
+ outTransmittance = vec4(cl.transmittance, transmit) * holdout;
+#else
+ outRadiance = vec4(cl.radiance, holdout);
+ ssrNormals = cl.ssr_normal;
+ ssrData = cl.ssr_data;
+# ifdef USE_SSS
+ sssIrradiance = cl.sss_irradiance;
+ sssRadius = cl.sss_radius;
+ sssAlbedo = cl.sss_albedo;
+# endif
+#endif
+
+ /* For Probe capture */
+#ifdef USE_SSS
+ float fac = float(!sssToggle);
+
+ /* TODO(fclem) we shouldn't need this.
+ * Just disable USE_SSS when USE_REFRACTION is enabled. */
+# ifdef USE_REFRACTION
+ /* SSRefraction pass is done after the SSS pass.
+ * In order to not loose the diffuse light totally we
+ * need to merge the SSS radiance to the main radiance. */
+ fac = 1.0;
+# endif
+
+ outRadiance.rgb += cl.sss_irradiance.rgb * cl.sss_albedo.rgb * fac;
+#endif
+
+#ifndef USE_ALPHA_BLEND
+ float alpha_div = 1.0 / max(1e-8, alpha);
+ outRadiance.rgb *= alpha_div;
+ ssrData.rgb *= alpha_div;
+# ifdef USE_SSS
+ sssAlbedo.rgb *= alpha_div;
+# endif
+#endif
+
+#ifdef LOOKDEV
+ /* Lookdev spheres are rendered in front. */
+ gl_FragDepth = 0.0;
+#endif
+}
diff --git a/source/blender/draw/engines/eevee/shaders/surface_geom.glsl b/source/blender/draw/engines/eevee/shaders/surface_geom.glsl
new file mode 100644
index 00000000000..ad437dca79a
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/surface_geom.glsl
@@ -0,0 +1,46 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+
+RESOURCE_ID_VARYING
+
+/* Only used to compute barycentric coordinates. */
+
+void main()
+{
+#ifdef DO_BARYCENTRIC_DISTANCES
+ dataAttrOut.barycentricDist = calc_barycentric_distances(
+ dataIn[0].worldPosition, dataIn[1].worldPosition, dataIn[2].worldPosition);
+#endif
+
+ PASS_RESOURCE_ID
+
+#ifdef USE_ATTR
+ pass_attr(0);
+#endif
+ PASS_SURFACE_INTERFACE(0);
+ gl_Position = gl_in[0].gl_Position;
+ gl_ClipDistance[0] = gl_in[0].gl_ClipDistance[0];
+ EmitVertex();
+
+#ifdef USE_ATTR
+ pass_attr(1);
+#endif
+ PASS_SURFACE_INTERFACE(1);
+ gl_Position = gl_in[1].gl_Position;
+ gl_ClipDistance[0] = gl_in[1].gl_ClipDistance[0];
+ EmitVertex();
+
+#ifdef USE_ATTR
+ pass_attr(2);
+#endif
+ PASS_SURFACE_INTERFACE(2);
+ gl_Position = gl_in[2].gl_Position;
+ gl_ClipDistance[0] = gl_in[2].gl_ClipDistance[0];
+ EmitVertex();
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
new file mode 100644
index 00000000000..b93a3a23eff
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
@@ -0,0 +1,43 @@
+/** This describe the entire interface of the shader. */
+
+/* Samplers */
+uniform sampler2D colorBuffer;
+uniform sampler2D depthBuffer;
+
+/* Uniforms */
+uniform float refractionDepth;
+
+#define SURFACE_INTERFACE \
+ vec3 worldPosition; \
+ vec3 viewPosition; \
+ vec3 worldNormal; \
+ vec3 viewNormal;
+
+#ifdef GPU_GEOMETRY_SHADER
+in ShaderStageInterface{SURFACE_INTERFACE} dataIn[];
+
+out ShaderStageInterface{SURFACE_INTERFACE} dataOut;
+
+# define PASS_SURFACE_INTERFACE(vert) \
+ dataOut.worldPosition = dataIn[vert].worldPosition; \
+ dataOut.viewPosition = dataIn[vert].viewPosition; \
+ dataOut.worldNormal = dataIn[vert].worldNormal; \
+ dataOut.viewNormal = dataIn[vert].viewNormal;
+
+#else
+
+IN_OUT ShaderStageInterface{SURFACE_INTERFACE};
+
+#endif
+
+#ifdef HAIR_SHADER
+IN_OUT ShaderHairInterface
+{
+ /* world space */
+ vec3 hairTangent;
+ float hairThickTime;
+ float hairThickness;
+ float hairTime;
+ flat int hairStrandID;
+};
+#endif
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
index 1b94fc2bee1..0ad1393dd70 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
@@ -1,32 +1,20 @@
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
#ifndef HAIR_SHADER
in vec3 pos;
in vec3 nor;
#endif
-#ifdef MESH_SHADER
-out vec3 worldPosition;
-out vec3 viewPosition;
-out vec3 worldNormal;
-out vec3 viewNormal;
-#endif
-
-#ifdef HAIR_SHADER
-out vec3 hairTangent;
-out float hairThickTime;
-out float hairThickness;
-out float hairTime;
-flat out int hairStrandID;
-#endif
+RESOURCE_ID_VARYING
void main()
{
-#ifdef GPU_INTEL
- /* Due to some shader compiler bug, we somewhat
- * need to access gl_VertexID to make it work. even
- * if it's actually dead code. */
- gl_Position.x = float(gl_VertexID);
-#endif
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+
+ PASS_RESOURCE_ID
#ifdef HAIR_SHADER
hairStrandID = hair_get_strand_id();
@@ -63,7 +51,10 @@ void main()
/* No need to normalize since this is just a rotation. */
viewNormal = normal_world_to_view(worldNormal);
# ifdef USE_ATTR
- pass_attr(pos);
+# ifdef HAIR_SHADER
+ pos = hair_get_strand_pos();
+# endif
+ pass_attr(pos, NormalMatrix, ModelMatrixInverse);
# endif
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl b/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl
index 02ad2170f06..0c01c46c2ba 100644
--- a/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl
@@ -1,11 +1,11 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
uniform sampler2D blueNoise;
uniform vec3 offsets;
out vec4 FragColor;
-#define M_2PI 6.28318530717958647692
-
void main(void)
{
vec3 blue_noise = texelFetch(blueNoise, ivec2(gl_FragCoord.xy), 0).xyz;
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
index 312fc07054a..bac69ab0355 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
@@ -1,9 +1,10 @@
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+#pragma BLENDER_REQUIRE(closure_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
-#define NODETREE_EXEC
-
#ifdef MESH_SHADER
uniform vec3 volumeOrcoLoc;
uniform vec3 volumeOrcoSize;
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl
index 96b891c929f..30cda401284 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
#ifdef MESH_SHADER
/* TODO tight slices */
layout(triangles) in;
@@ -12,12 +14,16 @@ in vec4 vPos[];
flat out int slice;
+RESOURCE_ID_VARYING
+
#ifdef MESH_SHADER
/* TODO tight slices */
void main()
{
gl_Layer = slice = int(vPos[0].z);
+ PASS_RESOURCE_ID
+
# ifdef USE_ATTR
pass_attr(0);
# endif
@@ -48,6 +54,8 @@ void main()
{
gl_Layer = slice = int(vPos[0].z);
+ PASS_RESOURCE_ID
+
# ifdef USE_ATTR
pass_attr(0);
# endif
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
index c3c442e7b69..f4276bd61bd 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
@@ -11,9 +13,11 @@ uniform sampler3D volumeExtinction;
#ifdef USE_VOLUME_OPTI
uniform layout(binding = 0, r11f_g11f_b10f) writeonly restrict image3D finalScattering_img;
uniform layout(binding = 1, r11f_g11f_b10f) writeonly restrict image3D finalTransmittance_img;
+
vec3 finalScattering;
vec3 finalTransmittance;
#else
+
flat in int slice;
layout(location = 0) out vec3 finalScattering;
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
index 40eb3da42d1..9b852a57ec4 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
@@ -1,4 +1,8 @@
+#pragma BLENDER_REQUIRE(lights_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
@@ -58,7 +62,6 @@ float phase_function(vec3 v, vec3 l, float g)
return (1 - sqr_g) / max(1e-8, 4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0));
}
-#ifdef LAMPS_LIB
vec3 light_volume(LightData ld, vec4 l_vector)
{
float power;
@@ -95,7 +98,7 @@ vec3 light_volume(LightData ld, vec4 l_vector)
return tint * lum;
}
-# define VOLUMETRIC_SHADOW_MAX_STEP 32.0
+#define VOLUMETRIC_SHADOW_MAX_STEP 32.0
vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction)
{
@@ -109,7 +112,7 @@ vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction)
vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D volume_extinction)
{
-# if defined(VOLUME_SHADOW)
+#if defined(VOLUME_SHADOW)
/* Heterogeneous volume shadows */
float dd = l_vector.w / volShadowSteps;
vec3 L = l_vector.xyz * l_vector.w;
@@ -120,27 +123,24 @@ vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D v
shadow *= exp(-s_extinction * dd);
}
return shadow;
-# else
+#else
return vec3(1.0);
-# endif /* VOLUME_SHADOW */
+#endif /* VOLUME_SHADOW */
}
-#endif
-#ifdef IRRADIANCE_LIB
vec3 irradiance_volumetric(vec3 wpos)
{
-# ifdef IRRADIANCE_HL2
+#ifdef IRRADIANCE_HL2
IrradianceData ir_data = load_irradiance_cell(0, vec3(1.0));
vec3 irradiance = ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2];
ir_data = load_irradiance_cell(0, vec3(-1.0));
irradiance += ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2];
irradiance *= 0.16666666; /* 1/6 */
return irradiance;
-# else
+#else
return vec3(0.0);
-# endif
-}
#endif
+}
uniform sampler3D inScattering;
uniform sampler3D inTransmittance;
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl
index 1ff7e848c40..6ab21587c9a 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
index 9621fa1cc0d..806f1b5b205 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl
index b96360febb0..b70747ecec3 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl
@@ -1,6 +1,10 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
out vec4 vPos;
+RESOURCE_ID_VARYING
+
void main()
{
/* Generate Triangle : less memory fetches from a VBO */
@@ -25,7 +29,9 @@ void main()
vPos.z = float(t_id);
vPos.w = 1.0;
+ PASS_RESOURCE_ID
+
#ifdef USE_ATTR
- pass_attr(vec3(0.0));
+ pass_attr(vec3(0.0), mat3(1), mat4(1));
#endif
}
diff --git a/source/blender/draw/engines/external/external_engine.h b/source/blender/draw/engines/external/external_engine.h
index 01edea38ab0..c645fb99e0e 100644
--- a/source/blender/draw/engines/external/external_engine.h
+++ b/source/blender/draw/engines/external/external_engine.h
@@ -20,9 +20,6 @@
* \ingroup draw_engine
*/
-#ifndef __EXTERNAL_ENGINE_H__
-#define __EXTERNAL_ENGINE_H__
+#pragma once
extern RenderEngineType DRW_engine_viewport_external_type;
-
-#endif /* __EXTERNAL_ENGINE_H__ */
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index d97bf9255d2..41a7196cb90 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -106,7 +106,7 @@ GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob)
copy_v3_v3(tgp_ob->plane_mat[3], center);
/* Add to corresponding list if is in front. */
- if (ob->dtx & OB_DRAWXRAY) {
+ if (ob->dtx & OB_DRAW_IN_FRONT) {
BLI_LINKS_APPEND(&pd->tobjects_infront, tgp_ob);
}
else {
@@ -132,12 +132,11 @@ static int gpencil_tobject_dist_sort(const void *a, const void *b)
if (ob_a->camera_z > ob_b->camera_z) {
return 1;
}
- else if (ob_a->camera_z < ob_b->camera_z) {
+ if (ob_a->camera_z < ob_b->camera_z) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
void gpencil_object_cache_sort(GPENCIL_PrivateData *pd)
@@ -193,7 +192,7 @@ static float gpencil_layer_final_opacity_get(const GPENCIL_PrivateData *pd,
if (is_obact && is_fade) {
return gpl->opacity * pd->fade_layer_opacity;
}
- else if (!is_obact && (pd->fade_gp_object_opacity > -1.0f)) {
+ if (!is_obact && (pd->fade_gp_object_opacity > -1.0f)) {
return gpl->opacity * pd->fade_gp_object_opacity;
}
}
@@ -258,7 +257,7 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
{
bGPdata *gpd = (bGPdata *)ob->data;
- const bool is_in_front = (ob->dtx & OB_DRAWXRAY);
+ const bool is_in_front = (ob->dtx & OB_DRAW_IN_FRONT);
const bool is_screenspace = (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0;
const bool overide_vertcol = (pd->v3d_color_type != -1);
const bool is_vert_col_mode = (pd->v3d_color_type == V3D_SHADING_VERTEX_COLOR) ||
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
index 6e6b35e19ca..51152475a06 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
@@ -63,7 +63,7 @@ static struct GPUTexture *gpencil_image_texture_get(Image *image, bool *r_alpha_
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
if (ibuf != NULL && ibuf->rect != NULL) {
- gpu_tex = GPU_texture_from_blender(image, &iuser, ibuf, GL_TEXTURE_2D);
+ gpu_tex = BKE_image_get_gpu_texture(image, &iuser, ibuf);
*r_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
}
BKE_image_release_ibuf(image, ibuf, lock);
@@ -359,12 +359,11 @@ static float light_power_get(const Light *la)
if (la->type == LA_AREA) {
return 1.0f / (4.0f * M_PI);
}
- else if (la->type == LA_SPOT || la->type == LA_LOCAL) {
+ if (la->type == LA_SPOT || la->type == LA_LOCAL) {
return 1.0f / (4.0f * M_PI * M_PI);
}
- else {
- return 1.0f / M_PI;
- }
+
+ return 1.0f / M_PI;
}
void gpencil_light_pool_populate(GPENCIL_LightPool *lightpool, Object *ob)
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index dded83bacf1..dbad226099e 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -525,12 +525,6 @@ static void gpencil_stroke_cache_populate(bGPDlayer *gpl,
DRW_shgroup_uniform_texture(iter->grp, "gpStrokeTexture", tex_stroke);
iter->tex_stroke = tex_stroke;
}
-
- /* TODO(fclem): This is a quick workaround but
- * ideally we should have this as a permanent bind. */
- const bool is_masked = iter->tgp_ob->layers.last->mask_bits != NULL;
- GPUTexture **mask_tex = (is_masked) ? &iter->pd->mask_tx : &iter->pd->dummy_tx;
- DRW_shgroup_uniform_texture_ref(iter->grp, "gpMaskTexture", mask_tex);
}
bool do_sbuffer = (iter->do_sbuffer_call == DRAW_NOW);
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 7baca28dca3..a406df530fc 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __GPENCIL_ENGINE_H__
-#define __GPENCIL_ENGINE_H__
+#pragma once
#include "DNA_gpencil_types.h"
@@ -439,5 +438,3 @@ void GPENCIL_render_to_image(void *vedata,
void gpencil_light_pool_free(void *storage);
void gpencil_material_pool_free(void *storage);
GPENCIL_ViewLayerData *GPENCIL_view_layer_data_ensure(void);
-
-#endif /* __GPENCIL_ENGINE_H__ */
diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c
index bb91bdbe396..c3294f88acf 100644
--- a/source/blender/draw/engines/gpencil/gpencil_render.c
+++ b/source/blender/draw/engines/gpencil/gpencil_render.c
@@ -143,9 +143,11 @@ void GPENCIL_render_init(GPENCIL_Data *vedata,
int w = BLI_rcti_size_x(rect);
int h = BLI_rcti_size_y(rect);
if (pix_col) {
+ GPU_texture_bind(txl->render_color_tx, 0);
GPU_texture_update_sub(txl->render_color_tx, GPU_DATA_FLOAT, pix_col, x, y, 0, w, h, 0);
}
if (pix_z) {
+ GPU_texture_bind(txl->render_depth_tx, 0);
GPU_texture_update_sub(txl->render_depth_tx, GPU_DATA_FLOAT, pix_z, x, y, 0, w, h, 0);
}
}
@@ -235,6 +237,7 @@ static void GPENCIL_render_result_combined(struct RenderLayer *rl,
BLI_rcti_size_y(rect),
4,
0,
+ GPU_DATA_FLOAT,
rp->rect);
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
index 1e75f6dd5bb..c19bf1e7b50 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -137,24 +137,20 @@ void blend_mode_output(
}
}
-#ifdef GPU_VERTEX_SHADER
-# define IN_OUT out
-#else
-# define IN_OUT in
-#endif
-
-/* Shader interface. */
-IN_OUT vec4 finalColorMul;
-IN_OUT vec4 finalColorAdd;
-IN_OUT vec3 finalPos;
-IN_OUT vec2 finalUvs;
-noperspective IN_OUT float strokeThickness;
-noperspective IN_OUT float strokeHardeness;
-flat IN_OUT vec2 strokeAspect;
-flat IN_OUT vec2 strokePt1;
-flat IN_OUT vec2 strokePt2;
-flat IN_OUT int matFlag;
-flat IN_OUT float depth;
+IN_OUT ShaderStageInterface
+{
+ vec4 finalColorMul;
+ vec4 finalColorAdd;
+ vec3 finalPos;
+ vec2 finalUvs;
+ noperspective float strokeThickness;
+ noperspective float strokeHardeness;
+ flat vec2 strokeAspect;
+ flat vec2 strokePt1;
+ flat vec2 strokePt2;
+ flat int matFlag;
+ flat float depth;
+};
#ifdef GPU_FRAGMENT_SHADER
@@ -491,7 +487,7 @@ void stroke_vertex()
vec2 screen_ofs = miter * y;
- /* Reminder: we packed the cap flag into the sign of stength and thickness sign. */
+ /* Reminder: we packed the cap flag into the sign of strength and thickness sign. */
if ((is_stroke_start && strength1 > 0.0) || (is_stroke_end && thickness1 > 0.0) ||
(miter_break && !is_stroke_start && !is_stroke_end)) {
screen_ofs += line * x;
diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c
index 7ccb5d5a753..1a3bfb9934c 100644
--- a/source/blender/draw/engines/overlay/overlay_armature.c
+++ b/source/blender/draw/engines/overlay/overlay_armature.c
@@ -178,6 +178,7 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
#define BUF_INSTANCE DRW_shgroup_call_buffer_instance
#define BUF_LINE(grp, format) DRW_shgroup_call_buffer(grp, format, GPU_PRIM_LINES)
+#define BUF_POINT(grp, format) DRW_shgroup_call_buffer(grp, format, GPU_PRIM_POINTS)
{
format = formats->instance_bone;
@@ -923,12 +924,11 @@ static float get_bone_wire_thickness(const ArmatureDrawContext *ctx, int bonefla
if (ctx->const_color) {
return ctx->const_wire;
}
- else if (boneflag & (BONE_DRAW_ACTIVE | BONE_SELECTED)) {
+ if (boneflag & (BONE_DRAW_ACTIVE | BONE_SELECTED)) {
return 2.0f;
}
- else {
- return 1.0f;
- }
+
+ return 1.0f;
}
static const float *get_bone_wire_color(const ArmatureDrawContext *ctx,
@@ -2118,10 +2118,11 @@ static void armature_context_setup(ArmatureDrawContext *ctx,
const bool do_envelope_dist,
const bool is_edit_mode,
const bool is_pose_mode,
- float *const_color)
+ const float *const_color)
{
const bool is_object_mode = !do_envelope_dist;
- const bool is_xray = (ob->dtx & OB_DRAWXRAY) != 0 || (pd->armature.do_pose_xray && is_pose_mode);
+ const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0 ||
+ (pd->armature.do_pose_xray && is_pose_mode);
const bool draw_as_wire = (ob->dt < OB_SOLID);
const bool is_filled = (!pd->armature.transparent && !draw_as_wire) || !is_object_mode;
const bool is_transparent = pd->armature.transparent || (draw_as_wire && !is_object_mode);
@@ -2217,13 +2218,13 @@ static bool POSE_is_driven_by_active_armature(Object *ob)
}
return is_active;
}
- else {
- Object *ob_mesh_deform = BKE_modifiers_is_deformed_by_meshdeform(ob);
- if (ob_mesh_deform) {
- /* Recursive. */
- return POSE_is_driven_by_active_armature(ob_mesh_deform);
- }
+
+ Object *ob_mesh_deform = BKE_modifiers_is_deformed_by_meshdeform(ob);
+ if (ob_mesh_deform) {
+ /* Recursive. */
+ return POSE_is_driven_by_active_armature(ob_mesh_deform);
}
+
return false;
}
diff --git a/source/blender/draw/engines/overlay/overlay_edit_curve.c b/source/blender/draw/engines/overlay/overlay_edit_curve.c
index 9a79c78c996..6d907646817 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_curve.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_curve.c
@@ -78,7 +78,7 @@ void OVERLAY_edit_curve_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
bool draw_normals = (pd->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_NORMALS) != 0;
- bool do_xray = (ob->dtx & OB_DRAWXRAY) != 0;
+ bool do_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
Curve *cu = ob->data;
struct GPUBatch *geom;
diff --git a/source/blender/draw/engines/overlay/overlay_edit_mesh.c b/source/blender/draw/engines/overlay/overlay_edit_mesh.c
index fd872108b00..ebc8a2f97ef 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_mesh.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_mesh.c
@@ -270,7 +270,7 @@ void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob)
struct GPUBatch *geom = NULL;
bool draw_as_solid = (ob->dt > OB_WIRE);
- bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
+ bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
bool do_occlude_wire = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
bool do_show_mesh_analysis = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_STATVIS) != 0;
bool fnormals_do = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
@@ -312,7 +312,7 @@ void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob)
overlay_edit_mesh_add_ob_to_pass(pd, ob, do_in_front);
}
- pd->edit_mesh.ghost_ob += (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
+ pd->edit_mesh.ghost_ob += (ob->dtx & OB_DRAW_IN_FRONT) ? 1 : 0;
pd->edit_mesh.edit_ob += 1;
if (DRW_state_show_text() && (pd->edit_mesh.flag & OVERLAY_EDIT_TEXT)) {
diff --git a/source/blender/draw/engines/overlay/overlay_edit_text.c b/source/blender/draw/engines/overlay/overlay_edit_text.c
index 4ee936f5ce6..6ddd0e6d9be 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_text.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_text.c
@@ -182,7 +182,7 @@ void OVERLAY_edit_text_cache_populate(OVERLAY_Data *vedata, Object *ob)
OVERLAY_PrivateData *pd = vedata->stl->pd;
Curve *cu = ob->data;
struct GPUBatch *geom;
- bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
+ bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
bool has_surface = (cu->flag & (CU_FRONT | CU_BACK)) || cu->ext1 != 0.0f || cu->ext2 != 0.0f;
if ((cu->flag & CU_FAST) || !has_surface) {
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index e76b3c82c1d..bc96a03da31 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -182,7 +182,6 @@ static void OVERLAY_cache_init(void *vedata)
OVERLAY_motion_path_cache_init(vedata);
OVERLAY_outline_cache_init(vedata);
OVERLAY_particle_cache_init(vedata);
- OVERLAY_pointcloud_cache_init(vedata);
OVERLAY_wireframe_cache_init(vedata);
}
@@ -403,12 +402,6 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
OVERLAY_particle_cache_populate(vedata, ob);
}
- /* TODO: these should not be overlays, just here for testing since it's
- * easier to implement than integrating it into eevee/workbench. */
- if (ob->type == OB_POINTCLOUD) {
- OVERLAY_pointcloud_cache_populate(vedata, ob);
- }
-
/* Relationship, object center, bounbox ... */
if (!pd->hide_overlays) {
OVERLAY_extra_cache_populate(vedata, ob);
@@ -482,7 +475,6 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_armature_draw(vedata);
OVERLAY_particle_draw(vedata);
OVERLAY_metaball_draw(vedata);
- OVERLAY_pointcloud_draw(vedata);
OVERLAY_gpencil_draw(vedata);
OVERLAY_extra_draw(vedata);
diff --git a/source/blender/draw/engines/overlay/overlay_engine.h b/source/blender/draw/engines/overlay/overlay_engine.h
index 795e3805037..f9f6ee0511c 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.h
+++ b/source/blender/draw/engines/overlay/overlay_engine.h
@@ -20,9 +20,6 @@
* \ingroup draw_engine
*/
-#ifndef __OVERLAY_ENGINE_H__
-#define __OVERLAY_ENGINE_H__
+#pragma once
extern DrawEngineType draw_engine_overlay_type;
-
-#endif /* __OVERLAY_ENGINE_H__ */
diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c
index c0407345729..c7c4e2b1a3a 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.c
+++ b/source/blender/draw/engines/overlay/overlay_extra.c
@@ -53,8 +53,6 @@
#include "ED_view3d.h"
-#include "GPU_draw.h"
-
#include "overlay_private.h"
#include "draw_common.h"
@@ -199,6 +197,9 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
cb->extra_loose_points = grp = DRW_shgroup_create(sh, extra_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
+
+ /* Buffer access for drawing isolated points, matching `extra_lines`. */
+ cb->extra_points = BUF_POINT(grp, formats->point_extra);
}
{
format = formats->pos;
@@ -230,6 +231,11 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
}
}
+void OVERLAY_extra_point(OVERLAY_ExtraCallBuffers *cb, const float point[3], const float color[4])
+{
+ DRW_buffer_add_entry(cb->extra_points, point, color);
+}
+
void OVERLAY_extra_line_dashed(OVERLAY_ExtraCallBuffers *cb,
const float start[3],
const float end[3],
@@ -250,7 +256,7 @@ void OVERLAY_extra_line(OVERLAY_ExtraCallBuffers *cb,
OVERLAY_ExtraCallBuffers *OVERLAY_extra_call_buffer_get(OVERLAY_Data *vedata, Object *ob)
{
- bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
+ bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
OVERLAY_PrivateData *pd = vedata->stl->pd;
return &pd->extra_call_buffers[do_in_front];
}
@@ -539,7 +545,7 @@ static void OVERLAY_forcefield(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLay
if (cu && (cu->flag & CU_PATH) && ob->runtime.curve_cache->path &&
ob->runtime.curve_cache->path->data) {
instdata.size_x = instdata.size_y = instdata.size_z = pd->f_strength;
- float pos[3], tmp[3];
+ float pos[4], tmp[3];
where_on_path(ob, 0.0f, pos, tmp, NULL, NULL, NULL);
copy_v3_v3(instdata.pos, ob->obmat[3]);
translate_m4(instdata.mat, pos[0], pos[1], pos[2]);
@@ -1012,9 +1018,8 @@ static float camera_offaxis_shiftx_get(Scene *scene,
const float width = instdata->corner_x * 2.0f;
return delta_shiftx * width;
}
- else {
- return 0.0;
- }
+
+ return 0.0;
}
/**
* Draw the stereo 3d support elements (cameras, plane, volume).
@@ -1276,6 +1281,19 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
OVERLAY_extra_line_dashed(cb, parent_pos, ob->obmat[3], relation_color);
}
+ /* Drawing the hook lines. */
+ for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Hook) {
+ HookModifierData *hmd = (HookModifierData *)md;
+ float center[3];
+ mul_v3_m4v3(center, ob->obmat, hmd->cent);
+ if (hmd->object) {
+ OVERLAY_extra_line_dashed(cb, hmd->object->obmat[3], center, relation_color);
+ }
+ OVERLAY_extra_point(cb, center, relation_color);
+ }
+ }
+
if (ob->rigidbody_constraint) {
Object *rbc_ob1 = ob->rigidbody_constraint->ob1;
Object *rbc_ob2 = ob->rigidbody_constraint->ob2;
@@ -1318,7 +1336,7 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
else {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
- if ((cti && cti->get_constraint_targets) && (curcon->ui_expand_flag && (1 << 0))) {
+ if ((cti && cti->get_constraint_targets) && (curcon->ui_expand_flag & (1 << 0))) {
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1356,7 +1374,7 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
Object *ob,
ModifierData *md,
Scene *scene,
- float *color)
+ const float *color)
{
FluidModifierData *fmd = (FluidModifierData *)md;
FluidDomainSettings *fds = fmd->domain;
@@ -1401,7 +1419,7 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
line_count /= fds->res[axis];
}
- GPU_create_smoke_velocity(fmd);
+ DRW_smoke_ensure_velocity(fmd);
GPUShader *sh = OVERLAY_shader_volume_velocity(use_needle);
DRWShadingGroup *grp = DRW_shgroup_create(sh, data->psl->extra_ps[0]);
@@ -1431,7 +1449,7 @@ static void OVERLAY_volume_free_smoke_textures(OVERLAY_Data *data)
LinkData *link;
while ((link = BLI_pophead(&data->stl->pd->smoke_domains))) {
FluidModifierData *fmd = (FluidModifierData *)link->data;
- GPU_free_smoke_velocity(fmd);
+ DRW_smoke_free_velocity(fmd);
MEM_freeN(link);
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_facing.c b/source/blender/draw/engines/overlay/overlay_facing.c
index 4eb4b8ae85b..cfeaf8e1927 100644
--- a/source/blender/draw/engines/overlay/overlay_facing.c
+++ b/source/blender/draw/engines/overlay/overlay_facing.c
@@ -60,7 +60,7 @@ void OVERLAY_facing_cache_populate(OVERLAY_Data *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
!DRW_state_is_image_render();
- const bool is_xray = (ob->dtx & OB_DRAWXRAY) != 0;
+ const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
if (use_sculpt_pbvh) {
DRW_shgroup_call_sculpt(pd->facing_grp[is_xray], ob, false, false);
diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.c
index a754f7cbd49..06d92f486d0 100644
--- a/source/blender/draw/engines/overlay/overlay_image.c
+++ b/source/blender/draw/engines/overlay/overlay_image.c
@@ -109,13 +109,12 @@ static eStereoViews camera_background_images_stereo_eye(const Scene *scene, cons
if ((scene->r.scemode & R_MULTIVIEW) == 0) {
return STEREO_LEFT_ID;
}
- else if (v3d->stereo3d_camera != STEREO_3D_ID) {
+ if (v3d->stereo3d_camera != STEREO_3D_ID) {
/* show only left or right camera */
return v3d->stereo3d_camera;
}
- else {
- return v3d->multiview_eye;
- }
+
+ return v3d->multiview_eye;
}
static void camera_background_images_stereo_setup(const Scene *scene,
@@ -162,9 +161,8 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
/* Frame is out of range, dont show. */
return NULL;
}
- else {
- camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser);
- }
+
+ camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser);
iuser->scene = draw_ctx->scene;
ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, &lock);
@@ -175,7 +173,7 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
}
width = ibuf->x;
height = ibuf->y;
- tex = GPU_texture_from_blender(image, iuser, ibuf, GL_TEXTURE_2D);
+ tex = BKE_image_get_gpu_texture(image, iuser, ibuf);
BKE_image_release_ibuf(image, ibuf, lock);
iuser->scene = NULL;
@@ -203,7 +201,7 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
}
BKE_movieclip_user_set_frame(&bgpic->cuser, ctime);
- tex = GPU_texture_from_movieclip(clip, &bgpic->cuser, GL_TEXTURE_2D);
+ tex = BKE_movieclip_get_gpu_texture(clip, &bgpic->cuser);
if (tex == NULL) {
return NULL;
}
@@ -232,7 +230,7 @@ static void OVERLAY_image_free_movieclips_textures(OVERLAY_Data *data)
LinkData *link;
while ((link = BLI_pophead(&data->stl->pd->bg_movie_clips))) {
MovieClip *clip = (MovieClip *)link->data;
- GPU_free_texture_movieclip(clip);
+ BKE_movieclip_free_gputexture(clip);
MEM_freeN(link);
}
}
@@ -383,7 +381,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (ima != NULL) {
ImageUser iuser = *ob->iuser;
camera_background_images_stereo_setup(draw_ctx->scene, draw_ctx->v3d, ima, &iuser);
- tex = GPU_texture_from_blender(ima, &iuser, NULL, GL_TEXTURE_2D);
+ tex = BKE_image_get_gpu_texture(ima, &iuser, NULL);
if (tex) {
size[0] = GPU_texture_orig_width(tex);
size[1] = GPU_texture_orig_height(tex);
@@ -405,7 +403,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
/* Use the actual depth if we are doing depth tests to determine the distance to the object */
char depth_mode = DRW_state_is_depth() ? OB_EMPTY_IMAGE_DEPTH_DEFAULT : ob->empty_image_depth;
DRWPass *pass = NULL;
- if ((ob->dtx & OB_DRAWXRAY) != 0) {
+ if ((ob->dtx & OB_DRAW_IN_FRONT) != 0) {
/* Object In Front overrides image empty depth mode. */
pass = psl->image_empties_front_ps;
}
diff --git a/source/blender/draw/engines/overlay/overlay_metaball.c b/source/blender/draw/engines/overlay/overlay_metaball.c
index 76ffbe4cc6b..c10c0a84247 100644
--- a/source/blender/draw/engines/overlay/overlay_metaball.c
+++ b/source/blender/draw/engines/overlay/overlay_metaball.c
@@ -69,7 +69,7 @@ static void metaball_instance_data_set(
void OVERLAY_edit_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
- const bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
+ const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
const bool is_select = DRW_state_is_select();
OVERLAY_PrivateData *pd = vedata->stl->pd;
MetaBall *mb = ob->data;
@@ -112,7 +112,7 @@ void OVERLAY_edit_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
{
- const bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
+ const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
OVERLAY_PrivateData *pd = vedata->stl->pd;
MetaBall *mb = ob->data;
const DRWContextState *draw_ctx = DRW_context_state_get();
diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.c
index e00ebe12cd6..214322c4adc 100644
--- a/source/blender/draw/engines/overlay/overlay_outline.c
+++ b/source/blender/draw/engines/overlay/overlay_outline.c
@@ -138,6 +138,11 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
pd->outlines_grp = grp = DRW_shgroup_create(sh_geom, psl->outlines_prepass_ps);
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
+ GPUShader *sh_geom_ptcloud = OVERLAY_shader_outline_prepass_pointcloud();
+
+ pd->outlines_ptcloud_grp = grp = DRW_shgroup_create(sh_geom_ptcloud, psl->outlines_prepass_ps);
+ DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
+
GPUShader *sh_gpencil = OVERLAY_shader_outline_prepass_gpencil();
pd->outlines_gpencil_grp = grp = DRW_shgroup_create(sh_gpencil, psl->outlines_prepass_ps);
@@ -288,6 +293,12 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
return;
}
+ if (ob->type == OB_POINTCLOUD && pd->wireframe_mode) {
+ /* Looks bad in this case. Could be relaxed if we draw a
+ * wireframe of some sort in the future. */
+ return;
+ }
+
if (dupli && !init_dupli) {
geom = dupli->outline_geom;
shgroup = dupli->outline_shgrp;
@@ -307,12 +318,18 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
}
if (geom) {
- shgroup = pd->outlines_grp;
+ shgroup = (ob->type == OB_POINTCLOUD) ? pd->outlines_ptcloud_grp : pd->outlines_grp;
}
}
if (shgroup && geom) {
- DRW_shgroup_call(shgroup, geom, ob);
+ if (ob->type == OB_POINTCLOUD) {
+ /* Draw range to avoid drawcall batching messing up the instance attrib. */
+ DRW_shgroup_call_instance_range(shgroup, ob, geom, 0, 0);
+ }
+ else {
+ DRW_shgroup_call(shgroup, geom, ob);
+ }
}
if (init_dupli) {
diff --git a/source/blender/draw/engines/overlay/overlay_paint.c b/source/blender/draw/engines/overlay/overlay_paint.c
index 652d6af54a2..f0a1e77cf05 100644
--- a/source/blender/draw/engines/overlay/overlay_paint.c
+++ b/source/blender/draw/engines/overlay/overlay_paint.c
@@ -22,6 +22,8 @@
#include "DRW_render.h"
+#include "BKE_image.h"
+
#include "DNA_mesh_types.h"
#include "DEG_depsgraph_query.h"
@@ -34,7 +36,7 @@ static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob)
if (v3d->shading.type == OB_WIRE) {
return true;
}
- else if (v3d->shading.type == OB_SOLID) {
+ if (v3d->shading.type == OB_SOLID) {
if (v3d->shading.flag & V3D_SHADING_XRAY) {
return true;
}
@@ -42,8 +44,8 @@ static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob)
if (ob && v3d->shading.color_type == V3D_SHADING_OBJECT_COLOR) {
return ob->color[3] < 1.0f;
}
- else if (ob && ob->type == OB_MESH && ob->data &&
- v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) {
+ if (ob && ob->type == OB_MESH && ob->data &&
+ v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) {
Mesh *me = ob->data;
for (int i = 0; i < me->totcol; i++) {
Material *mat = me->mat[i];
@@ -63,7 +65,7 @@ void OVERLAY_paint_init(OVERLAY_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
pd->painting.in_front = pd->use_in_front && draw_ctx->obact &&
- (draw_ctx->obact->dtx & OB_DRAWXRAY);
+ (draw_ctx->obact->dtx & OB_DRAW_IN_FRONT);
pd->painting.alpha_blending = paint_object_is_rendered_transparent(draw_ctx->v3d,
draw_ctx->obact);
}
@@ -136,7 +138,7 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
- GPUTexture *tex = GPU_texture_from_blender(imapaint->stencil, NULL, NULL, GL_TEXTURE_2D);
+ GPUTexture *tex = BKE_image_get_gpu_texture(imapaint->stencil, NULL, NULL);
const bool mask_premult = (imapaint->stencil->alpha_mode == IMA_ALPHA_PREMUL);
const bool mask_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0;
diff --git a/source/blender/draw/engines/overlay/overlay_pointcloud.c b/source/blender/draw/engines/overlay/overlay_pointcloud.c
deleted file mode 100644
index b2a2d44bf73..00000000000
--- a/source/blender/draw/engines/overlay/overlay_pointcloud.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright 2020, Blender Foundation.
- */
-
-/** \file
- * \ingroup draw_engine
- */
-
-#include "DRW_render.h"
-
-#include "DEG_depsgraph_query.h"
-
-#include "DNA_pointcloud_types.h"
-
-#include "BKE_pointcache.h"
-
-#include "overlay_private.h"
-
-/* -------------------------------------------------------------------- */
-/** \name PointCloud
- * \{ */
-
-void OVERLAY_pointcloud_cache_init(OVERLAY_Data *vedata)
-{
- OVERLAY_PassList *psl = vedata->psl;
- OVERLAY_PrivateData *pd = vedata->stl->pd;
- GPUShader *sh;
- DRWShadingGroup *grp;
-
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
- DRW_PASS_CREATE(psl->pointcloud_ps, state | pd->clipping_state);
-
- sh = OVERLAY_shader_pointcloud_dot();
- pd->pointcloud_dots_grp = grp = DRW_shgroup_create(sh, psl->pointcloud_ps);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
-}
-
-void OVERLAY_pointcloud_cache_populate(OVERLAY_Data *vedata, Object *ob)
-{
- OVERLAY_PrivateData *pd = vedata->stl->pd;
-
- struct GPUBatch *geom = DRW_cache_pointcloud_get_dots(ob);
-
- const float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
-
- DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->pointcloud_dots_grp);
- DRW_shgroup_uniform_vec4_copy(grp, "color", color);
- DRW_shgroup_call(grp, geom, ob);
-}
-
-void OVERLAY_pointcloud_draw(OVERLAY_Data *vedata)
-{
- OVERLAY_PassList *psl = vedata->psl;
-
- DRW_draw_pass(psl->pointcloud_ps);
-}
-
-/** \} */
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 59fa58c0c03..a8ac2616c02 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -20,8 +20,7 @@
* \ingroup DNA
*/
-#ifndef __OVERLAY_PRIVATE_H__
-#define __OVERLAY_PRIVATE_H__
+#pragma once
#ifdef __APPLE__
# define USE_GEOM_SHADER_WORKAROUND 1
@@ -149,6 +148,7 @@ typedef struct OVERLAY_ExtraCallBuffers {
DRWCallBuffer *extra_dashed_lines;
DRWCallBuffer *extra_lines;
+ DRWCallBuffer *extra_points;
DRWCallBuffer *field_curve;
DRWCallBuffer *field_force;
@@ -243,6 +243,7 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *motion_path_lines_grp;
DRWShadingGroup *motion_path_points_grp;
DRWShadingGroup *outlines_grp;
+ DRWShadingGroup *outlines_ptcloud_grp;
DRWShadingGroup *outlines_gpencil_grp;
DRWShadingGroup *paint_depth_grp;
DRWShadingGroup *paint_surf_grp;
@@ -387,6 +388,7 @@ typedef struct OVERLAY_InstanceFormats {
struct GPUVertFormat *pos;
struct GPUVertFormat *pos_color;
struct GPUVertFormat *wire_extra;
+ struct GPUVertFormat *point_extra;
} OVERLAY_InstanceFormats;
/* Pack data into the last row of the 4x4 matrix. It will be decoded by the vertex shader. */
@@ -480,6 +482,7 @@ void OVERLAY_lightprobe_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_speaker_cache_populate(OVERLAY_Data *vedata, Object *ob);
OVERLAY_ExtraCallBuffers *OVERLAY_extra_call_buffer_get(OVERLAY_Data *vedata, Object *ob);
+void OVERLAY_extra_point(OVERLAY_ExtraCallBuffers *cb, const float point[3], const float color[4]);
void OVERLAY_extra_line_dashed(OVERLAY_ExtraCallBuffers *cb,
const float start[3],
const float end[3],
@@ -550,10 +553,6 @@ void OVERLAY_particle_cache_init(OVERLAY_Data *vedata);
void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_particle_draw(OVERLAY_Data *vedata);
-void OVERLAY_pointcloud_cache_init(OVERLAY_Data *vedata);
-void OVERLAY_pointcloud_cache_populate(OVERLAY_Data *vedata, Object *ob);
-void OVERLAY_pointcloud_draw(OVERLAY_Data *vedata);
-
void OVERLAY_sculpt_cache_init(OVERLAY_Data *vedata);
void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_sculpt_draw(OVERLAY_Data *vedata);
@@ -610,6 +609,7 @@ GPUShader *OVERLAY_shader_motion_path_vert(void);
GPUShader *OVERLAY_shader_uniform_color(void);
GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
+GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void);
GPUShader *OVERLAY_shader_extra_grid(void);
GPUShader *OVERLAY_shader_outline_detect(void);
GPUShader *OVERLAY_shader_paint_face(void);
@@ -620,7 +620,6 @@ GPUShader *OVERLAY_shader_paint_weight(void);
GPUShader *OVERLAY_shader_paint_wire(void);
GPUShader *OVERLAY_shader_particle_dot(void);
GPUShader *OVERLAY_shader_particle_shape(void);
-GPUShader *OVERLAY_shader_pointcloud_dot(void);
GPUShader *OVERLAY_shader_sculpt_mask(void);
GPUShader *OVERLAY_shader_volume_velocity(bool use_needle);
GPUShader *OVERLAY_shader_wireframe(bool custom_bias);
@@ -630,5 +629,3 @@ GPUShader *OVERLAY_shader_xray_fade(void);
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void);
void OVERLAY_shader_free(void);
-
-#endif /* __OVERLAY_PRIVATE_H__ */
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index edf91c99531..e3cb052890b 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -103,8 +103,6 @@ extern char datatoc_paint_weight_vert_glsl[];
extern char datatoc_paint_wire_vert_glsl[];
extern char datatoc_particle_vert_glsl[];
extern char datatoc_particle_frag_glsl[];
-extern char datatoc_pointcloud_vert_glsl[];
-extern char datatoc_pointcloud_frag_glsl[];
extern char datatoc_sculpt_mask_vert_glsl[];
extern char datatoc_sculpt_mask_frag_glsl[];
extern char datatoc_volume_velocity_vert_glsl[];
@@ -127,6 +125,7 @@ extern char datatoc_common_fullscreen_vert_glsl[];
extern char datatoc_common_fxaa_lib_glsl[];
extern char datatoc_common_smaa_lib_glsl[];
extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_pointcloud_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
typedef struct OVERLAY_Shaders {
@@ -181,6 +180,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *motion_path_vert;
GPUShader *outline_prepass;
GPUShader *outline_prepass_gpencil;
+ GPUShader *outline_prepass_pointcloud;
GPUShader *outline_prepass_wire;
GPUShader *outline_detect;
GPUShader *paint_face;
@@ -1135,6 +1135,33 @@ GPUShader *OVERLAY_shader_outline_prepass_gpencil(void)
return sh_data->outline_prepass_gpencil;
}
+GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
+ if (!sh_data->outline_prepass_pointcloud) {
+ sh_data->outline_prepass_pointcloud = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_common_pointcloud_lib_glsl,
+ datatoc_gpu_shader_common_obinfos_lib_glsl,
+ datatoc_outline_prepass_vert_glsl,
+ NULL},
+ .frag = (const char *[]){datatoc_common_view_lib_glsl,
+ datatoc_gpencil_common_lib_glsl,
+ datatoc_outline_prepass_frag_glsl,
+ NULL},
+ .defs = (const char *[]){sh_cfg->def,
+ "#define POINTCLOUD\n",
+ "#define INSTANCED_ATTR\n",
+ "#define UNIFORM_RESOURCE_ID\n",
+ NULL},
+ });
+ }
+ return sh_data->outline_prepass_pointcloud;
+}
+
GPUShader *OVERLAY_shader_outline_detect(void)
{
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
@@ -1306,25 +1333,6 @@ GPUShader *OVERLAY_shader_particle_shape(void)
return sh_data->particle_shape;
}
-GPUShader *OVERLAY_shader_pointcloud_dot(void)
-{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
- OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
- if (!sh_data->pointcloud_dot) {
- sh_data->pointcloud_dot = GPU_shader_create_from_arrays({
- .vert = (const char *[]){sh_cfg->lib,
- datatoc_common_globals_lib_glsl,
- datatoc_common_view_lib_glsl,
- datatoc_pointcloud_vert_glsl,
- NULL},
- .frag = (const char *[]){datatoc_pointcloud_frag_glsl, NULL},
- .defs = (const char *[]){sh_cfg->def, "#define USE_DOTS\n", NULL},
- });
- }
- return sh_data->pointcloud_dot;
-}
-
GPUShader *OVERLAY_shader_sculpt_mask(void)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -1468,6 +1476,11 @@ OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void)
{"pos", DRW_ATTR_FLOAT, 3},
{"colorid", DRW_ATTR_INT, 1},
});
+ DRW_shgroup_instance_format(g_formats.point_extra,
+ {
+ {"pos", DRW_ATTR_FLOAT, 3},
+ {"colorid", DRW_ATTR_INT, 1},
+ });
DRW_shgroup_instance_format(g_formats.instance_bone,
{
{"inst_obmat", DRW_ATTR_FLOAT, 16},
diff --git a/source/blender/draw/engines/overlay/overlay_wireframe.c b/source/blender/draw/engines/overlay/overlay_wireframe.c
index ea45ad5190c..4129983a901 100644
--- a/source/blender/draw/engines/overlay/overlay_wireframe.c
+++ b/source/blender/draw/engines/overlay/overlay_wireframe.c
@@ -102,12 +102,9 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_bool_copy(grp, "isHair", false);
pd->wires_all_grp[xray][use_coloring] = grp = DRW_shgroup_create(wires_sh, pass);
- DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tx);
DRW_shgroup_uniform_float_copy(grp, "wireStepParam", 1.0f);
pd->wires_hair_grp[xray][use_coloring] = grp = DRW_shgroup_create(wires_sh, pass);
- /* TODO(fclem) texture ref persist */
- DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tx);
DRW_shgroup_uniform_bool_copy(grp, "isHair", true);
DRW_shgroup_uniform_float_copy(grp, "wireStepParam", 10.0f);
}
@@ -134,7 +131,7 @@ void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
static void wireframe_hair_cache_populate(OVERLAY_Data *vedata, Object *ob, ParticleSystem *psys)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
- const bool is_xray = (ob->dtx & OB_DRAWXRAY) != 0;
+ const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
Object *dupli_parent = DRW_object_get_dupli_parent(ob);
DupliObject *dupli_object = DRW_object_get_dupli(ob);
@@ -170,7 +167,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES) != 0;
- const bool is_xray = (ob->dtx & OB_DRAWXRAY) != 0;
+ const bool is_xray = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
const bool is_mesh = ob->type == OB_MESH;
const bool is_mesh_verts_only = is_mesh && (((Mesh *)ob->data)->totedge == 0 &&
((Mesh *)ob->data)->totvert > 0);
@@ -235,10 +232,15 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
}
}
- if (use_wire && ob->type == OB_VOLUME) {
- /* Volume object as points exception. */
- Volume *volume = ob->data;
- if (volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS) {
+ if (use_wire && ELEM(ob->type, OB_VOLUME, OB_POINTCLOUD)) {
+ bool draw_as_points = true;
+ if (ob->type == OB_VOLUME) {
+ /* Volume object as points exception. */
+ Volume *volume = ob->data;
+ draw_as_points = volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS;
+ }
+
+ if (draw_as_points) {
float *color;
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
diff --git a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl b/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl
index 0d01f67c6ea..2989e07691f 100644
--- a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
uniform sampler2D colorTex;
uniform sampler2D depthTex;
uniform sampler2D lineTex;
diff --git a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl
index 380708795e9..0925901a9c9 100644
--- a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl
@@ -14,19 +14,6 @@ layout(depth_greater) out float gl_FragDepth;
layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec4 lineOutput;
-#define cameraPos ViewMatrixInverse[3].xyz
-
-float get_depth_from_view_z(float z)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- z = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
- }
- else {
- z = z * ProjectionMatrix[2][2] / (1.0 - ProjectionMatrix[3][2]);
- }
- return z * 0.5 + 0.5;
-}
-
void main()
{
const float sphere_radius = 0.05;
diff --git a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl
index 317e9fe0447..d0b68df0625 100644
--- a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl
@@ -14,8 +14,6 @@ uniform float meshSize;
uniform float lineKernel = 0.0;
uniform sampler2D depthBuffer;
-#define cameraPos (ViewMatrixInverse[3].xyz)
-
uniform int gridFlag;
#define STEPS_LEN 8
diff --git a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl
index 496bb011c74..dd0e771ad93 100644
--- a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl
@@ -7,8 +7,6 @@ uniform float meshSize;
uniform int gridFlag;
-#define cameraPos (ViewMatrixInverse[3].xyz)
-
#define PLANE_XY (1 << 4)
#define PLANE_XZ (1 << 5)
#define PLANE_YZ (1 << 6)
diff --git a/source/blender/draw/engines/overlay/shaders/outline_prepass_vert.glsl b/source/blender/draw/engines/overlay/shaders/outline_prepass_vert.glsl
index a2021759196..582a7c6cae2 100644
--- a/source/blender/draw/engines/overlay/shaders/outline_prepass_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/outline_prepass_vert.glsl
@@ -1,7 +1,7 @@
uniform bool isTransform;
-#ifndef USE_GPENCIL
+#if !defined(USE_GPENCIL) && !defined(POINTCLOUD)
in vec3 pos;
#endif
@@ -56,7 +56,11 @@ void main()
# endif
#else
+# ifdef POINTCLOUD
+ vec3 world_pos = pointcloud_get_pos();
+# else
vec3 world_pos = point_object_to_world(pos);
+# endif
gl_Position = point_world_to_ndc(world_pos);
# ifdef USE_GEOM
vPos = point_world_to_view(world_pos);
diff --git a/source/blender/draw/engines/overlay/shaders/pointcloud_frag.glsl b/source/blender/draw/engines/overlay/shaders/pointcloud_frag.glsl
deleted file mode 100644
index 36928d0c776..00000000000
--- a/source/blender/draw/engines/overlay/shaders/pointcloud_frag.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-
-in vec4 finalColor;
-
-out vec4 fragColor;
-
-void main()
-{
- float dist = length(gl_PointCoord - vec2(0.5));
-
- if (dist > 0.5) {
- discard;
- }
- /* Nice sphere falloff. */
- float intensity = sqrt(1.0 - dist * 2.0) * 0.5 + 0.5;
- fragColor = finalColor * vec4(intensity, intensity, intensity, 1.0);
-}
diff --git a/source/blender/draw/engines/overlay/shaders/pointcloud_vert.glsl b/source/blender/draw/engines/overlay/shaders/pointcloud_vert.glsl
deleted file mode 100644
index d71ccee5159..00000000000
--- a/source/blender/draw/engines/overlay/shaders/pointcloud_vert.glsl
+++ /dev/null
@@ -1,27 +0,0 @@
-
-uniform vec4 color;
-
-/* ---- Per instance Attrs ---- */
-in vec3 pointcloud_pos;
-in vec3 pointcloud_radius;
-
-out vec4 finalColor;
-
-void main()
-{
- vec3 world_pos = point_object_to_world(pointcloud_pos);
-
- vec3 world_size = abs(mat3(ModelMatrix) * vec3(pointcloud_radius));
- float world_radius = (world_size.x + world_size.y + world_size.z) / 3.0;
-
- gl_Position = point_world_to_ndc(world_pos);
- /* World sized points. */
- gl_PointSize = sizePixel * world_radius * ProjectionMatrix[1][1] * sizeViewport.y /
- gl_Position.w;
-
- finalColor = color;
-
-#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance(world_pos);
-#endif
-}
diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c
index bb7c947a0b9..8cee6c4ee9f 100644
--- a/source/blender/draw/engines/select/select_engine.c
+++ b/source/blender/draw/engines/select/select_engine.c
@@ -378,7 +378,7 @@ RenderEngineType DRW_engine_viewport_select_type = {
NULL,
SELECT_ENGINE,
N_("Select ID"),
- RE_INTERNAL | RE_USE_STEREO_VIEWPORT,
+ RE_INTERNAL | RE_USE_STEREO_VIEWPORT | RE_USE_GPU_CONTEXT,
NULL,
NULL,
NULL,
diff --git a/source/blender/draw/engines/select/select_engine.h b/source/blender/draw/engines/select/select_engine.h
index 79139d9deaf..2b35cf6bee5 100644
--- a/source/blender/draw/engines/select/select_engine.h
+++ b/source/blender/draw/engines/select/select_engine.h
@@ -20,8 +20,7 @@
* \ingroup draw_engine
*/
-#ifndef __SELECT_ENGINE_H__
-#define __SELECT_ENGINE_H__
+#pragma once
extern DrawEngineType draw_engine_select_type;
extern RenderEngineType DRW_engine_viewport_select_type;
@@ -30,5 +29,3 @@ struct SELECTID_Context *DRW_select_engine_context_get(void);
struct GPUFrameBuffer *DRW_engine_select_framebuffer_get(void);
struct GPUTexture *DRW_engine_select_texture_get(void);
-
-#endif /* __SELECT_ENGINE_H__ */
diff --git a/source/blender/draw/engines/select/select_private.h b/source/blender/draw/engines/select/select_private.h
index 1e99a49252e..763d1a0897d 100644
--- a/source/blender/draw/engines/select/select_private.h
+++ b/source/blender/draw/engines/select/select_private.h
@@ -20,8 +20,7 @@
* \ingroup draw_engine
*/
-#ifndef __SELECT_PRIVATE_H__
-#define __SELECT_PRIVATE_H__
+#pragma once
#define USE_CAGE_OCCLUSION
@@ -78,5 +77,3 @@ void select_id_draw_object(void *vedata,
uint *r_vert_offset,
uint *r_edge_offset,
uint *r_face_offset);
-
-#endif /* __SELECT_PRIVATE_H__ */
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
index d8cb4f86f7b..d0d52c8485b 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
@@ -28,7 +28,7 @@ void cavity_compute(vec2 screenco,
return;
}
- vec3 position = view_position_from_depth(screenco, depth, world_data.viewvecs, ProjectionMatrix);
+ vec3 position = get_view_space_from_depth(screenco, depth);
vec3 normal = workbench_normal_decode(texture(normalBuffer, screenco));
vec2 jitter_co = (screenco * world_data.viewport_size.xy) * world_data.cavity_jitter_scale;
@@ -68,8 +68,7 @@ void cavity_compute(vec2 screenco,
bool is_background = (s_depth == 1.0);
/* This trick provide good edge effect even if no neighbor is found. */
s_depth = (is_background) ? depth : s_depth;
- vec3 s_pos = view_position_from_depth(
- uvcoords, s_depth, world_data.viewvecs, ProjectionMatrix);
+ vec3 s_pos = get_view_space_from_depth(uvcoords, s_depth);
if (is_background) {
s_pos.z -= world_data.cavity_distance;
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 25eaf003e07..eb61edca6c7 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -48,7 +48,7 @@ float workbench_float_pair_encode(float v1, float v2)
{
// const uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS);
// const uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS);
- /* Same as above because some compiler are dumb af. and think we use mediump int. */
+ /* Same as above because some compiler are very dumb and think we use medium int. */
const int v1_mask = 0x1F;
const int v2_mask = 0x7;
int iv1 = int(v1 * float(v1_mask));
@@ -60,38 +60,10 @@ void workbench_float_pair_decode(float data, out float v1, out float v2)
{
// const uint v1_mask = ~(0xFFFFFFFFu << ROUGHNESS_BITS);
// const uint v2_mask = ~(0xFFFFFFFFu << METALLIC_BITS);
- /* Same as above because some compiler are dumb af. and think we use mediump int. */
+ /* Same as above because some compiler are very dumb and think we use medium int. */
const int v1_mask = 0x1F;
const int v2_mask = 0x7;
int idata = int(data);
v1 = float(idata & v1_mask) * (1.0 / float(v1_mask));
v2 = float(idata >> int(ROUGHNESS_BITS)) * (1.0 / float(v2_mask));
}
-
-vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[3], mat4 proj_mat)
-{
- if (proj_mat[3][3] == 0.0) {
- return normalize(viewvecs[0].xyz + vec3(uv, 0.0) * viewvecs[1].xyz);
- }
- else {
- return vec3(0.0, 0.0, 1.0);
- }
-}
-
-vec3 view_position_from_depth(vec2 uvcoords, float depth, vec4 viewvecs[3], mat4 proj_mat)
-{
- if (proj_mat[3][3] == 0.0) {
- /* Perspective */
- float d = 2.0 * depth - 1.0;
-
- float zview = -proj_mat[3][2] / (d + proj_mat[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;
- }
-}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
index cdb9823096c..6e10a656fc1 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
@@ -14,7 +14,7 @@ out vec4 fragColor;
void main()
{
/* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
- vec3 I = view_vector_from_screen_uv(uvcoordsvar.st, world_data.viewvecs, ProjectionMatrix);
+ vec3 I = get_view_vector_from_screen_uv(uvcoordsvar.st);
vec3 N = workbench_normal_decode(texture(normalBuffer, uvcoordsvar.st));
vec4 mat_data = texture(materialBuffer, uvcoordsvar.st);
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 5f3283e1643..a76a14fa750 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl
@@ -5,7 +5,6 @@ struct LightData {
};
struct WorldData {
- vec4 viewvecs[3];
vec4 viewport_size;
vec4 object_outline_color;
vec4 shadow_direction_vs;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
index 51007a9f246..71816f6ff6e 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
@@ -1,3 +1,6 @@
+
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
/**
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
@@ -21,13 +24,6 @@ uniform sampler2D noiseTex;
#define dof_distance dofParams.y
#define dof_invsensorsize dofParams.z
-#define M_PI 3.1415926535897932 /* pi */
-
-float max_v4(vec4 v)
-{
- return max(max(v.x, v.y), max(v.z, v.w));
-}
-
#define weighted_sum(a, b, c, d, e, e_sum) \
((a)*e.x + (b)*e.y + (c)*e.z + (d)*e.w) / max(1e-6, e_sum);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_hair_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_hair_vert.glsl
index 6a7bc185fe9..3e1ea14f47c 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_hair_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_hair_vert.glsl
@@ -90,5 +90,5 @@ void main()
packed_rough_metal = workbench_float_pair_encode(roughness, metallic);
#endif
- object_id = int((uint(resource_id) + 1u) & 0xFFu);
+ object_id = int(uint(resource_handle) & 0xFFFFu) + 1;
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl
new file mode 100644
index 00000000000..6f61874b8f5
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl
@@ -0,0 +1,38 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl)
+#pragma BLENDER_REQUIRE(workbench_shader_interface_lib.glsl)
+#pragma BLENDER_REQUIRE(workbench_common_lib.glsl)
+#pragma BLENDER_REQUIRE(workbench_material_lib.glsl)
+#pragma BLENDER_REQUIRE(workbench_image_lib.glsl)
+
+void main()
+{
+ vec3 world_pos;
+ pointcloud_get_pos_and_nor(world_pos, normal_interp);
+
+ normal_interp = normalize(normal_world_to_view(normal_interp));
+
+ gl_Position = point_world_to_ndc(world_pos);
+
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance(world_pos);
+#endif
+
+ uv_interp = vec2(0.0);
+
+#ifdef OPAQUE_MATERIAL
+ float metallic, roughness;
+#endif
+ workbench_material_data_get(resource_handle, color_interp, alpha_interp, roughness, metallic);
+
+ if (materialIndex == 0) {
+ color_interp = vec3(1.0);
+ }
+
+#ifdef OPAQUE_MATERIAL
+ packed_rough_metal = workbench_float_pair_encode(roughness, metallic);
+#endif
+
+ object_id = int(uint(resource_handle) & 0xFFFFu) + 1;
+}
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 31e298d1540..1192081caf1 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
@@ -36,5 +36,5 @@ void main()
packed_rough_metal = workbench_float_pair_encode(roughness, metallic);
#endif
- object_id = int((uint(resource_id) + 1u) & 0xFFu);
+ object_id = int(uint(resource_handle) & 0xFFFFu) + 1;
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shader_interface_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shader_interface_lib.glsl
index 8e2f7ba4735..6bfa351aeb0 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shader_interface_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shader_interface_lib.glsl
@@ -1,10 +1,4 @@
-#ifdef GPU_VERTEX_SHADER
-# define IN_OUT out
-#else
-# define IN_OUT in
-#endif
-
IN_OUT ShaderStageInterface
{
vec3 normal_interp;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
index 3c2d1a9c0c7..fd4d00d96dd 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
@@ -15,7 +15,7 @@ layout(location = 1) out vec4 revealageAccum;
layout(location = 2) out uint objectId;
/* Special function only to be used with calculate_transparent_weight(). */
-float linear_zdepth(float depth, vec4 viewvecs[3], mat4 proj_mat)
+float linear_zdepth(float depth, vec4 viewvecs[2], mat4 proj_mat)
{
if (proj_mat[3][3] == 0.0) {
float d = 2.0 * depth - 1.0;
@@ -33,7 +33,7 @@ float linear_zdepth(float depth, vec4 viewvecs[3], mat4 proj_mat)
*/
float calculate_transparent_weight(void)
{
- float z = linear_zdepth(gl_FragCoord.z, world_data.viewvecs, ProjectionMatrix);
+ float z = linear_zdepth(gl_FragCoord.z, ViewVecs, ProjectionMatrix);
#if 0
/* Eq 10 : Good for surfaces with varying opacity (like particles) */
float a = min(1.0, alpha * 10.0) + 0.01;
@@ -57,7 +57,7 @@ void main()
{
/* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
vec2 uv_viewport = gl_FragCoord.xy * world_data.viewport_size_inv;
- vec3 I = view_vector_from_screen_uv(uv_viewport, world_data.viewvecs, ProjectionMatrix);
+ vec3 I = get_view_vector_from_screen_uv(uv_viewport);
vec3 N = normalize(normal_interp);
vec3 color = color_interp;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
index 2920a504062..aa938d80fa3 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -1,4 +1,5 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_common_obinfos_lib.glsl)
#pragma BLENDER_REQUIRE(workbench_data_lib.glsl)
@@ -33,11 +34,6 @@ float phase_function_isotropic()
return 1.0 / (4.0 * M_PI);
}
-float max_v3(vec3 v)
-{
- return max(v.x, max(v.y, v.z));
-}
-
float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
{
/* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
@@ -194,10 +190,8 @@ void main()
float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r;
float depth_end = min(depth, gl_FragCoord.z);
- vec3 vs_ray_end = view_position_from_depth(
- screen_uv, depth_end, world_data.viewvecs, ProjectionMatrix);
- vec3 vs_ray_ori = view_position_from_depth(
- screen_uv, 0.0, world_data.viewvecs, ProjectionMatrix);
+ vec3 vs_ray_end = get_view_space_from_depth(screen_uv, depth_end);
+ vec3 vs_ray_ori = get_view_space_from_depth(screen_uv, 0.0);
vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0);
vs_ray_dir /= abs(vs_ray_dir.z);
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index 7b08e97ac31..0d7f4ee660b 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -86,43 +86,6 @@ static WORKBENCH_ViewLayerData *workbench_view_layer_data_ensure_ex(struct ViewL
/* \} */
-static void workbench_viewvecs_update(float r_viewvecs[3][4])
-{
- float invproj[4][4];
- const bool is_persp = DRW_view_is_persp_get(NULL);
- DRW_view_winmat_get(NULL, invproj, true);
-
- /* view vectors for the corners of the view frustum.
- * Can be used to recreate the world space position easily */
- copy_v4_fl4(r_viewvecs[0], -1.0f, -1.0f, -1.0f, 1.0f);
- copy_v4_fl4(r_viewvecs[1], 1.0f, -1.0f, -1.0f, 1.0f);
- copy_v4_fl4(r_viewvecs[2], -1.0f, 1.0f, -1.0f, 1.0f);
-
- /* convert the view vectors to view space */
- for (int i = 0; i < 3; i++) {
- mul_m4_v4(invproj, r_viewvecs[i]);
- /* normalized trick see:
- * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
- mul_v3_fl(r_viewvecs[i], 1.0f / r_viewvecs[i][3]);
- if (is_persp) {
- mul_v3_fl(r_viewvecs[i], 1.0f / r_viewvecs[i][2]);
- }
- r_viewvecs[i][3] = 1.0;
- }
-
- /* we need to store the differences */
- r_viewvecs[1][0] -= r_viewvecs[0][0];
- r_viewvecs[1][1] = r_viewvecs[2][1] - r_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]);
- r_viewvecs[1][2] = vec_far[2] - r_viewvecs[0][2];
- }
-}
-
static void workbench_studiolight_data_update(WORKBENCH_PrivateData *wpd, WORKBENCH_UBO_World *wd)
{
StudioLight *studiolight = wpd->studio_light;
@@ -256,6 +219,8 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
}
else if (XRAY_ENABLED(v3d)) {
wpd->shading.xray_alpha = XRAY_ALPHA(v3d);
+ /* Disable shading options that aren't supported in transparency mode. */
+ wpd->shading.flag &= ~(V3D_SHADING_SHADOW | V3D_SHADING_CAVITY | V3D_SHADING_DEPTH_OF_FIELD);
}
else {
wpd->shading.xray_alpha = 1.0f;
@@ -309,7 +274,6 @@ void workbench_update_world_ubo(WORKBENCH_PrivateData *wpd)
workbench_studiolight_data_update(wpd, &wd);
workbench_shadow_data_update(wpd, &wd);
workbench_cavity_data_update(wpd, &wd);
- workbench_viewvecs_update(wd.viewvecs);
DRW_uniformbuffer_update(wpd->world_ubo, &wd);
}
diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
index 0e896c4b7bb..faf64b55c2d 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
@@ -112,17 +112,15 @@ int workbench_antialiasing_sample_count_get(WORKBENCH_PrivateData *wpd)
/* Only draw using SMAA or no AA when navigating. */
return min_ii(wpd->preferences->viewport_aa, 1);
}
- else if (DRW_state_is_image_render()) {
+ if (DRW_state_is_image_render()) {
if (draw_ctx->v3d) {
return scene->display.viewport_aa;
}
- else {
- return scene->display.render_aa;
- }
- }
- else {
- return wpd->preferences->viewport_aa;
+
+ return scene->display.render_aa;
}
+
+ return wpd->preferences->viewport_aa;
}
void workbench_antialiasing_view_updated(WORKBENCH_Data *vedata)
@@ -361,53 +359,52 @@ bool workbench_antialiasing_setup(WORKBENCH_Data *vedata)
/* TAA accumulation has finish. Just copy the result back */
return false;
}
- else {
- const float *viewport_size = DRW_viewport_size_get();
- const DRWView *default_view = DRW_view_default_get();
- float *transform_offset;
-
- switch (wpd->taa_sample_len) {
- default:
- case 5:
- transform_offset = e_data.jitter_5[min_ii(wpd->taa_sample, 5)];
- break;
- case 8:
- transform_offset = e_data.jitter_8[min_ii(wpd->taa_sample, 8)];
- break;
- case 11:
- transform_offset = e_data.jitter_11[min_ii(wpd->taa_sample, 11)];
- break;
- case 16:
- transform_offset = e_data.jitter_16[min_ii(wpd->taa_sample, 16)];
- break;
- case 32:
- transform_offset = e_data.jitter_32[min_ii(wpd->taa_sample, 32)];
- break;
- }
-
- /* construct new matrices from transform delta */
- float winmat[4][4], viewmat[4][4], persmat[4][4];
- DRW_view_winmat_get(default_view, winmat, false);
- DRW_view_viewmat_get(default_view, viewmat, false);
- DRW_view_persmat_get(default_view, persmat, false);
- window_translate_m4(winmat,
- persmat,
- transform_offset[0] / viewport_size[0],
- transform_offset[1] / viewport_size[1]);
-
- if (wpd->view) {
- /* When rendering just update the view. This avoids recomputing the culling. */
- DRW_view_update_sub(wpd->view, viewmat, winmat);
- }
- else {
- /* TAA is not making a big change to the matrices.
- * Reuse the main view culling by creating a sub-view. */
- wpd->view = DRW_view_create_sub(default_view, viewmat, winmat);
- }
- DRW_view_set_active(wpd->view);
- return true;
+ const float *viewport_size = DRW_viewport_size_get();
+ const DRWView *default_view = DRW_view_default_get();
+ float *transform_offset;
+
+ switch (wpd->taa_sample_len) {
+ default:
+ case 5:
+ transform_offset = e_data.jitter_5[min_ii(wpd->taa_sample, 5)];
+ break;
+ case 8:
+ transform_offset = e_data.jitter_8[min_ii(wpd->taa_sample, 8)];
+ break;
+ case 11:
+ transform_offset = e_data.jitter_11[min_ii(wpd->taa_sample, 11)];
+ break;
+ case 16:
+ transform_offset = e_data.jitter_16[min_ii(wpd->taa_sample, 16)];
+ break;
+ case 32:
+ transform_offset = e_data.jitter_32[min_ii(wpd->taa_sample, 32)];
+ break;
+ }
+
+ /* construct new matrices from transform delta */
+ float winmat[4][4], viewmat[4][4], persmat[4][4];
+ DRW_view_winmat_get(default_view, winmat, false);
+ DRW_view_viewmat_get(default_view, viewmat, false);
+ DRW_view_persmat_get(default_view, persmat, false);
+
+ window_translate_m4(winmat,
+ persmat,
+ transform_offset[0] / viewport_size[0],
+ transform_offset[1] / viewport_size[1]);
+
+ if (wpd->view) {
+ /* When rendering just update the view. This avoids recomputing the culling. */
+ DRW_view_update_sub(wpd->view, viewmat, winmat);
+ }
+ else {
+ /* TAA is not making a big change to the matrices.
+ * Reuse the main view culling by creating a sub-view. */
+ wpd->view = DRW_view_create_sub(default_view, viewmat, winmat);
}
+ DRW_view_set_active(wpd->view);
+ return true;
}
void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata)
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index c8dde4d513b..53119723fab 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -130,6 +130,17 @@ static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd,
}
}
+BLI_INLINE void workbench_object_drawcall(DRWShadingGroup *grp, struct GPUBatch *geom, Object *ob)
+{
+ if (ob->type == OB_POINTCLOUD) {
+ /* Draw range to avoid drawcall batching messing up the instance attrib. */
+ DRW_shgroup_call_instance_range(grp, ob, geom, 0, 0);
+ }
+ else {
+ DRW_shgroup_call(grp, geom, ob);
+ }
+}
+
static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object *ob)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -145,7 +156,7 @@ static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object
SET_FLAG_FROM_TEST(state, imapaint->interp == IMAGEPAINT_INTERP_LINEAR, GPU_SAMPLER_FILTER);
DRWShadingGroup *grp = workbench_image_setup(wpd, ob, 0, ima, NULL, state);
- DRW_shgroup_call(grp, geom, ob);
+ workbench_object_drawcall(grp, geom, ob);
}
}
else {
@@ -157,7 +168,7 @@ static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object
continue;
}
DRWShadingGroup *grp = workbench_image_setup(wpd, ob, i + 1, NULL, NULL, 0);
- DRW_shgroup_call(grp, geoms[i], ob);
+ workbench_object_drawcall(grp, geoms[i], ob);
}
}
}
@@ -180,7 +191,12 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
geom = DRW_cache_mesh_surface_vertpaint_get(ob);
}
else {
- geom = DRW_cache_mesh_surface_sculptcolors_get(ob);
+ if (U.experimental.use_sculpt_vertex_colors) {
+ geom = DRW_cache_mesh_surface_sculptcolors_get(ob);
+ }
+ else {
+ geom = DRW_cache_mesh_surface_vertpaint_get(ob);
+ }
}
}
else {
@@ -189,7 +205,7 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
if (geom) {
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, 0, color_type, r_transp);
- DRW_shgroup_call(grp, geom, ob);
+ workbench_object_drawcall(grp, geom, ob);
}
}
else {
@@ -202,7 +218,7 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
continue;
}
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, i + 1, color_type, r_transp);
- DRW_shgroup_call(grp, geoms[i], ob);
+ workbench_object_drawcall(grp, geoms[i], ob);
}
}
}
@@ -261,8 +277,15 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
}
}
else if (color_type == V3D_SHADING_VERTEX_COLOR) {
- if ((me == NULL) || !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
- color_type = V3D_SHADING_OBJECT_COLOR;
+ if (U.experimental.use_sculpt_vertex_colors) {
+ if ((me == NULL) || !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
+ color_type = V3D_SHADING_OBJECT_COLOR;
+ }
+ }
+ else {
+ if ((me == NULL) || !CustomData_has_layer(&me->ldata, CD_MLOOPCOL)) {
+ color_type = V3D_SHADING_OBJECT_COLOR;
+ }
}
}
@@ -438,7 +461,7 @@ void workbench_cache_finish(void *ved)
/* TODO don't free reuse next redraw. */
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
- for (int k = 0; k < 2; k++) {
+ for (int k = 0; k < WORKBENCH_DATATYPE_MAX; k++) {
if (wpd->prepass[i][j][k].material_hash) {
BLI_ghash_free(wpd->prepass[i][j][k].material_hash, NULL, NULL);
wpd->prepass[i][j][k].material_hash = NULL;
@@ -618,7 +641,7 @@ RenderEngineType DRW_engine_viewport_workbench_type = {
NULL,
WORKBENCH_ENGINE,
N_("Workbench"),
- RE_INTERNAL | RE_USE_STEREO_VIEWPORT,
+ RE_INTERNAL | RE_USE_STEREO_VIEWPORT | RE_USE_GPU_CONTEXT,
NULL,
&DRW_render_to_image,
NULL,
diff --git a/source/blender/draw/engines/workbench/workbench_engine.h b/source/blender/draw/engines/workbench/workbench_engine.h
index eee53fcde07..8fd427c2683 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.h
+++ b/source/blender/draw/engines/workbench/workbench_engine.h
@@ -20,9 +20,6 @@
* \ingroup draw_engine
*/
-#ifndef __WORKBENCH_ENGINE_H__
-#define __WORKBENCH_ENGINE_H__
+#pragma once
extern RenderEngineType DRW_engine_viewport_workbench_type;
-
-#endif /* __WORKBENCH_ENGINE_H__ */
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index d6d3ff8610b..2ed63bac853 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -162,13 +162,13 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
Object *ob,
int mat_nr,
eV3DShadingColorType color_type,
- bool hair,
+ eWORKBENCH_DataType datatype,
bool *r_transp)
{
Image *ima = NULL;
ImageUser *iuser = NULL;
eGPUSamplerState sampler;
- const bool infront = (ob->dtx & OB_DRAWXRAY) != 0;
+ const bool infront = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
if (color_type == V3D_SHADING_TEXTURE_COLOR) {
workbench_material_get_image(ob, mat_nr, &ima, &iuser, &sampler);
@@ -180,7 +180,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
switch (color_type) {
case V3D_SHADING_TEXTURE_COLOR: {
- return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, sampler, hair);
+ return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, sampler, datatype);
}
case V3D_SHADING_MATERIAL_COLOR: {
/* For now, we use the same ubo for material and object coloring but with different indices.
@@ -191,7 +191,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
Material *ma = workbench_object_material_get(ob, mat_nr);
const bool transp = wpd->shading.xray_alpha < 1.0f || ma->a < 1.0f;
- WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][hair];
+ WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][datatype];
if (r_transp && transp) {
*r_transp = true;
@@ -216,7 +216,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
}
case V3D_SHADING_VERTEX_COLOR: {
const bool transp = wpd->shading.xray_alpha < 1.0f;
- DRWShadingGroup *grp = wpd->prepass[transp][infront][hair].vcol_shgrp;
+ DRWShadingGroup *grp = wpd->prepass[transp][infront][datatype].vcol_shgrp;
return grp;
}
default: {
@@ -231,15 +231,15 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
workbench_material_ubo_data(wpd, ob, NULL, &wpd->material_ubo_data_curr[mat_id], color_type);
const bool transp = wpd->shading.xray_alpha < 1.0f || ob->color[3] < 1.0f;
- DRWShadingGroup *grp = wpd->prepass[transp][infront][hair].common_shgrp;
+ DRWShadingGroup **grp = &wpd->prepass[transp][infront][datatype].common_shgrp;
if (resource_changed) {
- grp = DRW_shgroup_create_sub(grp);
- DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
+ *grp = DRW_shgroup_create_sub(*grp);
+ DRW_shgroup_uniform_block(*grp, "material_block", wpd->material_ubo_curr);
}
if (r_transp && transp) {
*r_transp = true;
}
- return grp;
+ return *grp;
}
}
}
@@ -251,7 +251,7 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
Image *ima,
ImageUser *iuser,
eGPUSamplerState sampler,
- bool hair)
+ eWORKBENCH_DataType datatype)
{
GPUTexture *tex = NULL, *tex_tile_data = NULL;
@@ -261,11 +261,11 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
if (ima) {
if (ima->source == IMA_SRC_TILED) {
- tex = GPU_texture_from_blender(ima, iuser, NULL, GL_TEXTURE_2D_ARRAY);
- tex_tile_data = GPU_texture_from_blender(ima, iuser, NULL, GL_TEXTURE_1D_ARRAY);
+ tex = BKE_image_get_gpu_tiles(ima, iuser, NULL);
+ tex_tile_data = BKE_image_get_gpu_tilemap(ima, iuser, NULL);
}
else {
- tex = GPU_texture_from_blender(ima, iuser, NULL, GL_TEXTURE_2D);
+ tex = BKE_image_get_gpu_texture(ima, iuser, NULL);
}
}
@@ -273,9 +273,9 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
tex = wpd->dummy_image_tx;
}
- const bool infront = (ob->dtx & OB_DRAWXRAY) != 0;
+ const bool infront = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
const bool transp = wpd->shading.xray_alpha < 1.0f;
- WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][hair];
+ WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][datatype];
DRWShadingGroup **grp_tex = NULL;
/* A hashmap stores image shgroups to pack all similar drawcalls together. */
diff --git a/source/blender/draw/engines/workbench/workbench_opaque.c b/source/blender/draw/engines/workbench/workbench_opaque.c
index 27d5b71f35c..738f4a67471 100644
--- a/source/blender/draw/engines/workbench/workbench_opaque.c
+++ b/source/blender/draw/engines/workbench/workbench_opaque.c
@@ -59,10 +59,10 @@ void workbench_opaque_engine_init(WORKBENCH_Data *data)
});
}
-void workbench_opaque_cache_init(WORKBENCH_Data *data)
+void workbench_opaque_cache_init(WORKBENCH_Data *vedata)
{
- WORKBENCH_PassList *psl = data->psl;
- WORKBENCH_PrivateData *wpd = data->stl->wpd;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
struct GPUShader *sh;
DRWShadingGroup *grp;
@@ -84,31 +84,31 @@ void workbench_opaque_cache_init(WORKBENCH_Data *data)
pass = psl->opaque_ps;
}
- for (int hair = 0; hair < 2; hair++) {
- wpd->prepass[opaque][infront][hair].material_hash = BLI_ghash_ptr_new(__func__);
+ for (eWORKBENCH_DataType data = 0; data < WORKBENCH_DATATYPE_MAX; data++) {
+ wpd->prepass[opaque][infront][data].material_hash = BLI_ghash_ptr_new(__func__);
- sh = workbench_shader_opaque_get(wpd, hair);
+ sh = workbench_shader_opaque_get(wpd, data);
- wpd->prepass[opaque][infront][hair].common_shgrp = grp = DRW_shgroup_create(sh, pass);
+ wpd->prepass[opaque][infront][data].common_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
- wpd->prepass[opaque][infront][hair].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
+ wpd->prepass[opaque][infront][data].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
- sh = workbench_shader_opaque_image_get(wpd, hair, false);
+ sh = workbench_shader_opaque_image_get(wpd, data, false);
- wpd->prepass[opaque][infront][hair].image_shgrp = grp = DRW_shgroup_create(sh, pass);
+ wpd->prepass[opaque][infront][data].image_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
- sh = workbench_shader_opaque_image_get(wpd, hair, true);
+ sh = workbench_shader_opaque_image_get(wpd, data, true);
- wpd->prepass[opaque][infront][hair].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
+ wpd->prepass[opaque][infront][data].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index ee9960ea0ef..4a6dadc32fd 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -20,8 +20,7 @@
* \ingroup draw_engine
*/
-#ifndef __WORKBENCH_PRIVATE_H__
-#define __WORKBENCH_PRIVATE_H__
+#pragma once
#include "BKE_studiolight.h"
@@ -71,6 +70,14 @@ struct RenderEngine;
struct RenderLayer;
struct rcti;
+typedef enum eWORKBENCH_DataType {
+ WORKBENCH_DATATYPE_MESH = 0,
+ WORKBENCH_DATATYPE_HAIR,
+ WORKBENCH_DATATYPE_POINTCLOUD,
+
+ WORKBENCH_DATATYPE_MAX,
+} eWORKBENCH_DataType;
+
typedef struct WORKBENCH_FramebufferList {
struct GPUFrameBuffer *opaque_fb;
struct GPUFrameBuffer *opaque_infront_fb;
@@ -168,7 +175,6 @@ typedef struct WORKBENCH_UBO_Material {
} WORKBENCH_UBO_Material;
typedef struct WORKBENCH_UBO_World {
- float viewvecs[3][4];
float viewport_size[2], viewport_size_inv[2];
float object_outline_color[4];
float shadow_direction_vs[4];
@@ -293,8 +299,8 @@ typedef struct WORKBENCH_PrivateData {
/** Object IDs buffer for curvature & outline. */
struct GPUTexture *object_id_tx;
- /** Pre-pass information for each draw types [transparent][infront][hair]. */
- WORKBENCH_Prepass prepass[2][2][2];
+ /** Pre-pass information for each draw types [transparent][infront][datatype]. */
+ WORKBENCH_Prepass prepass[2][2][WORKBENCH_DATATYPE_MAX];
/* Materials */
/** Copy of vldata->material_ubo for faster access. */
@@ -393,14 +399,16 @@ void workbench_shadow_cache_init(WORKBENCH_Data *data);
void workbench_shadow_cache_populate(WORKBENCH_Data *data, Object *ob, const bool has_transp_mat);
/* workbench_shader.c */
-GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, bool hair);
-GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd, bool hair, bool tiled);
+GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data);
+GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd,
+ eWORKBENCH_DataType data,
+ bool tiled);
GPUShader *workbench_shader_composite_get(WORKBENCH_PrivateData *wpd);
GPUShader *workbench_shader_merge_infront_get(WORKBENCH_PrivateData *wpd);
-GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, bool hair);
+GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data);
GPUShader *workbench_shader_transparent_image_get(WORKBENCH_PrivateData *wpd,
- bool hair,
+ eWORKBENCH_DataType data,
bool tiled);
GPUShader *workbench_shader_transparent_resolve_get(WORKBENCH_PrivateData *wpd);
@@ -455,7 +463,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
Object *ob,
int mat_nr,
eV3DShadingColorType color_type,
- bool hair,
+ eWORKBENCH_DataType datatype,
bool *r_transp);
DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
Object *ob,
@@ -463,17 +471,20 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
Image *ima,
ImageUser *iuser,
eGPUSamplerState sampler,
- bool hair);
+ eWORKBENCH_DataType datatype);
+
+#define WORKBENCH_OBJECT_DATATYPE(ob) \
+ ((ob->type == OB_POINTCLOUD) ? WORKBENCH_DATATYPE_POINTCLOUD : WORKBENCH_DATATYPE_MESH)
#define workbench_material_setup(wpd, ob, mat_nr, color_type, r_transp) \
- workbench_material_setup_ex(wpd, ob, mat_nr, color_type, false, r_transp)
+ workbench_material_setup_ex(wpd, ob, mat_nr, color_type, WORKBENCH_OBJECT_DATATYPE(ob), r_transp)
#define workbench_image_setup(wpd, ob, mat_nr, ima, iuser, interp) \
- workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, false)
+ workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, WORKBENCH_OBJECT_DATATYPE(ob))
#define workbench_material_hair_setup(wpd, ob, mat_nr, color_type) \
- workbench_material_setup_ex(wpd, ob, mat_nr, color_type, true, 0)
+ workbench_material_setup_ex(wpd, ob, mat_nr, color_type, WORKBENCH_DATATYPE_HAIR, 0)
#define workbench_image_hair_setup(wpd, ob, mat_nr, ima, iuser, interp) \
- workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, true)
+ workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, WORKBENCH_DATATYPE_HAIR)
/* workbench_data.c */
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
@@ -508,5 +519,3 @@ void workbench_render(void *ved,
void workbench_render_update_passes(struct RenderEngine *engine,
struct Scene *scene,
struct ViewLayer *view_layer);
-
-#endif
diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c
index 9e66bcb07f4..77e16327a43 100644
--- a/source/blender/draw/engines/workbench/workbench_render.c
+++ b/source/blender/draw/engines/workbench/workbench_render.c
@@ -212,6 +212,7 @@ void workbench_render(void *ved, RenderEngine *engine, RenderLayer *render_layer
BLI_rcti_size_y(rect),
4,
0,
+ GPU_DATA_FLOAT,
rp->rect);
workbench_render_result_z(render_layer, viewname, rect);
diff --git a/source/blender/draw/engines/workbench/workbench_shader.c b/source/blender/draw/engines/workbench/workbench_shader.c
index 99366779b22..aab3cef00e6 100644
--- a/source/blender/draw/engines/workbench/workbench_shader.c
+++ b/source/blender/draw/engines/workbench/workbench_shader.c
@@ -28,12 +28,16 @@
#include "workbench_engine.h"
#include "workbench_private.h"
+extern char datatoc_common_math_lib_glsl[];
+extern char datatoc_common_math_geom_lib_glsl[];
extern char datatoc_common_hair_lib_glsl[];
+extern char datatoc_common_pointcloud_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_common_smaa_lib_glsl[];
extern char datatoc_workbench_prepass_vert_glsl[];
extern char datatoc_workbench_prepass_hair_vert_glsl[];
+extern char datatoc_workbench_prepass_pointcloud_vert_glsl[];
extern char datatoc_workbench_prepass_frag_glsl[];
extern char datatoc_workbench_effect_cavity_frag_glsl[];
@@ -74,7 +78,6 @@ extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
/* Maximum number of variations. */
#define MAX_LIGHTING 3
#define MAX_COLOR 3
-#define MAX_GEOM 2
enum {
VOLUME_SH_SLICE = 0,
@@ -85,8 +88,9 @@ enum {
#define VOLUME_SH_MAX (1 << (VOLUME_SH_CUBIC + 1))
static struct {
- struct GPUShader *opaque_prepass_sh_cache[GPU_SHADER_CFG_LEN][MAX_GEOM][MAX_COLOR];
- struct GPUShader *transp_prepass_sh_cache[GPU_SHADER_CFG_LEN][MAX_GEOM][MAX_LIGHTING][MAX_COLOR];
+ struct GPUShader *opaque_prepass_sh_cache[GPU_SHADER_CFG_LEN][WORKBENCH_DATATYPE_MAX][MAX_COLOR];
+ struct GPUShader *transp_prepass_sh_cache[GPU_SHADER_CFG_LEN][WORKBENCH_DATATYPE_MAX]
+ [MAX_LIGHTING][MAX_COLOR];
struct GPUShader *opaque_composite_sh[MAX_LIGHTING];
struct GPUShader *oit_resolve_sh;
@@ -117,8 +121,11 @@ void workbench_shader_library_ensure(void)
if (e_data.lib == NULL) {
e_data.lib = DRW_shader_library_create();
/* NOTE: Theses needs to be ordered by dependencies. */
+ DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_pointcloud_lib);
DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib);
DRW_SHADER_LIB_ADD(e_data.lib, workbench_shader_interface_lib);
DRW_SHADER_LIB_ADD(e_data.lib, workbench_common_lib);
@@ -177,15 +184,18 @@ static int workbench_color_index(WORKBENCH_PrivateData *UNUSED(wpd), bool textur
return (textured) ? (tiled ? 2 : 1) : 0;
}
-static GPUShader *workbench_shader_get_ex(
- WORKBENCH_PrivateData *wpd, bool transp, bool hair, bool textured, bool tiled)
+static GPUShader *workbench_shader_get_ex(WORKBENCH_PrivateData *wpd,
+ bool transp,
+ eWORKBENCH_DataType datatype,
+ bool textured,
+ bool tiled)
{
int color = workbench_color_index(wpd, textured, tiled);
int light = wpd->shading.light;
BLI_assert(light < MAX_LIGHTING);
struct GPUShader **shader =
- (transp) ? &e_data.transp_prepass_sh_cache[wpd->sh_cfg][hair][light][color] :
- &e_data.opaque_prepass_sh_cache[wpd->sh_cfg][hair][color];
+ (transp) ? &e_data.transp_prepass_sh_cache[wpd->sh_cfg][datatype][light][color] :
+ &e_data.opaque_prepass_sh_cache[wpd->sh_cfg][datatype][color];
if (*shader == NULL) {
char *defines = workbench_build_defines(wpd, textured, tiled, false, false);
@@ -194,8 +204,11 @@ static GPUShader *workbench_shader_get_ex(
datatoc_workbench_prepass_frag_glsl;
char *frag_src = DRW_shader_library_create_shader_string(e_data.lib, frag_file);
- char *vert_file = hair ? datatoc_workbench_prepass_hair_vert_glsl :
- datatoc_workbench_prepass_vert_glsl;
+ char *vert_file = (datatype == WORKBENCH_DATATYPE_HAIR) ?
+ datatoc_workbench_prepass_hair_vert_glsl :
+ ((datatype == WORKBENCH_DATATYPE_POINTCLOUD) ?
+ datatoc_workbench_prepass_pointcloud_vert_glsl :
+ datatoc_workbench_prepass_vert_glsl);
char *vert_src = DRW_shader_library_create_shader_string(e_data.lib, vert_file);
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[wpd->sh_cfg];
@@ -207,6 +220,10 @@ static GPUShader *workbench_shader_get_ex(
defines,
transp ? "#define TRANSPARENT_MATERIAL\n" :
"#define OPAQUE_MATERIAL\n",
+ (datatype == WORKBENCH_DATATYPE_POINTCLOUD) ?
+ "#define UNIFORM_RESOURCE_ID\n"
+ "#define INSTANCED_ATTR\n" :
+ NULL,
NULL},
});
@@ -217,26 +234,29 @@ static GPUShader *workbench_shader_get_ex(
return *shader;
}
-GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, bool hair)
+GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType datatype)
{
- return workbench_shader_get_ex(wpd, false, hair, false, false);
+ return workbench_shader_get_ex(wpd, false, datatype, false, false);
}
-GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd, bool hair, bool tiled)
+GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd,
+ eWORKBENCH_DataType datatype,
+ bool tiled)
{
- return workbench_shader_get_ex(wpd, false, hair, true, tiled);
+ return workbench_shader_get_ex(wpd, false, datatype, true, tiled);
}
-GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, bool hair)
+GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd,
+ eWORKBENCH_DataType datatype)
{
- return workbench_shader_get_ex(wpd, true, hair, false, false);
+ return workbench_shader_get_ex(wpd, true, datatype, false, false);
}
GPUShader *workbench_shader_transparent_image_get(WORKBENCH_PrivateData *wpd,
- bool hair,
+ eWORKBENCH_DataType datatype,
bool tiled)
{
- return workbench_shader_get_ex(wpd, true, hair, true, tiled);
+ return workbench_shader_get_ex(wpd, true, datatype, true, tiled);
}
GPUShader *workbench_shader_composite_get(WORKBENCH_PrivateData *wpd)
diff --git a/source/blender/draw/engines/workbench/workbench_transparent.c b/source/blender/draw/engines/workbench/workbench_transparent.c
index 1c40a350300..5eff056846c 100644
--- a/source/blender/draw/engines/workbench/workbench_transparent.c
+++ b/source/blender/draw/engines/workbench/workbench_transparent.c
@@ -83,10 +83,10 @@ static void workbench_transparent_lighting_uniforms(WORKBENCH_PrivateData *wpd,
}
}
-void workbench_transparent_cache_init(WORKBENCH_Data *data)
+void workbench_transparent_cache_init(WORKBENCH_Data *vedata)
{
- WORKBENCH_PassList *psl = data->psl;
- WORKBENCH_PrivateData *wpd = data->stl->wpd;
+ WORKBENCH_PassList *psl = vedata->psl;
+ WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
struct GPUShader *sh;
DRWShadingGroup *grp;
@@ -105,30 +105,30 @@ void workbench_transparent_cache_init(WORKBENCH_Data *data)
pass = psl->transp_accum_ps;
}
- for (int hair = 0; hair < 2; hair++) {
- wpd->prepass[transp][infront][hair].material_hash = BLI_ghash_ptr_new(__func__);
+ for (eWORKBENCH_DataType data = 0; data < WORKBENCH_DATATYPE_MAX; data++) {
+ wpd->prepass[transp][infront][data].material_hash = BLI_ghash_ptr_new(__func__);
- sh = workbench_shader_transparent_get(wpd, hair);
+ sh = workbench_shader_transparent_get(wpd, data);
- wpd->prepass[transp][infront][hair].common_shgrp = grp = DRW_shgroup_create(sh, pass);
+ wpd->prepass[transp][infront][data].common_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
workbench_transparent_lighting_uniforms(wpd, grp);
- wpd->prepass[transp][infront][hair].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
+ wpd->prepass[transp][infront][data].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
- sh = workbench_shader_transparent_image_get(wpd, hair, false);
+ sh = workbench_shader_transparent_image_get(wpd, data, false);
- wpd->prepass[transp][infront][hair].image_shgrp = grp = DRW_shgroup_create(sh, pass);
+ wpd->prepass[transp][infront][data].image_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
workbench_transparent_lighting_uniforms(wpd, grp);
- sh = workbench_shader_transparent_image_get(wpd, hair, true);
+ sh = workbench_shader_transparent_image_get(wpd, data, true);
- wpd->prepass[transp][infront][hair].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
+ wpd->prepass[transp][infront][data].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
workbench_transparent_lighting_uniforms(wpd, grp);
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c
index 8e345f8275b..d3c4d51dbd4 100644
--- a/source/blender/draw/engines/workbench/workbench_volume.c
+++ b/source/blender/draw/engines/workbench/workbench_volume.c
@@ -38,8 +38,6 @@
#include "BKE_volume.h"
#include "BKE_volume_render.h"
-#include "GPU_draw.h"
-
void workbench_volume_engine_init(WORKBENCH_Data *vedata)
{
WORKBENCH_TextureList *txl = vedata->txl;
@@ -79,13 +77,10 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata,
wpd->volumes_do = true;
if (fds->use_coba) {
- GPU_create_smoke_coba_field(fmd);
- }
- else if (!(fds->flags & FLUID_DOMAIN_USE_NOISE)) {
- GPU_create_smoke(fmd, 0);
+ DRW_smoke_ensure_coba_field(fmd);
}
- else if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
- GPU_create_smoke(fmd, 1);
+ else {
+ DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE);
}
if ((!fds->use_coba && (fds->tex_density == NULL && fds->tex_color == NULL)) ||
@@ -293,7 +288,7 @@ void workbench_volume_draw_finish(WORKBENCH_Data *vedata)
* all viewport in a redraw at least. */
LISTBASE_FOREACH (LinkData *, link, &wpd->smoke_domains) {
FluidModifierData *fmd = (FluidModifierData *)link->data;
- GPU_free_smoke(fmd);
+ DRW_smoke_free(fmd);
}
BLI_freelistN(&wpd->smoke_domains);
}
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 555043ab408..956bddfb357 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -22,8 +22,7 @@
/* This is the Render Functions used by Realtime engines to draw with OpenGL */
-#ifndef __DRW_RENDER_H__
-#define __DRW_RENDER_H__
+#pragma once
#include "DRW_engine_types.h"
@@ -198,12 +197,28 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo);
} while (0)
/* Shaders */
+
+#ifndef __GPU_MATERIAL_H__
+/* FIXME: Meh avoid including all GPUMaterial. */
+typedef void (*GPUMaterialEvalCallbackFn)(struct GPUMaterial *mat,
+ int options,
+ const char **vert_code,
+ const char **geom_code,
+ const char **frag_lib,
+ const char **defines);
+#endif
+
struct GPUShader *DRW_shader_create(const char *vert,
const char *geom,
const char *frag,
const char *defines);
struct GPUShader *DRW_shader_create_with_lib(
const char *vert, const char *geom, const char *frag, const char *lib, const char *defines);
+struct GPUShader *DRW_shader_create_with_shaderlib(const char *vert,
+ const char *geom,
+ const char *frag,
+ const DRWShaderLibrary *lib,
+ const char *defines);
struct GPUShader *DRW_shader_create_with_transform_feedback(const char *vert,
const char *geom,
const char *defines,
@@ -211,6 +226,9 @@ struct GPUShader *DRW_shader_create_with_transform_feedback(const char *vert,
const char **varying_names,
const int varying_count);
struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines);
+struct GPUShader *DRW_shader_create_fullscreen_with_shaderlib(const char *frag,
+ const DRWShaderLibrary *lib,
+ const char *defines);
struct GPUMaterial *DRW_shader_find_from_world(struct World *wo,
const void *engine_type,
const int options,
@@ -229,7 +247,8 @@ struct GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
const char *geom,
const char *frag_lib,
const char *defines,
- bool deferred);
+ bool deferred,
+ GPUMaterialEvalCallbackFn callback);
struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
struct Material *ma,
struct bNodeTree *ntree,
@@ -240,7 +259,8 @@ struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
const char *geom,
const char *frag_lib,
const char *defines,
- bool deferred);
+ bool deferred,
+ GPUMaterialEvalCallbackFn callback);
void DRW_shader_free(struct GPUShader *shader);
#define DRW_SHADER_FREE_SAFE(shader) \
do { \
@@ -257,7 +277,8 @@ void DRW_shader_library_add_file(DRWShaderLibrary *lib, char *lib_code, const ch
#define DRW_SHADER_LIB_ADD(lib, lib_name) \
DRW_shader_library_add_file(lib, datatoc_##lib_name##_glsl, STRINGIFY(lib_name) ".glsl")
-char *DRW_shader_library_create_shader_string(DRWShaderLibrary *lib, char *shader_code);
+char *DRW_shader_library_create_shader_string(const DRWShaderLibrary *lib,
+ const char *shader_code);
void DRW_shader_library_free(DRWShaderLibrary *lib);
#define DRW_SHADER_LIB_FREE_SAFE(lib) \
@@ -623,7 +644,11 @@ void DRW_render_object_iter(void *vedata,
struct RenderEngine *engine,
struct Depsgraph *depsgraph));
void DRW_render_instance_buffer_finish(void);
-void DRW_render_viewport_size_set(int size[2]);
+void DRW_render_set_time(struct RenderEngine *engine,
+ struct Depsgraph *depsgraph,
+ int frame,
+ float subframe);
+void DRW_render_viewport_size_set(const int size[2]);
void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
struct Depsgraph *depsgraph,
@@ -727,5 +752,3 @@ typedef struct DRWContextState {
} DRWContextState;
const DRWContextState *DRW_context_state_get(void);
-
-#endif /* __DRW_RENDER_H__ */
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 9f30cd85957..b36a177c19f 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -829,7 +829,7 @@ GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob)
case OB_HAIR:
return NULL;
case OB_POINTCLOUD:
- return NULL;
+ return DRW_pointcloud_batch_cache_get_dots(ob);
case OB_VOLUME:
return DRW_cache_volume_face_wireframe_get(ob);
case OB_GPENCIL: {
@@ -880,7 +880,7 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob)
case OB_HAIR:
return NULL;
case OB_POINTCLOUD:
- return NULL;
+ return DRW_cache_pointcloud_surface_get(ob);
case OB_VOLUME:
return NULL;
default:
@@ -958,7 +958,7 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob,
case OB_HAIR:
return NULL;
case OB_POINTCLOUD:
- return NULL;
+ return DRW_cache_pointcloud_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
case OB_VOLUME:
return NULL;
default:
@@ -2909,9 +2909,8 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wire_edge(cu);
- }
+
+ return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob)
@@ -2947,9 +2946,8 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_triangles_with_normals(cu);
- }
+
+ return DRW_curve_batch_cache_get_triangles_with_normals(cu);
}
GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob)
@@ -2961,11 +2959,10 @@ GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- /* TODO */
- UNUSED_VARS(cu);
- return NULL;
- }
+
+ /* TODO */
+ UNUSED_VARS(cu);
+ return NULL;
}
GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob)
@@ -2977,9 +2974,8 @@ GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wireframes_face(cu);
- }
+
+ return DRW_curve_batch_cache_get_wireframes_face(cu);
}
GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold)
@@ -2990,9 +2986,8 @@ GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
- else {
- return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
- }
+
+ return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
}
/* Return list of batches */
@@ -3007,9 +3002,8 @@ GPUBatch **DRW_cache_curve_surface_shaded_get(Object *ob,
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
- else {
- return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
- }
+
+ return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
}
/** \} */
@@ -3061,12 +3055,11 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob)
if (!has_surface) {
return NULL;
}
- else if (mesh_eval != NULL) {
+ if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wire_edge(cu);
- }
+
+ return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_text_surface_get(Object *ob)
@@ -3080,9 +3073,8 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_triangles_with_normals(cu);
- }
+
+ return DRW_curve_batch_cache_get_triangles_with_normals(cu);
}
GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold)
@@ -3096,9 +3088,8 @@ GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
- else {
- return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
- }
+
+ return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
}
GPUBatch *DRW_cache_text_loose_edges_get(Object *ob)
@@ -3112,9 +3103,8 @@ GPUBatch *DRW_cache_text_loose_edges_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wire_edge(cu);
- }
+
+ return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob)
@@ -3128,9 +3118,8 @@ GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wireframes_face(cu);
- }
+
+ return DRW_curve_batch_cache_get_wireframes_face(cu);
}
GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob,
@@ -3146,9 +3135,8 @@ GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob,
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
- else {
- return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
- }
+
+ return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
}
/** \} */
@@ -3166,9 +3154,8 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_triangles_with_normals(cu);
- }
+
+ return DRW_curve_batch_cache_get_triangles_with_normals(cu);
}
GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob)
@@ -3180,9 +3167,8 @@ GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wire_edge(cu);
- }
+
+ return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob)
@@ -3194,9 +3180,8 @@ GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wireframes_face(cu);
- }
+
+ return DRW_curve_batch_cache_get_wireframes_face(cu);
}
GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold)
@@ -3207,9 +3192,8 @@ GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
- else {
- return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
- }
+
+ return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
}
GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob)
@@ -3221,11 +3205,10 @@ GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- /* TODO */
- UNUSED_VARS(cu);
- return NULL;
- }
+
+ /* TODO */
+ UNUSED_VARS(cu);
+ return NULL;
}
/* Return list of batches */
@@ -3240,9 +3223,8 @@ GPUBatch **DRW_cache_surf_surface_shaded_get(Object *ob,
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
- else {
- return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
- }
+
+ return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
}
/** \} */
@@ -3289,9 +3271,16 @@ GPUBatch *DRW_cache_lattice_vert_overlay_get(Object *ob)
GPUBatch *DRW_cache_pointcloud_get_dots(Object *object)
{
+ BLI_assert(object->type == OB_POINTCLOUD);
return DRW_pointcloud_batch_cache_get_dots(object);
}
+GPUBatch *DRW_cache_pointcloud_surface_get(Object *object)
+{
+ BLI_assert(object->type == OB_POINTCLOUD);
+ return DRW_pointcloud_batch_cache_get_surface(object);
+}
+
/* -------------------------------------------------------------------- */
/** \name Volume
* \{ */
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 2f289bf4110..2a7448ce877 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRAW_CACHE_H__
-#define __DRAW_CACHE_H__
+#pragma once
struct GPUBatch;
struct GPUMaterial;
@@ -215,6 +214,7 @@ struct GPUBatch *DRW_cache_hair_edge_detection_get(struct Object *ob, bool *r_is
/* PointCloud */
struct GPUBatch *DRW_cache_pointcloud_get_dots(struct Object *obj);
+struct GPUBatch *DRW_cache_pointcloud_surface_get(struct Object *obj);
/* Volume */
typedef struct DRWVolumeGrid {
@@ -250,5 +250,3 @@ struct GPUBatch *DRW_cache_gpencil_face_wireframe_get(struct Object *ob);
struct bGPDstroke *DRW_cache_gpencil_sbuffer_stroke_data_get(struct Object *ob);
void DRW_cache_gpencil_sbuffer_clear(struct Object *ob);
-
-#endif /* __DRAW_CACHE_H__ */
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 302f9a0d3a8..2653b3127ae 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRAW_CACHE_EXTRACT_H__
-#define __DRAW_CACHE_EXTRACT_H__
+#pragma once
struct TaskGraph;
@@ -60,6 +59,10 @@ typedef struct DRW_MeshCDMask {
* modifiers could remove it. (see T68857) */
uint32_t edit_uv : 1;
} DRW_MeshCDMask;
+/* Keep `DRW_MeshCDMask` struct within an `uint64_t`.
+ * bit-wise and atomic operations are used to compare and update the struct.
+ * See `mesh_cd_layers_type_*` functions. */
+BLI_STATIC_ASSERT(sizeof(DRW_MeshCDMask) <= sizeof(uint64_t), "DRW_MeshCDMask exceeds 64 bits")
typedef enum eMRIterType {
MR_ITER_LOOPTRI = 1 << 0,
@@ -166,8 +169,7 @@ typedef enum DRWBatchFlag {
MBC_WIRE_EDGES = (1 << 23),
MBC_WIRE_LOOPS = (1 << 24),
MBC_WIRE_LOOPS_UVS = (1 << 25),
- MBC_SURF_PER_MAT = (1 << 26),
- MBC_SKIN_ROOTS = (1 << 27),
+ MBC_SKIN_ROOTS = (1 << 26),
} DRWBatchFlag;
#define MBC_EDITUV \
@@ -266,5 +268,3 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
const Scene *scene,
const ToolSettings *ts,
const bool use_hide);
-
-#endif /* __DRAW_CACHE_EXTRACT_H__ */
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 98da668f78f..a1d2a7eeb4a 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -474,10 +474,9 @@ BLI_INLINE const float *bm_vert_co_get(const MeshRenderData *mr, const BMVert *e
if (vert_coords != NULL) {
return vert_coords[BM_elem_index_get(eve)];
}
- else {
- UNUSED_VARS(mr);
- return eve->co;
- }
+
+ UNUSED_VARS(mr);
+ return eve->co;
}
BLI_INLINE const float *bm_vert_no_get(const MeshRenderData *mr, const BMVert *eve)
@@ -486,10 +485,9 @@ BLI_INLINE const float *bm_vert_no_get(const MeshRenderData *mr, const BMVert *e
if (vert_normals != NULL) {
return vert_normals[BM_elem_index_get(eve)];
}
- else {
- UNUSED_VARS(mr);
- return eve->no;
- }
+
+ UNUSED_VARS(mr);
+ return eve->no;
}
BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *efa)
@@ -498,10 +496,9 @@ BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *e
if (poly_normals != NULL) {
return poly_normals[BM_elem_index_get(efa)];
}
- else {
- UNUSED_VARS(mr);
- return efa->no;
- }
+
+ UNUSED_VARS(mr);
+ return efa->no;
}
/** \} */
@@ -890,12 +887,15 @@ static void extract_tris_finish(const MeshRenderData *mr, void *ibo, void *_data
MeshExtract_Tri_Data *data = _data;
GPU_indexbuf_build_in_place(&data->elb, ibo);
/* HACK: Create ibo sub-ranges and assign them to each #GPUBatch. */
+ /* The `surface_per_mat` tests are there when object shading type is set to Wire or Bounds. In
+ * these cases there isn't a surface per material. */
if (mr->use_final_mesh && mr->cache->surface_per_mat && mr->cache->surface_per_mat[0]) {
- BLI_assert(mr->cache->surface_per_mat[0]->elem == ibo);
for (int i = 0; i < mr->mat_len; i++) {
/* Multiply by 3 because these are triangle indices. */
- const int start = data->tri_mat_start[i] * 3;
- const int len = data->tri_mat_end[i] * 3 - data->tri_mat_start[i] * 3;
+ const int mat_start = data->tri_mat_start[i];
+ const int mat_end = data->tri_mat_end[i];
+ const int start = mat_start * 3;
+ const int len = (mat_end - mat_start) * 3;
GPUIndexBuf *sub_ibo = GPU_indexbuf_create_subrange(ibo, start, len);
/* WARNING: We modify the #GPUBatch here! */
GPU_batch_elembuf_set(mr->cache->surface_per_mat[i], sub_ibo, true);
@@ -2534,26 +2534,28 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
}
/* Sculpt Vertex Colors */
- for (int i = 0; i < 8; i++) {
- if (svcol_layers & (1 << i)) {
- char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
- const char *layer_name = CustomData_get_layer_name(cd_vdata, CD_PROP_COLOR, i);
- GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
-
- BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name);
- GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- if (i == CustomData_get_render_layer(cd_vdata, CD_PROP_COLOR)) {
- GPU_vertformat_alias_add(&format, "c");
- }
- if (i == CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR)) {
- GPU_vertformat_alias_add(&format, "ac");
- }
- /* Gather number of auto layers. */
- /* We only do `vcols` that are not overridden by `uvs`. */
- if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, layer_name) == -1) {
- BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
- GPU_vertformat_alias_add(&format, attr_name);
+ if (U.experimental.use_sculpt_vertex_colors) {
+ for (int i = 0; i < 8; i++) {
+ if (svcol_layers & (1 << i)) {
+ char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
+ const char *layer_name = CustomData_get_layer_name(cd_vdata, CD_PROP_COLOR, i);
+ GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
+
+ BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name);
+ GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ if (i == CustomData_get_render_layer(cd_vdata, CD_PROP_COLOR)) {
+ GPU_vertformat_alias_add(&format, "c");
+ }
+ if (i == CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR)) {
+ GPU_vertformat_alias_add(&format, "ac");
+ }
+ /* Gather number of auto layers. */
+ /* We only do `vcols` that are not overridden by `uvs`. */
+ if (CustomData_get_named_layer_index(cd_ldata, CD_MLOOPUV, layer_name) == -1) {
+ BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
+ GPU_vertformat_alias_add(&format, attr_name);
+ }
}
}
}
@@ -2599,7 +2601,7 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
}
}
- if (svcol_layers & (1 << i)) {
+ if (svcol_layers & (1 << i) && U.experimental.use_sculpt_vertex_colors) {
if (mr->extract_type == MR_EXTRACT_BMESH) {
int cd_ofs = CustomData_get_n_offset(cd_vdata, CD_PROP_COLOR, i);
BMIter f_iter;
@@ -2932,7 +2934,7 @@ static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeig
if ((wstate->defgroup_active < 0) && (wstate->defgroup_len > 0)) {
return -2.0f;
}
- else if (dvert == NULL) {
+ if (dvert == NULL) {
return (wstate->alert_mode != OB_DRAW_GROUPUSER_NONE) ? -1.0f : 0.0f;
}
@@ -4291,7 +4293,7 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp)
/* non-manifold edge, yet... */
continue;
}
- else if (*pval != NULL) {
+ if (*pval != NULL) {
const float *f1_no = mr->poly_normals[mp_index];
const float *f2_no = *pval;
angle = angle_normalized_v3v3(f1_no, f2_no);
@@ -4384,10 +4386,6 @@ static void *extract_fdots_pos_init(const MeshRenderData *mr, void *buf)
GPUVertBuf *vbo = buf;
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr->poly_len);
- if (!mr->use_subsurf_fdots) {
- /* Clear so we can accumulate on it. */
- memset(vbo->data, 0x0, mr->poly_len * vbo->format.stride);
- }
return vbo->data;
}
@@ -4396,12 +4394,20 @@ static void extract_fdots_pos_iter_poly_bm(const MeshRenderData *mr,
void *data)
{
float(*center)[3] = data;
- EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr)
+
+ EXTRACT_POLY_FOREACH_BM_BEGIN(f, f_index, params, mr)
{
- float w = 1.0f / (float)l->f->len;
- madd_v3_v3fl(center[BM_elem_index_get(l->f)], bm_vert_co_get(mr, l->v), w);
+ float *co = center[f_index];
+ zero_v3(co);
+
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ add_v3_v3(co, bm_vert_co_get(mr, l_iter->v));
+ } while ((l_iter = l_iter->next) != l_first);
+ mul_v3_fl(co, 1.0f / (float)f->len);
}
- EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l);
+ EXTRACT_POLY_FOREACH_BM_END;
}
static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
@@ -4409,20 +4415,34 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
void *data)
{
float(*center)[3] = (float(*)[3])data;
- EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr)
- {
- const MVert *mv = &mr->mvert[ml->v];
- if (mr->use_subsurf_fdots) {
+ const MVert *mvert = mr->mvert;
+ const MLoop *mloop = mr->mloop;
+
+ if (mr->use_subsurf_fdots) {
+ EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr)
+ {
+ const MVert *mv = &mr->mvert[ml->v];
if (mv->flag & ME_VERT_FACEDOT) {
copy_v3_v3(center[mp_index], mv->co);
}
}
- else {
- float w = 1.0f / (float)mp->totloop;
- madd_v3_v3fl(center[mp_index], mv->co, w);
+ EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END;
+ }
+ else {
+ EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr)
+ {
+ float *co = center[mp_index];
+ zero_v3(co);
+
+ const MLoop *ml = &mloop[mp->loopstart];
+ for (int i = 0; i < mp->totloop; i++, ml++) {
+ const MVert *mv = &mvert[ml->v];
+ add_v3_v3(center[mp_index], mv->co);
+ }
+ mul_v3_fl(co, 1.0f / (float)mp->totloop);
}
+ EXTRACT_POLY_FOREACH_MESH_END;
}
- EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END;
}
static const MeshExtract extract_fdots_pos = {
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 5cf1c24af0b..784e52cfa17 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRAW_CACHE_IMPL_H__
-#define __DRAW_CACHE_IMPL_H__
+#pragma once
struct GPUBatch;
struct GPUIndexBuf;
@@ -144,6 +143,10 @@ int DRW_hair_material_count_get(struct Hair *hair);
int DRW_pointcloud_material_count_get(struct PointCloud *pointcloud);
struct GPUBatch *DRW_pointcloud_batch_cache_get_dots(struct Object *ob);
+struct GPUBatch *DRW_pointcloud_batch_cache_get_surface(struct Object *ob);
+struct GPUBatch **DRW_cache_pointcloud_surface_shaded_get(struct Object *ob,
+ struct GPUMaterial **gpumat_array,
+ uint gpumat_array_len);
/* Volume */
int DRW_volume_material_count_get(struct Volume *volume);
@@ -250,5 +253,3 @@ struct GPUBatch *DRW_particles_batch_cache_get_edit_inner_points(struct Object *
struct GPUBatch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *object,
struct ParticleSystem *psys,
struct PTCacheEdit *edit);
-
-#endif /* __DRAW_CACHE_IMPL_H__ */
diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c
index 53e04fb61ee..0ab14574fa6 100644
--- a/source/blender/draw/intern/draw_cache_impl_gpencil.c
+++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c
@@ -135,9 +135,8 @@ static GpencilBatchCache *gpencil_batch_cache_get(Object *ob, int cfra)
gpencil_batch_cache_clear(cache);
return gpencil_batch_cache_init(ob, cfra);
}
- else {
- return cache;
- }
+
+ return cache;
}
void DRW_gpencil_batch_cache_dirty_tag(bGPdata *gpd)
@@ -150,7 +149,6 @@ void DRW_gpencil_batch_cache_free(bGPdata *gpd)
gpencil_batch_cache_clear(gpd->runtime.gpencil_cache);
MEM_SAFE_FREE(gpd->runtime.gpencil_cache);
gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
- return;
}
/** \} */
@@ -273,7 +271,7 @@ static void gpencil_buffer_add_point(gpStrokeVert *verts,
int v,
bool is_endpoint)
{
- /* Note: we use the sign of stength and thickness to pass cap flag. */
+ /* Note: we use the sign of strength and thickness to pass cap flag. */
const bool round_cap0 = (gps->caps[0] == GP_STROKE_CAP_ROUND);
const bool round_cap1 = (gps->caps[1] == GP_STROKE_CAP_ROUND);
gpStrokeVert *vert = &verts[v];
diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c
index 66a67d6b8fe..0f80b5159a7 100644
--- a/source/blender/draw/intern/draw_cache_impl_lattice.c
+++ b/source/blender/draw/intern/draw_cache_impl_lattice.c
@@ -83,10 +83,9 @@ static int lattice_render_verts_len_get(Lattice *lt)
if ((lt->flag & LT_OUTSIDE) == 0) {
return vert_len_calc(u, v, w);
}
- else {
- /* TODO remove internal coords */
- return vert_len_calc(u, v, w);
- }
+
+ /* TODO remove internal coords */
+ return vert_len_calc(u, v, w);
}
static int lattice_render_edges_len_get(Lattice *lt)
@@ -102,10 +101,9 @@ static int lattice_render_edges_len_get(Lattice *lt)
if ((lt->flag & LT_OUTSIDE) == 0) {
return edge_len_calc(u, v, w);
}
- else {
- /* TODO remove internal coords */
- return edge_len_calc(u, v, w);
- }
+
+ /* TODO remove internal coords */
+ return edge_len_calc(u, v, w);
}
/* ---------------------------------------------------------------------- */
@@ -252,12 +250,11 @@ static bool lattice_batch_cache_valid(Lattice *lt)
if (cache->is_dirty) {
return false;
}
- else {
- if ((cache->dims.u_len != lt->pntsu) || (cache->dims.v_len != lt->pntsv) ||
- (cache->dims.w_len != lt->pntsw) ||
- ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) {
- return false;
- }
+
+ if ((cache->dims.u_len != lt->pntsu) || (cache->dims.v_len != lt->pntsv) ||
+ (cache->dims.w_len != lt->pntsw) ||
+ ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) {
+ return false;
}
return true;
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index ea1717f0684..d6faeb16583 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -74,22 +74,30 @@ static void mesh_batch_cache_clear(Mesh *me);
/* Return true is all layers in _b_ are inside _a_. */
BLI_INLINE bool mesh_cd_layers_type_overlap(DRW_MeshCDMask a, DRW_MeshCDMask b)
{
- return (*((uint32_t *)&a) & *((uint32_t *)&b)) == *((uint32_t *)&b);
+ return (*((uint64_t *)&a) & *((uint64_t *)&b)) == *((uint64_t *)&b);
}
BLI_INLINE bool mesh_cd_layers_type_equal(DRW_MeshCDMask a, DRW_MeshCDMask b)
{
- return *((uint32_t *)&a) == *((uint32_t *)&b);
+ return *((uint64_t *)&a) == *((uint64_t *)&b);
}
BLI_INLINE void mesh_cd_layers_type_merge(DRW_MeshCDMask *a, DRW_MeshCDMask b)
{
- atomic_fetch_and_or_uint32((uint32_t *)a, *(uint32_t *)&b);
+ uint32_t *a_p = (uint32_t *)a;
+ uint32_t *b_p = (uint32_t *)&b;
+ atomic_fetch_and_or_uint32(a_p, *b_p);
+ atomic_fetch_and_or_uint32(a_p + 1, *(b_p + 1));
}
BLI_INLINE void mesh_cd_layers_type_clear(DRW_MeshCDMask *a)
{
- *((uint32_t *)a) = 0;
+ *((uint64_t *)a) = 0;
+}
+
+BLI_INLINE const Mesh *editmesh_final_or_this(const Mesh *me)
+{
+ return (me->edit_mesh && me->edit_mesh->mesh_eval_final) ? me->edit_mesh->mesh_eval_final : me;
}
static void mesh_cd_calc_edit_uv_layer(const Mesh *UNUSED(me), DRW_MeshCDMask *cd_used)
@@ -129,7 +137,7 @@ BLI_INLINE const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *me)
static void mesh_cd_calc_active_uv_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
{
- const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
+ const Mesh *me_final = editmesh_final_or_this(me);
const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
if (layer != -1) {
@@ -139,7 +147,7 @@ static void mesh_cd_calc_active_uv_layer(const Mesh *me, DRW_MeshCDMask *cd_used
static void mesh_cd_calc_active_mask_uv_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
{
- const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
+ const Mesh *me_final = editmesh_final_or_this(me);
const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
int layer = CustomData_get_stencil_layer(cd_ldata, CD_MLOOPUV);
if (layer != -1) {
@@ -149,7 +157,7 @@ static void mesh_cd_calc_active_mask_uv_layer(const Mesh *me, DRW_MeshCDMask *cd
static void mesh_cd_calc_active_vcol_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
{
- const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
+ const Mesh *me_final = editmesh_final_or_this(me);
const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final);
int layer = CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR);
@@ -160,7 +168,7 @@ static void mesh_cd_calc_active_vcol_layer(const Mesh *me, DRW_MeshCDMask *cd_us
static void mesh_cd_calc_active_mloopcol_layer(const Mesh *me, DRW_MeshCDMask *cd_used)
{
- const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
+ const Mesh *me_final = editmesh_final_or_this(me);
const CustomData *cd_ldata = &me_final->ldata;
int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
@@ -173,7 +181,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
struct GPUMaterial **gpumat_array,
int gpumat_array_len)
{
- const Mesh *me_final = (me->edit_mesh) ? me->edit_mesh->mesh_eval_final : me;
+ const Mesh *me_final = editmesh_final_or_this(me);
const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final);
@@ -200,14 +208,17 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
type = CD_MTFACE;
if (layer == -1) {
- layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name);
- type = CD_MCOL;
+ if (U.experimental.use_sculpt_vertex_colors) {
+ layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
+ type = CD_PROP_COLOR;
+ }
}
if (layer == -1) {
- layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name);
- type = CD_PROP_COLOR;
+ layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name);
+ type = CD_MCOL;
}
+
#if 0 /* Tangents are always from UV's - this will never happen. */
if (layer == -1) {
layer = CustomData_get_named_layer(cd_ldata, CD_TANGENT, name);
@@ -257,13 +268,26 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
}
case CD_PROP_COLOR: {
/* Sculpt Vertex Colors */
+ bool use_mloop_cols = false;
if (layer == -1) {
layer = (name[0] != '\0') ?
CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name) :
CustomData_get_render_layer(cd_vdata, CD_PROP_COLOR);
+ /* Fallback to Vertex Color data */
+ if (layer == -1) {
+ layer = (name[0] != '\0') ?
+ CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name) :
+ CustomData_get_render_layer(cd_ldata, CD_MLOOPCOL);
+ use_mloop_cols = true;
+ }
}
if (layer != -1) {
- cd_used.sculpt_vcol |= (1 << layer);
+ if (use_mloop_cols) {
+ cd_used.vcol |= (1 << layer);
+ }
+ else {
+ cd_used.sculpt_vcol |= (1 << layer);
+ }
}
break;
}
@@ -508,14 +532,26 @@ static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache,
}
}
-static void mesh_batch_cache_discard_shaded_batches(MeshBatchCache *cache)
+static void mesh_batch_cache_request_surface_batches(MeshBatchCache *cache)
{
+ mesh_batch_cache_add_request(cache, MBC_SURFACE);
+ DRW_batch_request(&cache->batch.surface);
+ if (cache->surface_per_mat) {
+ for (int i = 0; i < cache->mat_len; i++) {
+ DRW_batch_request(&cache->surface_per_mat[i]);
+ }
+ }
+}
+
+static void mesh_batch_cache_discard_surface_batches(MeshBatchCache *cache)
+{
+ GPU_BATCH_DISCARD_SAFE(cache->batch.surface);
if (cache->surface_per_mat) {
for (int i = 0; i < cache->mat_len; i++) {
GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]);
}
}
- cache->batch_ready &= ~MBC_SURF_PER_MAT;
+ cache->batch_ready &= ~MBC_SURFACE;
}
static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
@@ -527,7 +563,7 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.vcol);
GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.orco);
}
- mesh_batch_cache_discard_shaded_batches(cache);
+ mesh_batch_cache_discard_surface_batches(cache);
mesh_cd_layers_type_clear(&cache->cd_used);
MEM_SAFE_FREE(cache->surface_per_mat);
@@ -567,10 +603,7 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
cache->cd_used.edit_uv = 0;
/* Discard other batches that uses vbo.uv */
- mesh_batch_cache_discard_shaded_batches(cache);
-
- GPU_BATCH_DISCARD_SAFE(cache->batch.surface);
- cache->batch_ready &= ~MBC_SURFACE;
+ mesh_batch_cache_discard_surface_batches(cache);
}
static void mesh_batch_cache_discard_uvedit_select(MeshBatchCache *cache)
@@ -632,12 +665,8 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
GPU_BATCH_DISCARD_SAFE(cache->batch.surface);
GPU_BATCH_DISCARD_SAFE(cache->batch.wire_loops);
GPU_BATCH_DISCARD_SAFE(cache->batch.wire_edges);
- if (cache->surface_per_mat) {
- for (int i = 0; i < cache->mat_len; i++) {
- GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]);
- }
- }
- cache->batch_ready &= ~(MBC_SURFACE | MBC_WIRE_EDGES | MBC_WIRE_LOOPS | MBC_SURF_PER_MAT);
+ mesh_batch_cache_discard_surface_batches(cache);
+ cache->batch_ready &= ~(MBC_SURFACE | MBC_WIRE_EDGES | MBC_WIRE_LOOPS);
break;
case BKE_MESH_BATCH_DIRTY_ALL:
cache->is_dirty = true;
@@ -763,8 +792,8 @@ GPUBatch *DRW_mesh_batch_cache_get_all_edges(Mesh *me)
GPUBatch *DRW_mesh_batch_cache_get_surface(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
- mesh_batch_cache_add_request(cache, MBC_SURFACE);
- return DRW_batch_request(&cache->batch.surface);
+ mesh_batch_cache_request_surface_batches(cache);
+ return cache->batch.surface;
}
GPUBatch *DRW_mesh_batch_cache_get_loose_edges(Mesh *me)
@@ -774,9 +803,8 @@ GPUBatch *DRW_mesh_batch_cache_get_loose_edges(Mesh *me)
if (cache->no_loose_wire) {
return NULL;
}
- else {
- return DRW_batch_request(&cache->batch.loose_edges);
- }
+
+ return DRW_batch_request(&cache->batch.loose_edges);
}
GPUBatch *DRW_mesh_batch_cache_get_surface_weights(Mesh *me)
@@ -822,23 +850,15 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me,
BLI_assert(gpumat_array_len == cache->mat_len);
mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed);
-
- mesh_batch_cache_add_request(cache, MBC_SURF_PER_MAT);
-
- for (int i = 0; i < cache->mat_len; i++) {
- DRW_batch_request(&cache->surface_per_mat[i]);
- }
+ mesh_batch_cache_request_surface_batches(cache);
return cache->surface_per_mat;
}
GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
- mesh_batch_cache_add_request(cache, MBC_SURF_PER_MAT);
texpaint_request_active_uv(cache, me);
- for (int i = 0; i < cache->mat_len; i++) {
- DRW_batch_request(&cache->surface_per_mat[i]);
- }
+ mesh_batch_cache_request_surface_batches(cache);
return cache->surface_per_mat;
}
@@ -846,24 +866,24 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_uv(cache, me);
- mesh_batch_cache_add_request(cache, MBC_SURFACE);
- return DRW_batch_request(&cache->batch.surface);
+ mesh_batch_cache_request_surface_batches(cache);
+ return cache->batch.surface;
}
GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
texpaint_request_active_vcol(cache, me);
- mesh_batch_cache_add_request(cache, MBC_SURFACE);
- return DRW_batch_request(&cache->batch.surface);
+ mesh_batch_cache_request_surface_batches(cache);
+ return cache->batch.surface;
}
GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
sculpt_request_active_vcol(cache, me);
- mesh_batch_cache_add_request(cache, MBC_SURFACE);
- return DRW_batch_request(&cache->batch.surface);
+ mesh_batch_cache_request_surface_batches(cache);
+ return cache->batch.surface;
}
int DRW_mesh_material_count_get(Mesh *me)
@@ -881,8 +901,7 @@ GPUVertBuf *DRW_mesh_batch_cache_pos_vertbuf_get(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
/* Request surface to trigger the vbo filling. Otherwise it may do nothing. */
- mesh_batch_cache_add_request(cache, MBC_SURFACE);
- DRW_batch_request(&cache->batch.surface);
+ mesh_batch_cache_request_surface_batches(cache);
DRW_vbo_request(NULL, &cache->final.vbo.pos_nor);
return cache->final.vbo.pos_nor;
@@ -1103,6 +1122,40 @@ void DRW_mesh_batch_cache_free_old(Mesh *me, int ctime)
mesh_cd_layers_type_clear(&cache->cd_used_over_time);
}
+#ifdef DEBUG
+/* Sanity check function to test if all requested batches are available. */
+static void drw_mesh_batch_cache_check_available(struct TaskGraph *task_graph, Mesh *me)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+ /* Make sure all requested batches have been setup. */
+ /* Note: The next line creates a different scheduling than during release builds what can lead to
+ * some issues (See T77867 where we needed to disable this function in order to debug what was
+ * happening in release builds). */
+ BLI_task_graph_work_and_wait(task_graph);
+ for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); i++) {
+ BLI_assert(!DRW_batch_requested(((GPUBatch **)&cache->batch)[i], 0));
+ }
+ for (int i = 0; i < sizeof(cache->final.vbo) / sizeof(void *); i++) {
+ BLI_assert(!DRW_vbo_requested(((GPUVertBuf **)&cache->final.vbo)[i]));
+ }
+ for (int i = 0; i < sizeof(cache->final.ibo) / sizeof(void *); i++) {
+ BLI_assert(!DRW_ibo_requested(((GPUIndexBuf **)&cache->final.ibo)[i]));
+ }
+ for (int i = 0; i < sizeof(cache->cage.vbo) / sizeof(void *); i++) {
+ BLI_assert(!DRW_vbo_requested(((GPUVertBuf **)&cache->cage.vbo)[i]));
+ }
+ for (int i = 0; i < sizeof(cache->cage.ibo) / sizeof(void *); i++) {
+ BLI_assert(!DRW_ibo_requested(((GPUIndexBuf **)&cache->cage.ibo)[i]));
+ }
+ for (int i = 0; i < sizeof(cache->uv_cage.vbo) / sizeof(void *); i++) {
+ BLI_assert(!DRW_vbo_requested(((GPUVertBuf **)&cache->uv_cage.vbo)[i]));
+ }
+ for (int i = 0; i < sizeof(cache->uv_cage.ibo) / sizeof(void *); i++) {
+ BLI_assert(!DRW_ibo_requested(((GPUIndexBuf **)&cache->uv_cage.ibo)[i]));
+ }
+}
+#endif
+
/* Can be called for any surface type. Mesh *me is the final mesh. */
void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
Object *ob,
@@ -1123,10 +1176,9 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
/* Early out */
if (cache->batch_requested == 0) {
#ifdef DEBUG
- goto check;
-#else
- return;
+ drw_mesh_batch_cache_check_available(task_graph, me);
#endif
+ return;
}
/* Sanity check. */
@@ -1151,30 +1203,8 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
}
}
- /* HACK: if MBC_SURF_PER_MAT is requested and ibo.tris is already available, it won't have it's
- * index ranges initialized. So discard ibo.tris in order to recreate it.
- * This needs to happen before saved_elem_ranges is populated. */
- if ((batch_requested & MBC_SURF_PER_MAT) != 0 && (cache->batch_ready & MBC_SURF_PER_MAT) == 0) {
- FOREACH_MESH_BUFFER_CACHE (cache, mbuffercache) {
- GPU_INDEXBUF_DISCARD_SAFE(mbuffercache->ibo.tris);
- }
- /* Clear all batches that reference ibo.tris. */
- GPU_BATCH_CLEAR_SAFE(cache->batch.surface);
- GPU_BATCH_CLEAR_SAFE(cache->batch.surface_weights);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edit_mesh_analysis);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edit_triangles);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edit_lnor);
- GPU_BATCH_CLEAR_SAFE(cache->batch.edit_selection_faces);
- for (int i = 0; i < cache->mat_len; i++) {
- GPU_BATCH_CLEAR_SAFE(cache->surface_per_mat[i]);
- }
-
- cache->batch_ready &= ~(MBC_SURFACE | MBC_SURFACE_WEIGHTS | MBC_EDIT_MESH_ANALYSIS |
- MBC_EDIT_TRIANGLES | MBC_EDIT_LNOR | MBC_EDIT_SELECTION_FACES);
- }
-
if (batch_requested &
- (MBC_SURFACE | MBC_SURF_PER_MAT | MBC_WIRE_LOOPS_UVS | MBC_EDITUV_FACES_STRETCH_AREA |
+ (MBC_SURFACE | MBC_WIRE_LOOPS_UVS | MBC_EDITUV_FACES_STRETCH_AREA |
MBC_EDITUV_FACES_STRETCH_ANGLE | MBC_EDITUV_FACES | MBC_EDITUV_EDGES | MBC_EDITUV_VERTS)) {
/* Modifiers will only generate an orco layer if the mesh is deformed. */
if (cache->cd_needed.orco != 0) {
@@ -1227,7 +1257,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
GPU_BATCH_CLEAR_SAFE(cache->surface_per_mat[i]);
}
GPU_BATCH_CLEAR_SAFE(cache->batch.surface);
- cache->batch_ready &= ~(MBC_SURFACE | MBC_SURF_PER_MAT);
+ cache->batch_ready &= ~(MBC_SURFACE);
mesh_cd_layers_type_merge(&cache->cd_used, cache->cd_needed);
}
@@ -1243,9 +1273,11 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
FOREACH_MESH_BUFFER_CACHE (cache, mbuffercache) {
GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.edituv_data);
GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.fdots_uv);
+ GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.fdots_edituv_data);
GPU_INDEXBUF_DISCARD_SAFE(mbuffercache->ibo.edituv_tris);
GPU_INDEXBUF_DISCARD_SAFE(mbuffercache->ibo.edituv_lines);
GPU_INDEXBUF_DISCARD_SAFE(mbuffercache->ibo.edituv_points);
+ GPU_INDEXBUF_DISCARD_SAFE(mbuffercache->ibo.edituv_fdots);
}
/* We only clear the batches as they may already have been
* referenced. */
@@ -1263,10 +1295,9 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
/* Second chance to early out */
if ((batch_requested & ~cache->batch_ready) == 0) {
#ifdef DEBUG
- goto check;
-#else
- return;
+ drw_mesh_batch_cache_check_available(task_graph, me);
#endif
+ return;
}
cache->batch_ready |= batch_requested;
@@ -1518,32 +1549,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
ts,
use_hide);
#ifdef DEBUG
-check:
- /* Make sure all requested batches have been setup. */
- /* TODO(jbakker): we should move this to the draw_manager but that needs refactoring and
- * additional looping.*/
- BLI_task_graph_work_and_wait(task_graph);
- for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); i++) {
- BLI_assert(!DRW_batch_requested(((GPUBatch **)&cache->batch)[i], 0));
- }
- for (int i = 0; i < sizeof(cache->final.vbo) / sizeof(void *); i++) {
- BLI_assert(!DRW_vbo_requested(((GPUVertBuf **)&cache->final.vbo)[i]));
- }
- for (int i = 0; i < sizeof(cache->final.ibo) / sizeof(void *); i++) {
- BLI_assert(!DRW_ibo_requested(((GPUIndexBuf **)&cache->final.ibo)[i]));
- }
- for (int i = 0; i < sizeof(cache->cage.vbo) / sizeof(void *); i++) {
- BLI_assert(!DRW_vbo_requested(((GPUVertBuf **)&cache->cage.vbo)[i]));
- }
- for (int i = 0; i < sizeof(cache->cage.ibo) / sizeof(void *); i++) {
- BLI_assert(!DRW_ibo_requested(((GPUIndexBuf **)&cache->cage.ibo)[i]));
- }
- for (int i = 0; i < sizeof(cache->uv_cage.vbo) / sizeof(void *); i++) {
- BLI_assert(!DRW_vbo_requested(((GPUVertBuf **)&cache->uv_cage.vbo)[i]));
- }
- for (int i = 0; i < sizeof(cache->uv_cage.ibo) / sizeof(void *); i++) {
- BLI_assert(!DRW_ibo_requested(((GPUIndexBuf **)&cache->uv_cage.ibo)[i]));
- }
+ drw_mesh_batch_cache_check_available(task_graph, me);
#endif
}
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index 331a1f80bec..3ecdbff1e96 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -128,9 +128,8 @@ static bool particle_batch_cache_valid(ParticleSystem *psys)
if (cache->is_dirty == false) {
return true;
}
- else {
- return false;
- }
+
+ return false;
return true;
}
@@ -647,14 +646,13 @@ static float particle_key_weight(const ParticleData *particle, int strand, float
if (t == 1.0) {
return hkeys[part->totkey - 1].weight;
}
- else {
- float interp = t / edit_key_seg_t;
- int index = (int)interp;
- interp -= floorf(interp); /* Time between 2 edit key */
- float s1 = hkeys[index].weight;
- float s2 = hkeys[index + 1].weight;
- return s1 + interp * (s2 - s1);
- }
+
+ float interp = t / edit_key_seg_t;
+ int index = (int)interp;
+ interp -= floorf(interp); /* Time between 2 edit key */
+ float s1 = hkeys[index].weight;
+ float s2 = hkeys[index + 1].weight;
+ return s1 + interp * (s2 - s1);
}
static int particle_batch_cache_fill_segments_edit(
diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.c b/source/blender/draw/intern/draw_cache_impl_pointcloud.c
index 53939b35285..06cedb9f72c 100644
--- a/source/blender/draw/intern/draw_cache_impl_pointcloud.c
+++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.c
@@ -28,6 +28,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_math_base.h"
+#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "DNA_object_types.h"
@@ -45,11 +46,18 @@ static void pointcloud_batch_cache_clear(PointCloud *pointcloud);
/* PointCloud GPUBatch Cache */
typedef struct PointCloudBatchCache {
- GPUVertBuf *pos;
- GPUBatch *batch;
+ GPUVertBuf *pos; /* Position and radius. */
+ GPUVertBuf *geom; /* Instanced geometry for each point in the cloud (small sphere). */
+ GPUIndexBuf *geom_indices;
+
+ GPUBatch *dots;
+ GPUBatch *surface;
+ GPUBatch **surface_per_mat;
/* settings to determine if cache is invalid */
bool is_dirty;
+
+ int mat_len;
} PointCloudBatchCache;
/* GPUBatch cache management. */
@@ -57,7 +65,14 @@ typedef struct PointCloudBatchCache {
static bool pointcloud_batch_cache_valid(PointCloud *pointcloud)
{
PointCloudBatchCache *cache = pointcloud->batch_cache;
- return (cache && cache->is_dirty == false);
+
+ if (cache == NULL) {
+ return false;
+ }
+ if (cache->mat_len != DRW_pointcloud_material_count_get(pointcloud)) {
+ return false;
+ }
+ return cache->is_dirty == false;
}
static void pointcloud_batch_cache_init(PointCloud *pointcloud)
@@ -71,6 +86,10 @@ static void pointcloud_batch_cache_init(PointCloud *pointcloud)
memset(cache, 0, sizeof(*cache));
}
+ cache->mat_len = DRW_pointcloud_material_count_get(pointcloud);
+ cache->surface_per_mat = MEM_callocN(sizeof(GPUBatch *) * cache->mat_len,
+ "pointcloud suface_per_mat");
+
cache->is_dirty = false;
}
@@ -109,8 +128,18 @@ static void pointcloud_batch_cache_clear(PointCloud *pointcloud)
return;
}
- GPU_BATCH_DISCARD_SAFE(cache->batch);
+ GPU_BATCH_DISCARD_SAFE(cache->dots);
+ GPU_BATCH_DISCARD_SAFE(cache->surface);
GPU_VERTBUF_DISCARD_SAFE(cache->pos);
+ GPU_VERTBUF_DISCARD_SAFE(cache->geom);
+ GPU_INDEXBUF_DISCARD_SAFE(cache->geom_indices);
+
+ if (cache->surface_per_mat) {
+ for (int i = 0; i < cache->mat_len; i++) {
+ GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]);
+ }
+ }
+ MEM_SAFE_FREE(cache->surface_per_mat);
}
void DRW_pointcloud_batch_cache_free(PointCloud *pointcloud)
@@ -126,35 +155,84 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache *
}
PointCloud *pointcloud = ob->data;
+ const bool has_radius = pointcloud->radius != NULL;
static GPUVertFormat format = {0};
- static uint pos_id;
- static uint radius_id;
+ static GPUVertFormat format_no_radius = {0};
+ static uint pos;
if (format.attr_len == 0) {
/* initialize vertex format */
- pos_id = GPU_vertformat_attr_add(&format, "pointcloud_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- radius_id = GPU_vertformat_attr_add(
- &format, "pointcloud_radius", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ /* From the opengl wiki:
+ * Note that size does not have to exactly match the size used by the vertex shader. If the
+ * vertex shader has fewer components than the attribute provides, then the extras are ignored.
+ * If the vertex shader has more components than the array provides, the extras are given
+ * values from the vector (0, 0, 0, 1) for the missing XYZW components.
+ */
+ pos = GPU_vertformat_attr_add(&format_no_radius, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
}
- GPU_VERTBUF_DISCARD_SAFE(cache->pos);
- cache->pos = GPU_vertbuf_create_with_format(&format);
+ cache->pos = GPU_vertbuf_create_with_format(has_radius ? &format : &format_no_radius);
GPU_vertbuf_data_alloc(cache->pos, pointcloud->totpoint);
- GPU_vertbuf_attr_fill(cache->pos, pos_id, pointcloud->co);
- if (pointcloud->radius) {
- GPU_vertbuf_attr_fill(cache->pos, radius_id, pointcloud->radius);
- }
- else if (pointcloud->totpoint) {
- /* TODO: optimize for constant radius by not including in vertex buffer at all? */
- float *radius = MEM_malloc_arrayN(pointcloud->totpoint, sizeof(float), __func__);
+ if (has_radius) {
+ float(*vbo_data)[4] = (float(*)[4])cache->pos->data;
for (int i = 0; i < pointcloud->totpoint; i++) {
- /* TODO: add default radius to PointCloud data structure. */
- radius[i] = 0.01f;
+ copy_v3_v3(vbo_data[i], pointcloud->co[i]);
+ /* TODO(fclem) remove multiplication here. Here only for keeping the size correct for now. */
+ vbo_data[i][3] = pointcloud->radius[i] * 100.0f;
}
- GPU_vertbuf_attr_fill(cache->pos, radius_id, radius);
- MEM_freeN(radius);
}
+ else {
+ GPU_vertbuf_attr_fill(cache->pos, pos, pointcloud->co);
+ }
+}
+
+static const float half_octahedron_normals[5][3] = {
+ {0.0f, 0.0f, 1.0f},
+ {1.0f, 0.0f, 0.0f},
+ {0.0f, 1.0f, 0.0f},
+ {-1.0f, 0.0f, 0.0f},
+ {0.0f, -1.0f, 0.0f},
+};
+
+static const uint half_octahedron_tris[4][3] = {
+ {0, 1, 2},
+ {0, 2, 3},
+ {0, 3, 4},
+ {0, 4, 1},
+};
+
+static void pointcloud_batch_cache_ensure_geom(Object *UNUSED(ob), PointCloudBatchCache *cache)
+{
+ if (cache->geom != NULL) {
+ return;
+ }
+
+ static GPUVertFormat format = {0};
+ static uint pos;
+ if (format.attr_len == 0) {
+ /* initialize vertex format */
+ pos = GPU_vertformat_attr_add(&format, "pos_inst", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ GPU_vertformat_alias_add(&format, "nor");
+ }
+
+ cache->geom = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(cache->geom, ARRAY_SIZE(half_octahedron_normals));
+
+ GPU_vertbuf_attr_fill(cache->geom, pos, half_octahedron_normals);
+
+ GPUIndexBufBuilder builder;
+ GPU_indexbuf_init(&builder,
+ GPU_PRIM_TRIS,
+ ARRAY_SIZE(half_octahedron_tris),
+ ARRAY_SIZE(half_octahedron_normals));
+
+ for (int i = 0; i < ARRAY_SIZE(half_octahedron_tris); i++) {
+ GPU_indexbuf_add_tri_verts(&builder, UNPACK3(half_octahedron_tris[i]));
+ }
+
+ cache->geom_indices = GPU_indexbuf_build(&builder);
}
GPUBatch *DRW_pointcloud_batch_cache_get_dots(Object *ob)
@@ -162,12 +240,48 @@ GPUBatch *DRW_pointcloud_batch_cache_get_dots(Object *ob)
PointCloud *pointcloud = ob->data;
PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
- if (cache->batch == NULL) {
+ if (cache->dots == NULL) {
pointcloud_batch_cache_ensure_pos(ob, cache);
- cache->batch = GPU_batch_create(GPU_PRIM_POINTS, cache->pos, NULL);
+ cache->dots = GPU_batch_create(GPU_PRIM_POINTS, cache->pos, NULL);
+ }
+
+ return cache->dots;
+}
+
+GPUBatch *DRW_pointcloud_batch_cache_get_surface(Object *ob)
+{
+ PointCloud *pointcloud = ob->data;
+ PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
+
+ if (cache->surface == NULL) {
+ pointcloud_batch_cache_ensure_pos(ob, cache);
+ pointcloud_batch_cache_ensure_geom(ob, cache);
+
+ cache->surface = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices);
+ GPU_batch_instbuf_add_ex(cache->surface, cache->pos, false);
+ }
+
+ return cache->surface;
+}
+
+GPUBatch **DRW_cache_pointcloud_surface_shaded_get(Object *ob,
+ struct GPUMaterial **UNUSED(gpumat_array),
+ uint gpumat_array_len)
+{
+ PointCloud *pointcloud = ob->data;
+ PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
+ BLI_assert(cache->mat_len == gpumat_array_len);
+ UNUSED_VARS(gpumat_array_len);
+
+ if (cache->surface_per_mat[0] == NULL) {
+ pointcloud_batch_cache_ensure_pos(ob, cache);
+ pointcloud_batch_cache_ensure_geom(ob, cache);
+
+ cache->surface_per_mat[0] = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices);
+ GPU_batch_instbuf_add_ex(cache->surface_per_mat[0], cache->pos, false);
}
- return cache->batch;
+ return cache->surface_per_mat;
}
int DRW_pointcloud_material_count_get(PointCloud *pointcloud)
diff --git a/source/blender/draw/intern/draw_cache_impl_volume.c b/source/blender/draw/intern/draw_cache_impl_volume.c
index 9c2c075ab4f..e07f5b33d58 100644
--- a/source/blender/draw/intern/draw_cache_impl_volume.c
+++ b/source/blender/draw/intern/draw_cache_impl_volume.c
@@ -266,7 +266,7 @@ static DRWVolumeGrid *volume_grid_cache_get(Volume *volume,
NULL);
GPU_texture_bind(cache_grid->texture, 0);
- GPU_texture_swizzle_channel_auto(cache_grid->texture, channels);
+ GPU_texture_swizzle_set(cache_grid->texture, (channels == 3) ? "rgb1" : "rrr1");
GPU_texture_wrap_mode(cache_grid->texture, false, false);
GPU_texture_unbind(cache_grid->texture);
diff --git a/source/blender/draw/intern/draw_cache_inline.h b/source/blender/draw/intern/draw_cache_inline.h
index 67f44b5fb0c..bb3a908c6c5 100644
--- a/source/blender/draw/intern/draw_cache_inline.h
+++ b/source/blender/draw/intern/draw_cache_inline.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRAW_CACHE_INLINE_H__
-#define __DRAW_CACHE_INLINE_H__
+#pragma once
#include "GPU_batch.h"
#include "MEM_guardedalloc.h"
@@ -110,5 +109,3 @@ BLI_INLINE bool DRW_vbo_requested(GPUVertBuf *vbo)
{
return (vbo != NULL && vbo->format.attr_len == 0);
}
-
-#endif /* __DRAW_CACHE_INLINE_H__ */
diff --git a/source/blender/draw/intern/draw_color_management.h b/source/blender/draw/intern/draw_color_management.h
index 9d83eccdce9..3150ec72138 100644
--- a/source/blender/draw/intern/draw_color_management.h
+++ b/source/blender/draw/intern/draw_color_management.h
@@ -20,9 +20,6 @@
* \ingroup draw
*/
-#ifndef __DRAW_COLOR_MANAGEMENT_H__
-#define __DRAW_COLOR_MANAGEMENT_H__
+#pragma once
void DRW_transform_none(struct GPUTexture *tex);
-
-#endif /* __DRAW_COLOR_MANAGEMENT_H__ */
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index aa8dd2f7fa4..0f26a8ddc09 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -22,6 +22,7 @@
#include "DRW_render.h"
+#include "GPU_matrix.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
@@ -31,8 +32,6 @@
#include "BKE_global.h"
#include "BKE_object.h"
-#include "BIF_glutil.h"
-
#include "draw_common.h"
#if 0
@@ -280,7 +279,7 @@ DRWView *DRW_view_create_with_zoffset(const DRWView *parent_view,
viewdist = 1.0f / max_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
}
- winmat[3][2] -= bglPolygonOffsetCalc((float *)winmat, viewdist, offset);
+ winmat[3][2] -= GPU_polygon_offset_calc(winmat, viewdist, offset);
return DRW_view_create_sub(parent_view, viewmat, winmat);
}
@@ -456,11 +455,11 @@ bool DRW_object_is_flat(Object *ob, int *r_axis)
*r_axis = 0;
return true;
}
- else if (dim[1] == 0.0f) {
+ if (dim[1] == 0.0f) {
*r_axis = 1;
return true;
}
- else if (dim[2] == 0.0f) {
+ if (dim[2] == 0.0f) {
*r_axis = 2;
return true;
}
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 81c0e97a1a8..6060dce47ac 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -20,15 +20,16 @@
* \ingroup draw
*/
-#ifndef __DRAW_COMMON_H__
-#define __DRAW_COMMON_H__
+#pragma once
struct DRWPass;
struct DRWShadingGroup;
struct GPUMaterial;
struct ModifierData;
+struct FluidModifierData;
struct Object;
struct ParticleSystem;
+struct RegionView3D;
struct ViewLayer;
#define UBO_FIRST_COLOR colorWire
@@ -159,14 +160,14 @@ void DRW_globals_update(void);
void DRW_globals_free(void);
struct DRWView *DRW_view_create_with_zoffset(const struct DRWView *parent_view,
- const RegionView3D *rv3d,
+ const struct RegionView3D *rv3d,
float offset);
int DRW_object_wire_theme_get(struct Object *ob, struct ViewLayer *view_layer, float **r_color);
float *DRW_color_background_blend_get(int theme_id);
-bool DRW_object_is_flat(Object *ob, int *r_axis);
-bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis);
+bool DRW_object_is_flat(struct Object *ob, int *r_axis);
+bool DRW_object_axis_orthogonal_to_view(struct Object *ob, int axis);
/* draw_hair.c */
@@ -188,6 +189,16 @@ void DRW_hair_init(void);
void DRW_hair_update(void);
void DRW_hair_free(void);
+/* draw_fluid.c */
+
+/* Fluid simulation. */
+void DRW_smoke_ensure(struct FluidModifierData *fmd, int highres);
+void DRW_smoke_ensure_coba_field(struct FluidModifierData *fmd);
+void DRW_smoke_ensure_velocity(struct FluidModifierData *fmd);
+
+void DRW_smoke_free(struct FluidModifierData *fmd);
+void DRW_smoke_free_velocity(struct FluidModifierData *fmd);
+
/* draw_common.c */
struct DRW_Global {
/** If needed, contains all global/Theme colors
@@ -203,5 +214,3 @@ struct DRW_Global {
struct GPUUniformBuffer *view_ubo;
};
extern struct DRW_Global G_draw;
-
-#endif /* __DRAW_COMMON_H__ */
diff --git a/source/blender/draw/intern/draw_debug.h b/source/blender/draw/intern/draw_debug.h
index e7404b17384..149825974d4 100644
--- a/source/blender/draw/intern/draw_debug.h
+++ b/source/blender/draw/intern/draw_debug.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRAW_DEBUG_H__
-#define __DRAW_DEBUG_H__
+#pragma once
struct BoundBox;
@@ -34,5 +33,3 @@ void DRW_debug_m4(const float m[4][4]);
void DRW_debug_m4_as_bbox(const float m[4][4], const float color[4], const bool invert);
void DRW_debug_bbox(const BoundBox *bbox, const float color[4]);
void DRW_debug_sphere(const float center[3], const float radius, const float color[4]);
-
-#endif /* __DRAW_DEBUG_H__ */
diff --git a/source/blender/gpu/intern/gpu_draw_smoke.c b/source/blender/draw/intern/draw_fluid.c
index 79b3861d339..33311dc698f 100644
--- a/source/blender/gpu/intern/gpu_draw_smoke.c
+++ b/source/blender/draw/intern/draw_fluid.c
@@ -35,10 +35,10 @@
#include "BKE_colorband.h"
-#include "GPU_draw.h"
-#include "GPU_glew.h"
#include "GPU_texture.h"
+#include "draw_common.h" /* Own include. */
+
#ifdef WITH_FLUID
# include "manta_fluid_API.h"
#endif
@@ -62,7 +62,8 @@ static void create_flame_spectrum_texture(float *data)
# define MAX_FIRE_ALPHA 0.06f
# define FULL_ON_FIRE 100
- float *spec_pixels = MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float), "spec_pixels");
+ float *spec_pixels = (float *)MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float),
+ "spec_pixels");
blackbody_temperature_to_rgb_table(data, TFUNC_WIDTH, 1500, 3000);
@@ -105,7 +106,7 @@ static void create_color_ramp(const struct ColorBand *coba, float *data)
static GPUTexture *create_transfer_function(int type, const struct ColorBand *coba)
{
- float *data = MEM_mallocN(sizeof(float) * 4 * TFUNC_WIDTH, __func__);
+ float *data = (float *)MEM_mallocN(sizeof(float) * 4 * TFUNC_WIDTH, __func__);
switch (type) {
case TFUNC_FLAME_SPECTRUM:
@@ -128,7 +129,7 @@ static void swizzle_texture_channel_single(GPUTexture *tex)
/* Swizzle texture channels so that we get useful RGBA values when sampling
* a texture with fewer channels, e.g. when using density as color. */
GPU_texture_bind(tex, 0);
- GPU_texture_swizzle_channel_auto(tex, 1);
+ GPU_texture_swizzle_set(tex, "rrr1");
GPU_texture_unbind(tex);
}
@@ -184,7 +185,7 @@ static GPUTexture *create_field_texture(FluidDomainSettings *fds)
}
GPUTexture *tex = GPU_texture_create_nD(
- fds->res[0], fds->res[1], fds->res[2], 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
+ UNPACK3(fds->res), 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
swizzle_texture_channel_single(tex);
return tex;
@@ -196,14 +197,14 @@ static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
float *data;
if (highres) {
- data = manta_smoke_turbulence_get_density(fds->fluid);
+ data = manta_noise_get_density(fds->fluid);
}
else {
data = manta_smoke_get_density(fds->fluid);
}
GPUTexture *tex = GPU_texture_create_nD(
- dim[0], dim[1], dim[2], 3, data, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
+ UNPACK3(dim), 3, data, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
swizzle_texture_channel_single(tex);
@@ -212,23 +213,23 @@ static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
{
- const bool has_color = (highres) ? manta_smoke_turbulence_has_colors(fds->fluid) :
+ const bool has_color = (highres) ? manta_noise_has_colors(fds->fluid) :
manta_smoke_has_colors(fds->fluid);
if (!has_color) {
return NULL;
}
- int cell_count = (highres) ? manta_smoke_turbulence_get_cells(fds->fluid) : fds->total_cells;
+ int cell_count = (highres) ? manta_noise_get_cells(fds->fluid) : fds->total_cells;
int *dim = (highres) ? fds->res_noise : fds->res;
- float *data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
+ float *data = (float *)MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
if (data == NULL) {
return NULL;
}
if (highres) {
- manta_smoke_turbulence_get_rgba(fds->fluid, data, 0);
+ manta_noise_get_rgba(fds->fluid, data, 0);
}
else {
manta_smoke_get_rgba(fds->fluid, data, 0);
@@ -245,7 +246,7 @@ static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
{
float *source = NULL;
- const bool has_fuel = (highres) ? manta_smoke_turbulence_has_fuel(fds->fluid) :
+ const bool has_fuel = (highres) ? manta_noise_has_fuel(fds->fluid) :
manta_smoke_has_fuel(fds->fluid);
int *dim = (highres) ? fds->res_noise : fds->res;
@@ -254,7 +255,7 @@ static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
}
if (highres) {
- source = manta_smoke_turbulence_get_flame(fds->fluid);
+ source = manta_noise_get_flame(fds->fluid);
}
else {
source = manta_smoke_get_flame(fds->fluid);
@@ -276,7 +277,7 @@ static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
/** \name Public API
* \{ */
-void GPU_free_smoke(FluidModifierData *fmd)
+void DRW_smoke_free(FluidModifierData *fmd)
{
if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) {
if (fmd->domain->tex_density) {
@@ -316,7 +317,7 @@ void GPU_free_smoke(FluidModifierData *fmd)
}
}
-void GPU_create_smoke_coba_field(FluidModifierData *fmd)
+void DRW_smoke_ensure_coba_field(FluidModifierData *fmd)
{
#ifndef WITH_FLUID
UNUSED_VARS(fmd);
@@ -334,7 +335,7 @@ void GPU_create_smoke_coba_field(FluidModifierData *fmd)
#endif
}
-void GPU_create_smoke(FluidModifierData *fmd, int highres)
+void DRW_smoke_ensure(FluidModifierData *fmd, int highres)
{
#ifndef WITH_FLUID
UNUSED_VARS(fmd, highres);
@@ -355,9 +356,7 @@ void GPU_create_smoke(FluidModifierData *fmd, int highres)
fds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL);
}
if (!fds->tex_shadow) {
- fds->tex_shadow = GPU_texture_create_nD(fds->res[0],
- fds->res[1],
- fds->res[2],
+ fds->tex_shadow = GPU_texture_create_nD(UNPACK3(fds->res),
3,
manta_smoke_get_shadow(fds->fluid),
GPU_R8,
@@ -370,7 +369,7 @@ void GPU_create_smoke(FluidModifierData *fmd, int highres)
#endif /* WITH_FLUID */
}
-void GPU_create_smoke_velocity(FluidModifierData *fmd)
+void DRW_smoke_ensure_velocity(FluidModifierData *fmd)
{
#ifndef WITH_FLUID
UNUSED_VARS(fmd);
@@ -387,19 +386,16 @@ void GPU_create_smoke_velocity(FluidModifierData *fmd)
}
if (!fds->tex_velocity_x) {
- fds->tex_velocity_x = GPU_texture_create_3d(
- fds->res[0], fds->res[1], fds->res[2], GPU_R16F, vel_x, NULL);
- fds->tex_velocity_y = GPU_texture_create_3d(
- fds->res[0], fds->res[1], fds->res[2], GPU_R16F, vel_y, NULL);
- fds->tex_velocity_z = GPU_texture_create_3d(
- fds->res[0], fds->res[1], fds->res[2], GPU_R16F, vel_z, NULL);
+ fds->tex_velocity_x = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_x, NULL);
+ fds->tex_velocity_y = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_y, NULL);
+ fds->tex_velocity_z = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_z, NULL);
}
}
#endif /* WITH_FLUID */
}
-/* TODO Unify with the other GPU_free_smoke. */
-void GPU_free_smoke_velocity(FluidModifierData *fmd)
+/* TODO Unify with the other DRW_smoke_free. */
+void DRW_smoke_free_velocity(FluidModifierData *fmd)
{
if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) {
if (fmd->domain->tex_velocity_x) {
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 6cfba0e2a78..cbdcbbf9090 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -343,7 +343,7 @@ void DRW_hair_update(void)
DRW_draw_pass_subset(g_tf_pass, pr_call->shgrp, pr_call->shgrp);
/* Readback result to main memory. */
- GPU_framebuffer_read_color(fb, 0, 0, width, height, 4, 0, data);
+ GPU_framebuffer_read_color(fb, 0, 0, width, height, 4, 0, GPU_DATA_FLOAT, data);
/* Upload back to VBO. */
GPU_vertbuf_use(pr_call->vbo);
glBufferSubData(GL_ARRAY_BUFFER,
diff --git a/source/blender/draw/intern/draw_hair_private.h b/source/blender/draw/intern/draw_hair_private.h
index b599ad389c1..33abae156cc 100644
--- a/source/blender/draw/intern/draw_hair_private.h
+++ b/source/blender/draw/intern/draw_hair_private.h
@@ -21,8 +21,7 @@
* \ingroup draw
*/
-#ifndef __DRAW_HAIR_PRIVATE_H__
-#define __DRAW_HAIR_PRIVATE_H__
+#pragma once
#define MAX_LAYER_NAME_CT 4 /* u0123456789, u, au, a0123456789 */
#define MAX_LAYER_NAME_LEN GPU_MAX_SAFE_ATTR_NAME + 2
@@ -92,5 +91,3 @@ bool hair_ensure_procedural_data(struct Object *object,
struct ParticleHairCache **r_hair_cache,
int subdiv,
int thickness_res);
-
-#endif /* __DRAW_HAIR_PRIVATE_H__ */
diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h
index f891d380ee3..e562d99097e 100644
--- a/source/blender/draw/intern/draw_instance_data.h
+++ b/source/blender/draw/intern/draw_instance_data.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRAW_INSTANCE_DATA_H__
-#define __DRAW_INSTANCE_DATA_H__
+#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_sys_types.h"
@@ -55,5 +54,3 @@ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist);
void DRW_instance_data_list_reset(DRWInstanceDataList *idatalist);
void DRW_instance_data_list_free_unused(DRWInstanceDataList *idatalist);
void DRW_instance_data_list_resize(DRWInstanceDataList *idatalist);
-
-#endif /* __DRAW_INSTANCE_DATA_H__ */
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 3e42c4cdb23..d03b5107bb6 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -369,7 +369,7 @@ void DRW_engine_viewport_data_size_get(
}
/* WARNING: only use for custom pipeline. 99% of the time, you don't want to use this. */
-void DRW_render_viewport_size_set(int size[2])
+void DRW_render_viewport_size_set(const int size[2])
{
DST.size[0] = size[0];
DST.size[1] = size[1];
@@ -792,9 +792,8 @@ DrawDataList *DRW_drawdatalist_from_id(ID *id)
IdDdtTemplate *idt = (IdDdtTemplate *)id;
return &idt->drawdata;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type)
@@ -1658,26 +1657,9 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
Scene *scene = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RenderEngineType *engine_type = engine->type;
- RenderData *r = &scene->r;
Render *render = engine->re;
- /* Changing Context */
- if (G.background && DST.gl_context == NULL) {
- WM_init_opengl(G_MAIN);
- }
-
- void *re_gl_context = RE_gl_context_get(render);
- void *re_gpu_context = NULL;
- /* Changing Context */
- if (re_gl_context != NULL) {
- DRW_opengl_render_context_enable(re_gl_context);
- /* We need to query gpu context after a gl context has been bound. */
- re_gpu_context = RE_gpu_context_get(render);
- DRW_gpu_render_context_enable(re_gpu_context);
- }
- else {
- DRW_opengl_context_enable();
- }
+ DRW_render_context_enable(render);
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -1696,7 +1678,7 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
drw_context_state_init();
DST.viewport = GPU_viewport_create();
- const int size[2] = {(r->size * r->xsch) / 100, (r->size * r->ysch) / 100};
+ const int size[2] = {engine->resolution_x, engine->resolution_y};
GPU_viewport_size_set(DST.viewport, size);
drw_viewport_var_init();
@@ -1729,14 +1711,7 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
/* Restore Drawing area. */
GPU_framebuffer_restore();
- /* Changing Context */
- if (re_gl_context != NULL) {
- DRW_gpu_render_context_disable(re_gpu_context);
- DRW_opengl_render_context_disable(re_gl_context);
- }
- else {
- DRW_opengl_context_disable();
- }
+ DRW_render_context_disable(render);
DST.buffer_finish_called = false;
}
@@ -1749,24 +1724,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
DrawEngineType *draw_engine_type = engine_type->draw_engine;
Render *render = engine->re;
- if (G.background && DST.gl_context == NULL) {
- WM_init_opengl(G_MAIN);
- }
-
- void *re_gl_context = RE_gl_context_get(render);
- void *re_gpu_context = NULL;
-
- /* Changing Context */
- if (re_gl_context != NULL) {
- DRW_opengl_render_context_enable(re_gl_context);
- /* We need to query gpu context after a gl context has been bound. */
- re_gpu_context = RE_gpu_context_get(render);
- DRW_gpu_render_context_enable(re_gpu_context);
- }
- else {
- DRW_opengl_context_enable();
- }
-
/* IMPORTANT: We don't support immediate mode in render mode!
* This shall remain in effect until immediate mode supports
* multiple threads. */
@@ -1793,9 +1750,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine_type);
- /* set default viewport */
- glViewport(0, 0, size[0], size[1]);
-
/* Main rendering. */
rctf view_rect;
rcti render_rect;
@@ -1809,12 +1763,15 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
/* Reset state before drawing */
DRW_state_reset();
+ /* set default viewport */
+ GPU_viewport(0, 0, size[0], size[1]);
+
/* Init render result. */
RenderResult *render_result = RE_engine_begin_result(engine,
0,
0,
- (int)size[0],
- (int)size[1],
+ size[0],
+ size[1],
view_layer->name,
/* RR_ALL_VIEWS */ NULL);
@@ -1842,15 +1799,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
/* Reset state after drawing */
DRW_state_reset();
-
- /* Changing Context */
- if (re_gl_context != NULL) {
- DRW_gpu_render_context_disable(re_gpu_context);
- DRW_opengl_render_context_disable(re_gl_context);
- }
- else {
- DRW_opengl_context_disable();
- }
}
void DRW_render_object_iter(
@@ -2004,13 +1952,21 @@ void DRW_render_instance_buffer_finish(void)
drw_resource_buffer_finish(DST.vmempool);
}
+/* WARNING: Changing frame might free the ViewLayerEngineData */
+void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame, float subframe)
+{
+ RE_engine_frame_set(engine, frame, subframe);
+ DST.draw_ctx.scene = DEG_get_evaluated_scene(depsgraph);
+ DST.draw_ctx.view_layer = DEG_get_evaluated_view_layer(depsgraph);
+}
+
/**
* object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
*/
void DRW_draw_select_loop(struct Depsgraph *depsgraph,
ARegion *region,
View3D *v3d,
- bool UNUSED(use_obedit_skip),
+ bool use_obedit_skip,
bool draw_surface,
bool UNUSED(use_nearest),
const rcti *rect,
@@ -2023,7 +1979,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
Object *obact = OBACT(view_layer);
- Object *obedit = OBEDIT_FROM_OBACT(obact);
+ Object *obedit = use_obedit_skip ? NULL : OBEDIT_FROM_OBACT(obact);
#ifndef USE_GPU_SELECT
UNUSED_VARS(scene, view_layer, v3d, region, rect);
#else
@@ -2469,12 +2425,6 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons
#endif
}
-/** See #DRW_shgroup_world_clip_planes_from_rv3d. */
-static void draw_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
-{
- GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
-}
-
/**
* Clears the Depth Buffer and draws only the specified object.
*/
@@ -2497,7 +2447,7 @@ void DRW_draw_depth_object(
const float(*world_clip_planes)[4] = NULL;
if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
- ED_view3d_clipping_set(rv3d);
+ GPU_clip_distances(6);
ED_view3d_clipping_local(rv3d, object->obmat);
world_clip_planes = rv3d->clip_local;
}
@@ -2525,7 +2475,7 @@ void DRW_draw_depth_object(
GPU_SHADER_CFG_DEFAULT;
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
if (world_clip_planes != NULL) {
- draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
+ GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
}
GPU_batch_draw(batch);
@@ -2536,7 +2486,7 @@ void DRW_draw_depth_object(
}
if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
- ED_view3d_clipping_disable();
+ GPU_clip_distances(0);
}
GPU_matrix_set(rv3d->viewmat);
@@ -2769,6 +2719,54 @@ void DRW_engines_free(void)
DRW_opengl_context_disable();
}
+void DRW_render_context_enable(Render *render)
+{
+ if (G.background && DST.gl_context == NULL) {
+ WM_init_opengl();
+ }
+
+ if (GPU_use_main_context_workaround()) {
+ GPU_context_main_lock();
+ DRW_opengl_context_enable();
+ return;
+ }
+
+ void *re_gl_context = RE_gl_context_get(render);
+
+ /* Changing Context */
+ if (re_gl_context != NULL) {
+ DRW_opengl_render_context_enable(re_gl_context);
+ /* We need to query gpu context after a gl context has been bound. */
+ void *re_gpu_context = NULL;
+ re_gpu_context = RE_gpu_context_get(render);
+ DRW_gpu_render_context_enable(re_gpu_context);
+ }
+ else {
+ DRW_opengl_context_enable();
+ }
+}
+
+void DRW_render_context_disable(Render *render)
+{
+ if (GPU_use_main_context_workaround()) {
+ DRW_opengl_context_disable();
+ GPU_context_main_unlock();
+ return;
+ }
+
+ void *re_gl_context = RE_gl_context_get(render);
+
+ if (re_gl_context != NULL) {
+ void *re_gpu_context = NULL;
+ re_gpu_context = RE_gpu_context_get(render);
+ DRW_gpu_render_context_disable(re_gpu_context);
+ DRW_opengl_render_context_disable(re_gl_context);
+ }
+ else {
+ DRW_opengl_context_disable();
+ }
+}
+
/** \} */
/** \name Init/Exit (DRW_opengl_ctx)
@@ -2855,7 +2853,7 @@ void DRW_opengl_context_disable_ex(bool restore)
void DRW_opengl_context_enable(void)
{
if (G.background && DST.gl_context == NULL) {
- WM_init_opengl(G_MAIN);
+ WM_init_opengl();
}
DRW_opengl_context_enable_ex(true);
}
@@ -2909,8 +2907,8 @@ void DRW_gpu_render_context_disable(void *UNUSED(re_gpu_context))
* switch to it just to submit the final frame, which has notable performance impact.
*
* We could "inject" a context through DRW_opengl_render_context_enable(), but that would have to
- * work from the main thread, which is tricky to get working too. The preferable solution would be
- * using a separate thread for VR drawing where a single context can stay active. */
+ * work from the main thread, which is tricky to get working too. The preferable solution would
+ * be using a separate thread for VR drawing where a single context can stay active. */
void *DRW_xr_opengl_context_get(void)
{
return DST.gl_context;
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 31a2dd7f0fe..92a01cbbe04 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -22,8 +22,7 @@
/* Private functions / structs of the draw manager */
-#ifndef __DRAW_MANAGER_H__
-#define __DRAW_MANAGER_H__
+#pragma once
#include "DRW_engine.h"
#include "DRW_render.h"
@@ -380,6 +379,7 @@ typedef struct DRWViewUboStorage {
float wininv[4][4];
float clipplanes[6][4];
+ float viewvecs[2][4];
/* Should not be here. Not view dependent (only main view). */
float viewcamtexcofac[4];
} DRWViewUboStorage;
@@ -583,7 +583,7 @@ void drw_state_set(DRWState state);
void drw_debug_draw(void);
void drw_debug_init(void);
-eDRWCommandType command_type_get(uint64_t *command_type_bits, int index);
+eDRWCommandType command_type_get(const uint64_t *command_type_bits, int index);
void drw_batch_cache_validate(Object *ob);
void drw_batch_cache_generate_requested(struct Object *ob);
@@ -595,5 +595,3 @@ void drw_resource_buffer_finish(ViewportMemoryPool *vmempool);
GPUBatch *drw_cache_procedural_points_get(void);
GPUBatch *drw_cache_procedural_lines_get(void);
GPUBatch *drw_cache_procedural_triangles_get(void);
-
-#endif /* __DRAW_MANAGER_H__ */
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 3d83b918757..661a27c10b7 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -594,28 +594,26 @@ static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup,
DRWResourceHandle handle = 0;
return handle;
}
- else {
- return drw_resource_handle_new(obmat, NULL);
- }
+
+ return drw_resource_handle_new(obmat, NULL);
}
- else {
- if (DST.ob_handle == 0) {
- DST.ob_handle = drw_resource_handle_new(obmat, ob);
- DST.ob_state_obinfo_init = false;
- }
- if (shgroup->objectinfo) {
- if (!DST.ob_state_obinfo_init) {
- DST.ob_state_obinfo_init = true;
- DRWObjectInfos *ob_infos = DRW_memblock_elem_from_handle(DST.vmempool->obinfos,
- &DST.ob_handle);
+ if (DST.ob_handle == 0) {
+ DST.ob_handle = drw_resource_handle_new(obmat, ob);
+ DST.ob_state_obinfo_init = false;
+ }
- drw_call_obinfos_init(ob_infos, ob);
- }
- }
+ if (shgroup->objectinfo) {
+ if (!DST.ob_state_obinfo_init) {
+ DST.ob_state_obinfo_init = true;
+ DRWObjectInfos *ob_infos = DRW_memblock_elem_from_handle(DST.vmempool->obinfos,
+ &DST.ob_handle);
- return DST.ob_handle;
+ drw_call_obinfos_init(ob_infos, ob);
+ }
}
+
+ return DST.ob_handle;
}
static void command_type_set(uint64_t *command_type_bits, int index, eDRWCommandType type)
@@ -623,7 +621,7 @@ static void command_type_set(uint64_t *command_type_bits, int index, eDRWCommand
command_type_bits[index / 16] |= ((uint64_t)type) << ((index % 16) * 4);
}
-eDRWCommandType command_type_get(uint64_t *command_type_bits, int index)
+eDRWCommandType command_type_get(const uint64_t *command_type_bits, int index)
{
return ((command_type_bits[index / 16] >> ((index % 16) * 4)) & 0xF);
}
@@ -793,10 +791,10 @@ void DRW_shgroup_call_range(
drw_command_draw_range(shgroup, geom, handle, v_sta, v_ct);
}
+/* A count of 0 instance will use the default number of instance in the batch. */
void DRW_shgroup_call_instance_range(
DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint i_sta, uint i_ct)
{
- BLI_assert(i_ct > 0);
BLI_assert(geom != NULL);
if (G.f & G_FLAG_PICKSEL) {
drw_command_set_select_id(shgroup, NULL, DST.select_id);
@@ -1292,13 +1290,10 @@ static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass
}
static void drw_shgroup_material_texture(DRWShadingGroup *grp,
- GPUMaterialTexture *tex,
+ GPUTexture *gputex,
const char *name,
- eGPUSamplerState state,
- int textarget)
+ eGPUSamplerState state)
{
- GPUTexture *gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget);
-
DRW_shgroup_uniform_texture_ex(grp, name, gputex, state);
GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images);
@@ -1314,15 +1309,16 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial
LISTBASE_FOREACH (GPUMaterialTexture *, tex, &textures) {
if (tex->ima) {
/* Image */
+ GPUTexture *gputex;
if (tex->tiled_mapping_name[0]) {
- drw_shgroup_material_texture(
- grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D_ARRAY);
- drw_shgroup_material_texture(
- grp, tex, tex->tiled_mapping_name, tex->sampler_state, GL_TEXTURE_1D_ARRAY);
+ gputex = BKE_image_get_gpu_tiles(tex->ima, tex->iuser, NULL);
+ drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state);
+ gputex = BKE_image_get_gpu_tilemap(tex->ima, tex->iuser, NULL);
+ drw_shgroup_material_texture(grp, gputex, tex->tiled_mapping_name, tex->sampler_state);
}
else {
- drw_shgroup_material_texture(
- grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D);
+ gputex = BKE_image_get_gpu_texture(tex->ima, tex->iuser, NULL);
+ drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state);
}
}
else if (tex->colorband) {
@@ -1656,6 +1652,52 @@ static void draw_view_matrix_state_update(DRWViewUboStorage *storage,
mul_m4_m4m4(storage->persmat, winmat, viewmat);
invert_m4_m4(storage->persinv, storage->persmat);
+
+ const bool is_persp = (winmat[3][3] == 0.0f);
+
+ /* Near clip distance. */
+ storage->viewvecs[0][3] = (is_persp) ? -winmat[3][2] / (winmat[2][2] - 1.0f) :
+ -(winmat[3][2] + 1.0f) / winmat[2][2];
+
+ /* Far clip distance. */
+ storage->viewvecs[1][3] = (is_persp) ? -winmat[3][2] / (winmat[2][2] + 1.0f) :
+ -(winmat[3][2] - 1.0f) / winmat[2][2];
+
+ /* view vectors for the corners of the view frustum.
+ * Can be used to recreate the world space position easily */
+ float view_vecs[4][3] = {
+ {-1.0f, -1.0f, -1.0f},
+ {1.0f, -1.0f, -1.0f},
+ {-1.0f, 1.0f, -1.0f},
+ {-1.0f, -1.0f, 1.0f},
+ };
+
+ /* convert the view vectors to view space */
+ for (int i = 0; i < 4; i++) {
+ mul_project_m4_v3(storage->wininv, view_vecs[i]);
+ /* normalized trick see:
+ * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+ if (is_persp) {
+ /* Divide XY by Z. */
+ mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
+ }
+ }
+
+ /**
+ * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and
+ * view_vecs[1] is the vector going from the near-bottom-left corner to
+ * the far-top-right corner.
+ * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner
+ * when Z = 1, and top-left corner if Z = 1.
+ * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed)
+ * distance from the near plane to the far clip plane.
+ */
+ copy_v3_v3(storage->viewvecs[0], view_vecs[0]);
+
+ /* we need to store the differences */
+ storage->viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
+ storage->viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
+ storage->viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
}
/* Create a view with culling. */
@@ -1860,9 +1902,8 @@ float DRW_view_near_distance_get(const DRWView *view)
if (DRW_view_is_persp_get(view)) {
return -projmat[3][2] / (projmat[2][2] - 1.0f);
}
- else {
- return -(projmat[3][2] + 1.0f) / projmat[2][2];
- }
+
+ return -(projmat[3][2] + 1.0f) / projmat[2][2];
}
float DRW_view_far_distance_get(const DRWView *view)
@@ -1873,9 +1914,8 @@ float DRW_view_far_distance_get(const DRWView *view)
if (DRW_view_is_persp_get(view)) {
return -projmat[3][2] / (projmat[2][2] + 1.0f);
}
- else {
- return -(projmat[3][2] - 1.0f) / projmat[2][2];
- }
+
+ return -(projmat[3][2] - 1.0f) / projmat[2][2];
}
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
@@ -1982,18 +2022,16 @@ static int pass_shgroup_dist_sort(const void *a, const void *b)
if (shgrp_a->z_sorting.distance < shgrp_b->z_sorting.distance) {
return 1;
}
- else if (shgrp_a->z_sorting.distance > shgrp_b->z_sorting.distance) {
+ if (shgrp_a->z_sorting.distance > shgrp_b->z_sorting.distance) {
return -1;
}
- else {
- /* If distances are the same, keep original order. */
- if (shgrp_a->z_sorting.original_index > shgrp_b->z_sorting.original_index) {
- return -1;
- }
- else {
- return 0;
- }
+
+ /* If distances are the same, keep original order. */
+ if (shgrp_a->z_sorting.original_index > shgrp_b->z_sorting.original_index) {
+ return -1;
}
+
+ return 0;
}
/* ------------------ Shading group sorting --------------------- */
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 59b4e9af14e..4b63ea89e44 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -98,12 +98,7 @@ void drw_state_set(DRWState state)
{
int test;
if ((test = CHANGED_TO(DRW_STATE_WRITE_DEPTH))) {
- if (test == 1) {
- glDepthMask(GL_TRUE);
- }
- else {
- glDepthMask(GL_FALSE);
- }
+ GPU_depth_mask(test == 1);
}
}
@@ -142,10 +137,10 @@ void drw_state_set(DRWState state)
int test;
if ((test = CHANGED_TO(DRW_STATE_WRITE_COLOR))) {
if (test == 1) {
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ GPU_color_mask(true, true, true, true);
}
else {
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ GPU_color_mask(false, false, false, false);
}
}
}
@@ -355,14 +350,10 @@ void drw_state_set(DRWState state)
int test;
if ((test = CHANGED_TO(DRW_STATE_CLIP_PLANES))) {
if (test == 1) {
- for (int i = 0; i < DST.view_active->clip_planes_len; i++) {
- glEnable(GL_CLIP_DISTANCE0 + i);
- }
+ GPU_clip_distances(DST.view_active->clip_planes_len);
}
else {
- for (int i = 0; i < MAX_CLIP_PLANES; i++) {
- glDisable(GL_CLIP_DISTANCE0 + i);
- }
+ GPU_clip_distances(0);
}
}
}
@@ -455,6 +446,7 @@ void DRW_state_reset(void)
DRW_state_reset_ex(DRW_STATE_DEFAULT);
GPU_texture_unbind_all();
+ GPU_uniformbuffer_unbind_all();
/* Should stay constant during the whole rendering. */
GPU_point_size(5);
@@ -526,7 +518,7 @@ static bool draw_culling_box_test(const float (*frustum_planes)[4], const BoundB
* Go to next plane. */
break;
}
- else if (v == 7) {
+ if (v == 7) {
/* 8 points behind this plane. */
return false;
}
@@ -678,8 +670,7 @@ BLI_INLINE void draw_geometry_bind(DRWShadingGroup *shgroup, GPUBatch *geom)
DST.batch = geom;
- GPU_batch_program_set_no_use(
- geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
+ GPU_batch_set_shader_no_bind(geom, shgroup->shader);
geom->program_in_use = true; /* XXX hacking #GPUBatch */
@@ -782,10 +773,11 @@ static bool ubo_bindings_validate(DRWShadingGroup *shgroup)
DRWPass *parent_pass = DRW_memblock_elem_from_handle(DST.vmempool->passes,
&shgroup->pass_handle);
- printf("Pass : %s, Shader : %s, Block : %s\n",
+ printf("Pass : %s, Shader : %s, Block : %s, Binding %d\n",
parent_pass->name,
shgroup->shader->name,
- blockname);
+ blockname,
+ binding);
}
}
# endif
@@ -1003,9 +995,8 @@ static void draw_call_single_do(DRWShadingGroup *shgroup,
draw_select_buffer(shgroup, state, batch, &handle);
return;
}
- else {
- GPU_select_load_id(state->select_id);
- }
+
+ GPU_select_load_id(state->select_id);
}
draw_geometry_execute(shgroup,
@@ -1115,6 +1106,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
/* Unbinding can be costly. Skip in normal condition. */
if (G.debug & G_DEBUG_GPU) {
GPU_texture_unbind_all();
+ GPU_uniformbuffer_unbind_all();
}
}
GPU_shader_bind(shgroup->shader);
diff --git a/source/blender/draw/intern/draw_manager_profiling.h b/source/blender/draw/intern/draw_manager_profiling.h
index 3da6a4c8b1c..3842bdffaff 100644
--- a/source/blender/draw/intern/draw_manager_profiling.h
+++ b/source/blender/draw/intern/draw_manager_profiling.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRAW_MANAGER_PROFILING_H__
-#define __DRAW_MANAGER_PROFILING_H__
+#pragma once
struct rcti;
@@ -36,5 +35,3 @@ void DRW_stats_query_start(const char *name);
void DRW_stats_query_end(void);
void DRW_stats_draw(const rcti *rect);
-
-#endif /* __DRAW_MANAGER_PROFILING_H__ */
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 6304b707cb9..1c260721efb 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -34,6 +34,7 @@
#include "DEG_depsgraph_query.h"
+#include "GPU_extensions.h"
#include "GPU_material.h"
#include "GPU_shader.h"
@@ -91,10 +92,13 @@ static void drw_deferred_shader_queue_free(ListBase *queue)
}
}
-static void drw_deferred_shader_compilation_exec(void *custom_data,
- short *stop,
- short *do_update,
- float *progress)
+static void drw_deferred_shader_compilation_exec(
+ void *custom_data,
+ /* Cannot be const, this function implements wm_jobs_start_callback.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ short *stop,
+ short *do_update,
+ float *progress)
{
DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data;
void *gl_context = comp->gl_context;
@@ -103,6 +107,12 @@ static void drw_deferred_shader_compilation_exec(void *custom_data,
BLI_assert(gl_context != NULL);
#endif
+ const bool use_main_context_workaround = GPU_use_main_context_workaround();
+ if (use_main_context_workaround) {
+ BLI_assert(gl_context == DST.gl_context);
+ GPU_context_main_lock();
+ }
+
WM_opengl_context_activate(gl_context);
while (true) {
@@ -151,6 +161,9 @@ static void drw_deferred_shader_compilation_exec(void *custom_data,
}
WM_opengl_context_release(gl_context);
+ if (use_main_context_workaround) {
+ GPU_context_main_unlock();
+ }
}
static void drw_deferred_shader_compilation_free(void *custom_data)
@@ -193,6 +206,8 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
GPU_material_compile(mat);
return;
}
+ const bool use_main_context = GPU_use_main_context_workaround();
+ const bool job_own_context = !use_main_context;
DRWDeferredShader *dsh = MEM_callocN(sizeof(DRWDeferredShader), "Deferred Shader");
@@ -224,7 +239,7 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
if (old_comp->gl_context) {
comp->gl_context = old_comp->gl_context;
old_comp->own_context = false;
- comp->own_context = true;
+ comp->own_context = job_own_context;
}
}
@@ -232,9 +247,14 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
/* Create only one context. */
if (comp->gl_context == NULL) {
- comp->gl_context = WM_opengl_context_create();
- WM_opengl_context_activate(DST.gl_context);
- comp->own_context = true;
+ if (use_main_context) {
+ comp->gl_context = DST.gl_context;
+ }
+ else {
+ comp->gl_context = WM_opengl_context_create();
+ WM_opengl_context_activate(DST.gl_context);
+ }
+ comp->own_context = job_own_context;
}
WM_jobs_customdata_set(wm_job, comp, drw_deferred_shader_compilation_free);
@@ -325,6 +345,26 @@ GPUShader *DRW_shader_create_with_lib(
return sh;
}
+GPUShader *DRW_shader_create_with_shaderlib(const char *vert,
+ const char *geom,
+ const char *frag,
+ const DRWShaderLibrary *lib,
+ const char *defines)
+{
+ GPUShader *sh;
+ char *vert_with_lib = DRW_shader_library_create_shader_string(lib, vert);
+ char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag);
+ char *geom_with_lib = (geom) ? DRW_shader_library_create_shader_string(lib, geom) : NULL;
+
+ sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, __func__);
+
+ MEM_SAFE_FREE(vert_with_lib);
+ MEM_SAFE_FREE(frag_with_lib);
+ MEM_SAFE_FREE(geom_with_lib);
+
+ return sh;
+}
+
GPUShader *DRW_shader_create_with_transform_feedback(const char *vert,
const char *geom,
const char *defines,
@@ -349,6 +389,22 @@ GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines)
datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, __func__);
}
+GPUShader *DRW_shader_create_fullscreen_with_shaderlib(const char *frag,
+ const DRWShaderLibrary *lib,
+ const char *defines)
+{
+
+ GPUShader *sh;
+ char *vert = datatoc_common_fullscreen_vert_glsl;
+ char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag);
+
+ sh = GPU_shader_create(vert, frag_with_lib, NULL, NULL, defines, __func__);
+
+ MEM_SAFE_FREE(frag_with_lib);
+
+ return sh;
+}
+
GPUMaterial *DRW_shader_find_from_world(World *wo,
const void *engine_type,
const int options,
@@ -391,7 +447,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
const char *geom,
const char *frag_lib,
const char *defines,
- bool deferred)
+ bool deferred,
+ GPUMaterialEvalCallbackFn callback)
{
GPUMaterial *mat = NULL;
if (DRW_state_is_image_render() || !deferred) {
@@ -411,7 +468,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
geom,
frag_lib,
defines,
- wo->id.name);
+ wo->id.name,
+ callback);
}
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
@@ -431,7 +489,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
const char *geom,
const char *frag_lib,
const char *defines,
- bool deferred)
+ bool deferred,
+ GPUMaterialEvalCallbackFn callback)
{
GPUMaterial *mat = NULL;
if (DRW_state_is_image_render() || !deferred) {
@@ -451,7 +510,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
geom,
frag_lib,
defines,
- ma->id.name);
+ ma->id.name,
+ callback);
}
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
@@ -502,7 +562,7 @@ void DRW_shader_library_free(DRWShaderLibrary *lib)
MEM_SAFE_FREE(lib);
}
-static int drw_shader_library_search(DRWShaderLibrary *lib, const char *name)
+static int drw_shader_library_search(const DRWShaderLibrary *lib, const char *name)
{
for (int i = 0; i < MAX_LIB; i++) {
if (lib->libs[i]) {
@@ -518,18 +578,28 @@ static int drw_shader_library_search(DRWShaderLibrary *lib, const char *name)
}
/* Return bitmap of dependencies. */
-static uint32_t drw_shader_dependencies_get(DRWShaderLibrary *lib, char *lib_code)
+static uint32_t drw_shader_dependencies_get(const DRWShaderLibrary *lib, const char *lib_code)
{
/* Search dependencies. */
uint32_t deps = 0;
- char *haystack = lib_code;
+ const char *haystack = lib_code;
while ((haystack = strstr(haystack, "BLENDER_REQUIRE("))) {
haystack += 16;
int dep = drw_shader_library_search(lib, haystack);
if (dep == -1) {
+ char dbg_name[32];
+ int i = 0;
+ while ((haystack[0] != ')') && (i < 31)) {
+ dbg_name[i] = haystack[0];
+ haystack++;
+ i++;
+ }
+ dbg_name[i + 1] = '\0';
+
printf(
- "Error: Dependency not found.\n"
- "This might be due to bad lib ordering.\n");
+ "Error: Dependency not found: %s\n"
+ "This might be due to bad lib ordering.\n",
+ dbg_name);
BLI_assert(0);
}
else {
@@ -562,7 +632,7 @@ void DRW_shader_library_add_file(DRWShaderLibrary *lib, char *lib_code, const ch
/* Return an allocN'ed string containing the shader code with its dependencies prepended.
* Caller must free the string with MEM_freeN after use. */
-char *DRW_shader_library_create_shader_string(DRWShaderLibrary *lib, char *shader_code)
+char *DRW_shader_library_create_shader_string(const DRWShaderLibrary *lib, const char *shader_code)
{
uint32_t deps = drw_shader_dependencies_get(lib, shader_code);
diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.c
index f4601fe4f48..b3c4c97715e 100644
--- a/source/blender/draw/intern/draw_manager_text.c
+++ b/source/blender/draw/intern/draw_manager_text.c
@@ -38,6 +38,7 @@
#include "DNA_view3d_types.h"
#include "GPU_matrix.h"
+#include "GPU_state.h"
#include "ED_screen.h"
#include "ED_view3d.h"
@@ -149,8 +150,9 @@ void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, struct View3D *v3d)
if (tot) {
int col_pack_prev = 0;
+ /* Disable clipping for text */
if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
- ED_view3d_clipping_disable();
+ GPU_clip_distances(0);
}
float original_proj[4][4];
@@ -188,7 +190,7 @@ void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, struct View3D *v3d)
GPU_matrix_projection_set(original_proj);
if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
- ED_view3d_clipping_enable();
+ GPU_clip_distances(6);
}
}
}
diff --git a/source/blender/draw/intern/draw_manager_text.h b/source/blender/draw/intern/draw_manager_text.h
index 66ef2379e38..f6dff335f1f 100644
--- a/source/blender/draw/intern/draw_manager_text.h
+++ b/source/blender/draw/intern/draw_manager_text.h
@@ -20,8 +20,7 @@
* \ingroup draw
*/
-#ifndef __DRAW_MANAGER_TEXT_H__
-#define __DRAW_MANAGER_TEXT_H__
+#pragma once
struct ARegion;
struct DRWTextStore;
@@ -58,5 +57,3 @@ enum {
/* draw_manager.c */
struct DRWTextStore *DRW_text_cache_ensure(void);
-
-#endif /* __DRAW_MANAGER_TEXT_H__ */
diff --git a/source/blender/draw/intern/draw_manager_texture.c b/source/blender/draw/intern/draw_manager_texture.c
index 77b0462303d..b94a6db3bad 100644
--- a/source/blender/draw/intern/draw_manager_texture.c
+++ b/source/blender/draw/intern/draw_manager_texture.c
@@ -61,6 +61,10 @@ static bool drw_texture_format_supports_framebuffer(eGPUTextureFormat format)
void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags)
{
+ if (tex == NULL) {
+ return;
+ }
+
if (flags & DRW_TEX_MIPMAP) {
GPU_texture_mipmap_mode(tex, true, flags & DRW_TEX_FILTER);
GPU_texture_bind(tex, 0);
@@ -119,7 +123,6 @@ GPUTexture *DRW_texture_create_cube(int w,
{
GPUTexture *tex = GPU_texture_create_cube(w, format, fpixels, NULL);
drw_texture_set_parameters(tex, flags);
-
return tex;
}
@@ -128,7 +131,6 @@ GPUTexture *DRW_texture_create_cube_array(
{
GPUTexture *tex = GPU_texture_create_cube_array(w, d, format, fpixels, NULL);
drw_texture_set_parameters(tex, flags);
-
return tex;
}
diff --git a/source/blender/draw/intern/draw_select_buffer.c b/source/blender/draw/intern/draw_select_buffer.c
index 558d5441136..ee5561e1e38 100644
--- a/source/blender/draw/intern/draw_select_buffer.c
+++ b/source/blender/draw/intern/draw_select_buffer.c
@@ -84,14 +84,15 @@ uint *DRW_select_buffer_read(struct Depsgraph *depsgraph,
GPUFrameBuffer *select_id_fb = DRW_engine_select_framebuffer_get();
GPU_framebuffer_bind(select_id_fb);
- glReadBuffer(GL_COLOR_ATTACHMENT0);
- glReadPixels(rect_clamp.xmin,
- rect_clamp.ymin,
- BLI_rcti_size_x(&rect_clamp),
- BLI_rcti_size_y(&rect_clamp),
- GL_RED_INTEGER,
- GL_UNSIGNED_INT,
- r_buf);
+ GPU_framebuffer_read_color(select_id_fb,
+ rect_clamp.xmin,
+ rect_clamp.ymin,
+ BLI_rcti_size_x(&rect_clamp),
+ BLI_rcti_size_y(&rect_clamp),
+ 1,
+ 0,
+ GPU_DATA_UNSIGNED_INT,
+ r_buf);
if (!BLI_rcti_compare(rect, &rect_clamp)) {
/* The rect has been clamped so you need to realign the buffer and fill in the blanks */
@@ -394,7 +395,7 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph,
int center_x = width / 2;
int center_y = height / 2;
- /* Manhatten distance in keeping with other screen-based selection. */
+ /* Manhattan distance in keeping with other screen-based selection. */
*dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y));
/* Indices start at 1 here. */
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 06026d51faf..1458ff5341c 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -88,7 +88,7 @@ static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, Vie
/* no exception met? then don't draw cursor! */
return false;
}
- else if (draw_ctx->object_mode & OB_MODE_WEIGHT_GPENCIL) {
+ if (draw_ctx->object_mode & OB_MODE_WEIGHT_GPENCIL) {
/* grease pencil hide always in some modes */
return false;
}
@@ -103,9 +103,9 @@ void DRW_draw_cursor(void)
Scene *scene = draw_ctx->scene;
ViewLayer *view_layer = draw_ctx->view_layer;
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glDepthMask(GL_FALSE);
- glDisable(GL_DEPTH_TEST);
+ GPU_color_mask(true, true, true, true);
+ GPU_depth_mask(false);
+ GPU_depth_test(false);
if (is_cursor_visible(draw_ctx, scene, view_layer)) {
int co[2];
@@ -184,8 +184,7 @@ void DRW_draw_cursor(void)
GPUBatch *cursor_batch = DRW_cache_cursor_get(is_aligned);
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR);
- GPU_batch_program_set(
- cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
+ GPU_batch_set_shader(cursor_batch, shader);
GPU_batch_draw(cursor_batch);
@@ -217,5 +216,5 @@ void DRW_draw_gizmo_2d(void)
WM_gizmomap_draw(region->gizmo_map, draw_ctx->evil_C, WM_GIZMOMAP_DRAWSTEP_2D);
- glDepthMask(GL_TRUE);
+ GPU_depth_mask(true);
}
diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h
index 04f7d2bbabb..a01a2d0dcce 100644
--- a/source/blender/draw/intern/draw_view.h
+++ b/source/blender/draw/intern/draw_view.h
@@ -20,13 +20,10 @@
* \ingroup draw
*/
-#ifndef __DRAW_VIEW_H__
-#define __DRAW_VIEW_H__
+#pragma once
void DRW_draw_region_info(void);
void DRW_clear_background(void);
void DRW_draw_cursor(void);
void DRW_draw_gizmo_3d(void);
void DRW_draw_gizmo_2d(void);
-
-#endif /* __DRAW_VIEW_H__ */
diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl
index ffff631e34b..8684d82f228 100644
--- a/source/blender/draw/intern/shaders/common_hair_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl
@@ -95,7 +95,7 @@ void hair_get_interp_attrs(
* For final drawing, the vertex index and the number of vertex per segment
*/
-#ifndef HAIR_PHASE_SUBDIV
+#if !defined(HAIR_PHASE_SUBDIV) && defined(GPU_VERTEX_SHADER)
int hair_get_strand_id(void)
{
return gl_VertexID / (hairStrandsRes * hairThicknessRes);
@@ -206,4 +206,24 @@ vec3 hair_get_strand_pos(void)
return texelFetch(hairPointBuffer, id).point_position;
}
+vec2 hair_get_barycentric(void)
+{
+ /* To match cycles without breaking into individual segment we encode if we need to invert
+ * the first component into the second component. We invert if the barycentricTexCo.y
+ * is NOT 0.0 or 1.0. */
+ int id = hair_get_base_id();
+ return vec2(float((id % 2) == 1), float(((id % 4) % 3) > 0));
+}
+
#endif
+
+/* To be fed the result of hair_get_barycentric from vertex shader. */
+vec2 hair_resolve_barycentric(vec2 vert_barycentric)
+{
+ if (fract(vert_barycentric.y) != 0.0) {
+ return vec2(vert_barycentric.x, 0.0);
+ }
+ else {
+ return vec2(1.0 - vert_barycentric.x, 0.0);
+ }
+}
diff --git a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl
new file mode 100644
index 00000000000..643d7e7d942
--- /dev/null
+++ b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl
@@ -0,0 +1,119 @@
+
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
+/* ---------------------------------------------------------------------- */
+/** \name Math intersection & projection functions.
+ * \{ */
+
+float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal)
+{
+ return dot(planenormal, planeorigin - lineorigin);
+}
+
+float line_plane_intersect_dist(vec3 lineorigin,
+ vec3 linedirection,
+ vec3 planeorigin,
+ vec3 planenormal)
+{
+ return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
+}
+
+float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane)
+{
+ vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz));
+ vec3 h = lineorigin - plane_co;
+ return -dot(plane.xyz, h) / dot(plane.xyz, linedirection);
+}
+
+vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
+{
+ float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal);
+ return lineorigin + linedirection * dist;
+}
+
+vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane)
+{
+ float dist = line_plane_intersect_dist(lineorigin, linedirection, plane);
+ return lineorigin + linedirection * dist;
+}
+
+float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
+{
+ /* aligned plane normal */
+ vec3 L = planeorigin - lineorigin;
+ float diskdist = length(L);
+ vec3 planenormal = -normalize(L);
+ return -diskdist / dot(planenormal, linedirection);
+}
+
+vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
+{
+ float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin);
+ if (dist < 0) {
+ /* if intersection is behind we fake the intersection to be
+ * really far and (hopefully) not inside the radius of interest */
+ dist = 1e16;
+ }
+ return lineorigin + linedirection * dist;
+}
+
+float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection)
+{
+ float a = dot(linedirection, linedirection);
+ float b = dot(linedirection, lineorigin);
+ float c = dot(lineorigin, lineorigin) - 1;
+
+ float dist = 1e15;
+ float determinant = b * b - a * c;
+ if (determinant >= 0) {
+ dist = (sqrt(determinant) - b) / a;
+ }
+
+ return dist;
+}
+
+float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
+{
+ /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
+ */
+ vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection;
+ vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
+ vec3 furthestplane = max(firstplane, secondplane);
+
+ return min_v3(furthestplane);
+}
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Other useful functions.
+ * \{ */
+
+void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
+{
+ vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ T = normalize(cross(UpVector, N));
+ B = cross(N, T);
+}
+
+/* ---- Encode / Decode Normal buffer data ---- */
+/* From http://aras-p.info/texts/CompactNormalStorage.html
+ * Using Method #4: Spheremap Transform */
+vec2 normal_encode(vec3 n, vec3 view)
+{
+ float p = sqrt(n.z * 8.0 + 8.0);
+ return n.xy / p + 0.5;
+}
+
+vec3 normal_decode(vec2 enc, vec3 view)
+{
+ vec2 fenc = enc * 4.0 - 2.0;
+ float f = dot(fenc, fenc);
+ float g = sqrt(1.0 - f / 4.0);
+ vec3 n;
+ n.xy = fenc * g;
+ n.z = 1 - f / 2;
+ return n;
+}
+
+/** \} */
diff --git a/source/blender/draw/intern/shaders/common_math_lib.glsl b/source/blender/draw/intern/shaders/common_math_lib.glsl
new file mode 100644
index 00000000000..a82e0b5a5e9
--- /dev/null
+++ b/source/blender/draw/intern/shaders/common_math_lib.glsl
@@ -0,0 +1,130 @@
+
+/* ---------------------------------------------------------------------- */
+/** \name Common Math Utilities
+ * \{ */
+
+#define M_PI 3.14159265358979323846 /* pi */
+#define M_2PI 6.28318530717958647692 /* 2*pi */
+#define M_PI_2 1.57079632679489661923 /* pi/2 */
+#define M_1_PI 0.318309886183790671538 /* 1/pi */
+#define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */
+#define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */
+#define FLT_MAX 3.402823e+38
+
+vec3 mul(mat3 m, vec3 v)
+{
+ return m * v;
+}
+mat3 mul(mat3 m1, mat3 m2)
+{
+ return m1 * m2;
+}
+vec3 transform_direction(mat4 m, vec3 v)
+{
+ return mat3(m) * v;
+}
+vec3 transform_point(mat4 m, vec3 v)
+{
+ return (m * vec4(v, 1.0)).xyz;
+}
+vec3 project_point(mat4 m, vec3 v)
+{
+ vec4 tmp = m * vec4(v, 1.0);
+ return tmp.xyz / tmp.w;
+}
+
+#define min3(a, b, c) min(a, min(b, c))
+#define min4(a, b, c, d) min(a, min3(b, c, d))
+#define min5(a, b, c, d, e) min(a, min4(b, c, d, e))
+#define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f))
+#define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g))
+#define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h))
+#define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i))
+
+#define max3(a, b, c) max(a, max(b, c))
+#define max4(a, b, c, d) max(a, max3(b, c, d))
+#define max5(a, b, c, d, e) max(a, max4(b, c, d, e))
+#define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f))
+#define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g))
+#define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h))
+#define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i))
+
+#define avg3(a, b, c) (a + b + c) * (1.0 / 3.0)
+#define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0)
+#define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0)
+#define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0)
+#define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0)
+#define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0)
+#define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0)
+
+/* clang-format off */
+float min_v2(vec2 v) { return min(v.x, v.y); }
+float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); }
+float min_v4(vec4 v) { return min(min(v.x, v.y), min(v.z, v.w)); }
+float max_v2(vec2 v) { return max(v.x, v.y); }
+float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
+float max_v4(vec4 v) { return max(max(v.x, v.y), max(v.z, v.w)); }
+
+float sum(vec2 v) { return dot(vec2(1.0), v); }
+float sum(vec3 v) { return dot(vec3(1.0), v); }
+float sum(vec4 v) { return dot(vec4(1.0), v); }
+
+float avg(vec2 v) { return dot(vec2(1.0 / 2.0), v); }
+float avg(vec3 v) { return dot(vec3(1.0 / 3.0), v); }
+float avg(vec4 v) { return dot(vec4(1.0 / 4.0), v); }
+/* clang-format on */
+
+#define saturate(a) clamp(a, 0.0, 1.0)
+
+float distance_squared(vec2 a, vec2 b)
+{
+ a -= b;
+ return dot(a, a);
+}
+
+float distance_squared(vec3 a, vec3 b)
+{
+ a -= b;
+ return dot(a, a);
+}
+
+float len_squared(vec3 a)
+{
+ return dot(a, a);
+}
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Fast Math
+ * \{ */
+
+/* [Drobot2014a] Low Level Optimizations for GCN */
+float fast_sqrt(float v)
+{
+ return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
+}
+
+vec2 fast_sqrt(vec2 v)
+{
+ return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
+}
+
+/* [Eberly2014] GPGPU Programming for Games and Science */
+float fast_acos(float v)
+{
+ float res = -0.156583 * abs(v) + M_PI_2;
+ res *= fast_sqrt(1.0 - abs(v));
+ return (v >= 0) ? res : M_PI - res;
+}
+
+vec2 fast_acos(vec2 v)
+{
+ vec2 res = -0.156583 * abs(v) + M_PI_2;
+ res *= fast_sqrt(1.0 - abs(v));
+ v.x = (v.x >= 0) ? res.x : M_PI - res.x;
+ v.y = (v.y >= 0) ? res.y : M_PI - res.y;
+ return v;
+}
+
+/** \} */
diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
new file mode 100644
index 00000000000..625e8bb1ff8
--- /dev/null
+++ b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
@@ -0,0 +1,39 @@
+
+/* NOTE: To be used with UNIFORM_RESOURCE_ID and INSTANCED_ATTR as define. */
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+in vec4 pos; /* Position and radius. */
+
+/* ---- Instanced attribs ---- */
+
+in vec3 pos_inst;
+in vec3 nor;
+
+mat3 pointcloud_get_facing_matrix(vec3 p)
+{
+ mat3 facing_mat;
+ facing_mat[2] = normalize(ViewMatrixInverse[3].xyz - p);
+ facing_mat[1] = normalize(cross(ViewMatrixInverse[0].xyz, facing_mat[2]));
+ facing_mat[0] = cross(facing_mat[1], facing_mat[2]);
+ return facing_mat;
+}
+
+/* Return world position and normal. */
+void pointcloud_get_pos_and_nor(out vec3 outpos, out vec3 outnor)
+{
+ vec3 p = point_object_to_world(pos.xyz);
+ mat3 facing_mat = pointcloud_get_facing_matrix(p);
+
+ float radius = dot(abs(mat3(ModelMatrix) * pos.www), vec3(1.0 / 3.0));
+ /* TODO(fclem) remove multiplication here. Here only for keeping the size correct for now. */
+ radius *= 0.01;
+ outpos = p + (facing_mat * pos_inst) * radius;
+ outnor = facing_mat * nor;
+}
+
+vec3 pointcloud_get_pos(void)
+{
+ vec3 outpos, outnor;
+ pointcloud_get_pos_and_nor(outpos, outnor);
+ return outpos;
+}
diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl
index 1054f4d11c9..a55d2cd8c1a 100644
--- a/source/blender/draw/intern/shaders/common_view_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_view_lib.glsl
@@ -14,10 +14,24 @@ layout(std140) uniform viewBlock
vec4 clipPlanes[6];
+ /* View frustum corners [NDC(-1.0, -1.0, -1.0) & NDC(1.0, 1.0, 1.0)].
+ * Fourth components are near and far values. */
+ vec4 ViewVecs[2];
+
/* TODO move it elsewhere. */
vec4 CameraTexCoFactors;
};
+#define ViewNear (ViewVecs[0].w)
+#define ViewFar (ViewVecs[1].w)
+
+#define cameraForward ViewMatrixInverse[2].xyz
+#define cameraPos ViewMatrixInverse[3].xyz
+#define cameraVec \
+ ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
+#define viewCameraVec \
+ ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0))
+
#ifdef world_clip_planes_calc_clip_distance
# undef world_clip_planes_calc_clip_distance
# define world_clip_planes_calc_clip_distance(p) \
@@ -100,10 +114,13 @@ uniform int resourceId;
/* Use this to declare and pass the value if
* the fragment shader uses the resource_id. */
-# define RESOURCE_ID_VARYING flat out int resourceIDFrag;
-# define RESOURCE_ID_VARYING_GEOM flat out int resourceIDGeom;
-# define PASS_RESOURCE_ID resourceIDFrag = resource_id;
-# define PASS_RESOURCE_ID_GEOM resourceIDGeom = resource_id;
+# ifdef USE_GEOMETRY_SHADER
+# define RESOURCE_ID_VARYING flat out int resourceIDGeom;
+# define PASS_RESOURCE_ID resourceIDGeom = resource_id;
+# else
+# define RESOURCE_ID_VARYING flat out int resourceIDFrag;
+# define PASS_RESOURCE_ID resourceIDFrag = resource_id;
+# endif
#endif
/* If used in a fragment / geometry shader, we pass
@@ -114,7 +131,7 @@ uniform int resourceId;
flat in int resourceIDGeom[];
# define resource_id resourceIDGeom
-# define PASS_RESOURCE_ID(i) resourceIDFrag = resource_id[i];
+# define PASS_RESOURCE_ID resourceIDFrag = resource_id[0];
#endif
#ifdef GPU_FRAGMENT_SHADER
@@ -167,10 +184,14 @@ uniform mat4 ModelMatrixInverse;
* Note: This is only valid because we are only using the mat3 of the ViewMatrixInverse.
* ViewMatrix * transpose(ModelMatrixInverse)
**/
-#define normal_object_to_view(n) (mat3(ViewMatrix) * (transpose(mat3(ModelMatrixInverse)) * n))
-#define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n)
-#define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n)
+#define NormalMatrix transpose(mat3(ModelMatrixInverse))
+#define NormalMatrixInverse transpose(mat3(ModelMatrix))
+
+#define normal_object_to_view(n) (mat3(ViewMatrix) * (NormalMatrix * n))
+#define normal_object_to_world(n) (NormalMatrix * n)
+#define normal_world_to_object(n) (NormalMatrixInverse * n)
#define normal_world_to_view(n) (mat3(ViewMatrix) * n)
+#define normal_view_to_world(n) (mat3(ViewMatrixInverse) * n)
#define point_object_to_ndc(p) (ViewProjectionMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0))
#define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz)
@@ -194,3 +215,78 @@ uniform mat4 ModelMatrixInverse;
#define DRW_BASE_FROM_DUPLI (1 << 2)
#define DRW_BASE_FROM_SET (1 << 3)
#define DRW_BASE_ACTIVE (1 << 4)
+
+/* ---- Opengl Depth conversion ---- */
+
+float linear_depth(bool is_persp, float z, float zf, float zn)
+{
+ if (is_persp) {
+ return (zn * zf) / (z * (zn - zf) + zf);
+ }
+ else {
+ return (z * 2.0 - 1.0) * zf;
+ }
+}
+
+float buffer_depth(bool is_persp, float z, float zf, float zn)
+{
+ if (is_persp) {
+ return (zf * (zn - z)) / (z * (zn - zf));
+ }
+ else {
+ return (z / (zf * 2.0)) + 0.5;
+ }
+}
+
+float get_view_z_from_depth(float depth)
+{
+ if (ProjectionMatrix[3][3] == 0.0) {
+ float d = 2.0 * depth - 1.0;
+ return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
+ }
+ else {
+ return ViewVecs[0].z + depth * ViewVecs[1].z;
+ }
+}
+
+float get_depth_from_view_z(float z)
+{
+ if (ProjectionMatrix[3][3] == 0.0) {
+ float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
+ return d * 0.5 + 0.5;
+ }
+ else {
+ return (z - ViewVecs[0].z) / ViewVecs[1].z;
+ }
+}
+
+vec2 get_uvs_from_view(vec3 view)
+{
+ vec4 ndc = ProjectionMatrix * vec4(view, 1.0);
+ return (ndc.xy / ndc.w) * 0.5 + 0.5;
+}
+
+vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
+{
+ if (ProjectionMatrix[3][3] == 0.0) {
+ return vec3(ViewVecs[0].xy + uvcoords * ViewVecs[1].xy, 1.0) * get_view_z_from_depth(depth);
+ }
+ else {
+ return ViewVecs[0].xyz + vec3(uvcoords, depth) * ViewVecs[1].xyz;
+ }
+}
+
+vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
+{
+ return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz;
+}
+
+vec3 get_view_vector_from_screen_uv(vec2 uv)
+{
+ if (ProjectionMatrix[3][3] == 0.0) {
+ return normalize(vec3(ViewVecs[0].xy + uv * ViewVecs[1].xy, 1.0));
+ }
+ else {
+ return vec3(0.0, 0.0, 1.0);
+ }
+}
diff --git a/source/blender/draw/intern/smaa_textures.h b/source/blender/draw/intern/smaa_textures.h
index 43b29340cac..7556f3a1952 100644
--- a/source/blender/draw/intern/smaa_textures.h
+++ b/source/blender/draw/intern/smaa_textures.h
@@ -26,8 +26,7 @@
* SOFTWARE.
*/
-#ifndef __SMAA_TEXTURES_H__
-#define __SMAA_TEXTURES_H__
+#pragma once
#define AREATEX_WIDTH 160
#define AREATEX_HEIGHT 560
@@ -15083,4 +15082,3 @@ static const unsigned char searchTexBytes[] = {
/* clang-format off */
-#endif /* __SMAA_TEXTURES_H__ */
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 0947023e071..53401e0c05a 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -322,9 +322,7 @@ static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale)
if (acf && acf->get_indent_level) {
return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
}
- else {
- return 0;
- }
+ return 0;
}
/* offset based on nodetree type */
@@ -514,11 +512,10 @@ static int acf_summary_setting_flag(bAnimContext *UNUSED(ac),
*neg = true;
return ADS_FLAG_SUMMARY_COLLAPSED;
}
- else {
- /* unsupported */
- *neg = false;
- return 0;
- }
+
+ /* unsupported */
+ *neg = false;
+ return 0;
}
/* get pointer to the setting */
@@ -538,11 +535,10 @@ static void *acf_summary_setting_ptr(bAnimListElem *ale,
/* return pointer to DopeSheet's flag */
return GET_ACF_FLAG_PTR(ads->flag, type);
}
- else {
- /* can't return anything useful - unsupported */
- *type = 0;
- return NULL;
- }
+
+ /* can't return anything useful - unsupported */
+ *type = 0;
+ return NULL;
}
/* all animation summary (DopeSheet only) type define */
@@ -2846,8 +2842,9 @@ static void *acf_dshair_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings se
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (hair->adt)
+ if (hair->adt) {
return GET_ACF_FLAG_PTR(hair->adt->flag, type);
+ }
return NULL;
default: /* unsupported */
@@ -2926,8 +2923,9 @@ static void *acf_dspointcloud_setting_ptr(bAnimListElem *ale,
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (pointcloud->adt)
+ if (pointcloud->adt) {
return GET_ACF_FLAG_PTR(pointcloud->adt->flag, type);
+ }
return NULL;
default: /* unsupported */
@@ -3006,8 +3004,9 @@ static void *acf_dsvolume_setting_ptr(bAnimListElem *ale,
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (volume->adt)
+ if (volume->adt) {
return GET_ACF_FLAG_PTR(volume->adt->flag, type);
+ }
return NULL;
default: /* unsupported */
@@ -3084,8 +3083,9 @@ static void *acf_dssimulation_setting_ptr(bAnimListElem *ale,
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (simulation->adt)
+ if (simulation->adt) {
return GET_ACF_FLAG_PTR(simulation->adt->flag, type);
+ }
return NULL;
default: /* unsupported */
@@ -3815,19 +3815,15 @@ static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac),
/* ok - we've got a solo track, and this is it */
return true;
}
- else {
- /* not ok - we've got a solo track, but this isn't it, so make it more obvious */
- return false;
- }
+ /* not ok - we've got a solo track, but this isn't it, so make it more obvious */
+ return false;
}
/* ok - no tracks are solo'd, and this isn't being tweaked */
return true;
}
- else {
- /* unsupported - this track is being tweaked */
- return false;
- }
+ /* unsupported - this track is being tweaked */
+ return false;
/* unsupported */
default:
@@ -3901,9 +3897,8 @@ static int acf_nlaaction_icon(bAnimListElem *ale)
if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
return ICON_ACTION_TWEAK;
}
- else {
- return ICON_ACTION;
- }
+
+ return ICON_ACTION;
}
/* Backdrop color for nla action channel
@@ -4157,9 +4152,8 @@ const bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale)
if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES)) {
return animchannelTypeInfo[ale->type];
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/* --------------------------- */
@@ -4227,9 +4221,7 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChanne
if (negflag) {
return ((*val) & flag) == 0;
}
- else {
- return ((*val) & flag) != 0;
- }
+ return ((*val) & flag) != 0;
}
case sizeof(short): /* short pointer for setting */
{
@@ -4238,9 +4230,7 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChanne
if (negflag) {
return ((*val) & flag) == 0;
}
- else {
- return ((*val) & flag) != 0;
- }
+ return ((*val) & flag) != 0;
}
case sizeof(char): /* char pointer for setting */
{
@@ -4249,9 +4239,7 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChanne
if (negflag) {
return ((*val) & flag) == 0;
}
- else {
- return ((*val) & flag) != 0;
- }
+ return ((*val) & flag) != 0;
}
}
}
@@ -4720,6 +4708,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
ReportList *reports = CTX_wm_reports(C);
Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
ToolSettings *ts = scene->toolsettings;
ListBase nla_cache = {NULL, NULL};
PointerRNA id_ptr, ptr;
@@ -4732,8 +4721,10 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
RNA_id_pointer_create(id, &id_ptr);
/* Get NLA context for value remapping */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, adt, (float)CFRA, false);
+ &nla_cache, &id_ptr, adt, &anim_eval_context, false);
/* get current frame and apply NLA-mapping to it (if applicable) */
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
@@ -4750,7 +4741,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
/* insert a keyframe for this F-Curve */
done = insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag);
+ reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, nla_context, flag);
if (done) {
if (adt->action != NULL) {
@@ -4774,23 +4765,26 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
ReportList *reports = CTX_wm_reports(C);
Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
ToolSettings *ts = scene->toolsettings;
ListBase nla_cache = {NULL, NULL};
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
eInsertKeyFlags flag = 0;
bool done = false;
- float cfra;
/* Get RNA pointer */
RNA_id_pointer_create((ID *)key, &id_ptr);
/* Get NLA context for value remapping */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, key->adt, (float)CFRA, false);
+ &nla_cache, &id_ptr, key->adt, &anim_eval_context, false);
/* get current frame and apply NLA-mapping to it (if applicable) */
- cfra = BKE_nla_tweakedit_remap(key->adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ const float remapped_frame = BKE_nla_tweakedit_remap(
+ key->adt, anim_eval_context.eval_time, NLATIME_CONVERT_UNMAP);
/* get flags for keyframing */
flag = ANIM_get_keyframing_flags(scene, true);
@@ -4803,13 +4797,21 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
FCurve *fcu = ED_action_fcurve_ensure(bmain, act, NULL, &ptr, rna_path, 0);
/* set the special 'replace' flag if on a keyframe */
- if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
+ if (fcurve_frame_has_keyframe(fcu, remapped_frame, 0)) {
flag |= INSERTKEY_REPLACE;
}
/* insert a keyframe for this F-Curve */
- done = insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag);
+ const AnimationEvalContext remapped_anim_eval_context = BKE_animsys_eval_context_construct_at(
+ &anim_eval_context, remapped_frame);
+ done = insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &remapped_anim_eval_context,
+ ts->keyframe_type,
+ nla_context,
+ flag);
if (done) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
@@ -4860,7 +4862,11 @@ static void achannel_setting_slider_nla_curve_cb(bContext *C,
}
/* insert a keyframe for this F-Curve */
- done = insert_keyframe_direct(reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, flag);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+ done = insert_keyframe_direct(
+ reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, flag);
if (done) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 1ca3452e8d8..d5f68e44ad8 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -505,9 +505,9 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac,
printf("ERROR: no channel matching the one changed was found\n");
return;
}
- else {
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale_setting);
+ {
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale_setting);
if (acf == NULL) {
printf("ERROR: no channel info for the changed channel\n");
return;
@@ -571,9 +571,7 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac,
* finished, so skip until we get to the parent of this level
*/
}
- else {
- continue;
- }
+ continue;
}
}
}
@@ -2314,7 +2312,7 @@ static int animchannels_clean_empty_exec(bContext *C, wmOperator *UNUSED(op))
nla_empty = false;
break;
}
- else if (nlt->strips.first == NULL) {
+ if (nlt->strips.first == NULL) {
/* this track is empty, but another one may still have stuff in it, so can't break yet */
nla_empty = true;
}
@@ -2812,10 +2810,9 @@ static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), const
if (rename_anim_channels(&ac, channel_index)) {
return OPERATOR_FINISHED;
}
- else {
- /* allow event to be handled by selectall operator */
- return OPERATOR_PASS_THROUGH;
- }
+
+ /* allow event to be handled by selectall operator */
+ return OPERATOR_PASS_THROUGH;
}
static void ANIM_OT_channels_rename(wmOperatorType *ot)
@@ -3372,10 +3369,9 @@ static int animchannels_channel_select_keys_invoke(bContext *C,
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
return OPERATOR_FINISHED;
}
- else {
- /* allow event to be handled by selectall operator */
- return OPERATOR_PASS_THROUGH;
- }
+
+ /* allow event to be handled by selectall operator */
+ return OPERATOR_PASS_THROUGH;
}
static void ANIM_OT_channel_select_keys(wmOperatorType *ot)
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index a2a1f7eb1d2..4cbea0ded15 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -473,9 +473,7 @@ float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short flag
if (flag & ANIM_UNITCONV_RESTORE) {
return DEG2RADF(1.0f); /* degrees to radians */
}
- else {
- return RAD2DEGF(1.0f); /* radians to degrees */
- }
+ return RAD2DEGF(1.0f); /* radians to degrees */
}
}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 9564b662b12..8280b58c21a 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -419,6 +419,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ac->markers = ED_context_get_markers(C);
}
ac->view_layer = CTX_data_view_layer(C);
+ ac->depsgraph = CTX_data_depsgraph_pointer(C);
ac->obact = (ac->view_layer->basact) ? ac->view_layer->basact->object : NULL;
ac->area = area;
ac->region = region;
@@ -426,7 +427,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ac->spacetype = (area) ? area->spacetype : 0;
ac->regiontype = (region) ? region->regiontype : 0;
- /* initialise default y-scale factor */
+ /* Initialize default y-scale factor. */
animedit_get_yscale_factor(ac);
/* get data context info */
@@ -571,7 +572,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
channel_data, channel_type, owner_id, fcurve_owner_id, ale_statement) \
if (filter_mode & ANIMFILTER_TMP_PEEK) \
return 1; \
- else { \
+ { \
bAnimListElem *ale = make_new_animlistelem( \
channel_data, channel_type, (ID *)owner_id, fcurve_owner_id); \
if (ale) { \
@@ -1169,10 +1170,8 @@ static bool name_matches_dopesheet_filter(bDopeSheet *ads, char *name)
/* if we have a match somewhere, this returns true */
return found;
}
- else {
- /* fallback/default - just case insensitive, but starts from start of word */
- return BLI_strcasestr(name, ads->searchstr) != NULL;
- }
+ /* fallback/default - just case insensitive, but starts from start of word */
+ return BLI_strcasestr(name, ads->searchstr) != NULL;
}
/* (Display-)Name-based F-Curve filtering
@@ -2603,8 +2602,9 @@ static size_t animdata_filter_ds_obdata(
{
Hair *hair = (Hair *)ob->data;
- if (ads->filterflag2 & ADS_FILTER_NOHAIR)
+ if (ads->filterflag2 & ADS_FILTER_NOHAIR) {
return 0;
+ }
type = ANIMTYPE_DSHAIR;
expanded = FILTER_HAIR_OBJD(hair);
@@ -2614,8 +2614,9 @@ static size_t animdata_filter_ds_obdata(
{
PointCloud *pointcloud = (PointCloud *)ob->data;
- if (ads->filterflag2 & ADS_FILTER_NOPOINTCLOUD)
+ if (ads->filterflag2 & ADS_FILTER_NOPOINTCLOUD) {
return 0;
+ }
type = ANIMTYPE_DSPOINTCLOUD;
expanded = FILTER_POINTS_OBJD(pointcloud);
@@ -2625,8 +2626,9 @@ static size_t animdata_filter_ds_obdata(
{
Volume *volume = (Volume *)ob->data;
- if (ads->filterflag2 & ADS_FILTER_NOVOLUME)
+ if (ads->filterflag2 & ADS_FILTER_NOVOLUME) {
return 0;
+ }
type = ANIMTYPE_DSVOLUME;
expanded = FILTER_VOLUME_OBJD(volume);
diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h
index 7fb5540fdf7..fb7b6b8983a 100644
--- a/source/blender/editors/animation/anim_intern.h
+++ b/source/blender/editors/animation/anim_intern.h
@@ -21,8 +21,7 @@
* \ingroup edanimation
*/
-#ifndef __ANIM_INTERN_H__
-#define __ANIM_INTERN_H__
+#pragma once
/* KeyingSets/Keyframing Interface ------------- */
@@ -77,5 +76,3 @@ void ANIM_OT_driver_button_remove(struct wmOperatorType *ot);
void ANIM_OT_driver_button_edit(struct wmOperatorType *ot);
void ANIM_OT_copy_driver_button(struct wmOperatorType *ot);
void ANIM_OT_paste_driver_button(struct wmOperatorType *ot);
-
-#endif /* __ANIM_INTERN_H__ */
diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c
index 3613ca9eeda..72103d68b05 100644
--- a/source/blender/editors/animation/anim_ipo_utils.c
+++ b/source/blender/editors/animation/anim_ipo_utils.c
@@ -59,7 +59,8 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
if (name == NULL) {
return icon;
}
- else if (ELEM(NULL, id, fcu, fcu->rna_path)) {
+
+ if (ELEM(NULL, id, fcu, fcu->rna_path)) {
if (fcu == NULL) {
strcpy(name, TIP_("<invalid>"));
}
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 46566feea91..bcdbf4c74f0 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -110,9 +110,7 @@ ListBase *ED_animcontext_get_markers(const bAnimContext *ac)
if (ac) {
return context_get_markers(ac->scene, ac->area);
}
- else {
- return NULL;
- }
+ return NULL;
}
/* --------------------------------- */
@@ -307,7 +305,7 @@ static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only
}
return;
}
- else if (ce->cfra > marker->frame) {
+ if (ce->cfra > marker->frame) {
break;
}
}
@@ -487,13 +485,11 @@ static int marker_get_icon_id(TimeMarker *marker, int flag)
(marker->flag & SELECT) ? ICON_PMARKER_SEL : ICON_PMARKER;
}
#ifdef DURIAN_CAMERA_SWITCH
- else if (marker->camera) {
+ if (marker->camera) {
return (marker->flag & SELECT) ? ICON_OUTLINER_OB_CAMERA : ICON_CAMERA_DATA;
}
#endif
- else {
- return (marker->flag & SELECT) ? ICON_MARKER_HLT : ICON_MARKER;
- }
+ return (marker->flag & SELECT) ? ICON_MARKER_HLT : ICON_MARKER;
}
static void draw_marker(
@@ -544,7 +540,7 @@ static void draw_markers_background(rctf *rect)
immUnbindProgram();
}
-static bool marker_is_in_frame_range(TimeMarker *marker, int frame_range[2])
+static bool marker_is_in_frame_range(TimeMarker *marker, const int frame_range[2])
{
if (marker->frame < frame_range[0]) {
return false;
@@ -1508,9 +1504,8 @@ static int ed_marker_rename_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+
+ return OPERATOR_CANCELLED;
}
static int ed_marker_rename_invoke(bContext *C, wmOperator *op, const wmEvent *event)
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 328e435877c..3b15cd794d8 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -1020,9 +1020,7 @@ static int add_driver_button_none(bContext *C, wmOperator *op, short mapping_typ
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static int add_driver_button_menu_exec(bContext *C, wmOperator *op)
@@ -1032,16 +1030,15 @@ static int add_driver_button_menu_exec(bContext *C, wmOperator *op)
/* Just create driver with no targets */
return add_driver_button_none(C, op, mapping_type);
}
- 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);
+ /* Create Driver using Eyedropper */
+ wmOperatorType *ot = WM_operatortype_find("UI_OT_eyedropper_driver", true);
- return OPERATOR_FINISHED;
- }
+ /* 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;
}
/* Show menu or create drivers */
@@ -1054,12 +1051,11 @@ static int add_driver_button_menu_invoke(bContext *C, wmOperator *op, const wmEv
/* Mapping Type is Set - Directly go into creating drivers */
return add_driver_button_menu_exec(C, op);
}
- else {
- /* Show menu */
- // TODO: This should get filtered by the enum filter
- /* important to execute in the region we're currently in */
- return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT);
- }
+
+ /* Show menu */
+ // TODO: This should get filtered by the enum filter
+ /* important to execute in the region we're currently in */
+ return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT);
}
static void UNUSED_FUNCTION(ANIM_OT_driver_button_add_menu)(wmOperatorType *ot)
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index eadaa449b92..1ecdf5accb8 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -515,8 +515,7 @@ static void draw_modifier__cycles(uiLayout *layout,
RNA_pointer_create(fcurve_owner_id, &RNA_FModifierCycles, fcm, &ptr);
/* split into 2 columns
- * NOTE: the mode comboboxes shouldn't get labels, otherwise there isn't enough room
- */
+ * NOTE: the mode combination-boxes shouldn't get labels, otherwise there isn't enough room. */
split = uiLayoutSplit(layout, 0.5f, false);
/* before range */
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index b921ba039be..c69f3ce3e3a 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -84,9 +84,7 @@ short compare_ak_cfraPtr(void *node, void *data)
if (val < ak->cfra) {
return -1;
}
- else {
- return 1;
- }
+ return 1;
}
/* --------------- */
@@ -106,18 +104,16 @@ static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt)
if (bezt->h1 == HD_AUTO_ANIM && bezt->h2 == HD_AUTO_ANIM) {
return KEYFRAME_HANDLE_AUTO_CLAMP;
}
- else if (ELEM(bezt->h1, HD_AUTO_ANIM, HD_AUTO) && ELEM(bezt->h2, HD_AUTO_ANIM, HD_AUTO)) {
+ if (ELEM(bezt->h1, HD_AUTO_ANIM, HD_AUTO) && ELEM(bezt->h2, HD_AUTO_ANIM, HD_AUTO)) {
return KEYFRAME_HANDLE_AUTO;
}
- else if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) {
+ if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) {
return KEYFRAME_HANDLE_VECTOR;
}
- else if (ELEM(HD_FREE, bezt->h1, bezt->h2)) {
+ if (ELEM(HD_FREE, bezt->h1, bezt->h2)) {
return KEYFRAME_HANDLE_FREE;
}
- else {
- return KEYFRAME_HANDLE_ALIGNED;
- }
+ return KEYFRAME_HANDLE_ALIGNED;
}
/* Determine if the keyframe is an extreme by comparing with neighbors.
@@ -337,9 +333,8 @@ static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTripleChain *bezt)
if (ELEM(NULL, keys, bezt)) {
return;
}
- else {
- BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt);
- }
+
+ BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt);
}
/* Add the given GPencil Frame to the given 'list' of Keyframes */
@@ -348,9 +343,8 @@ static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf)
if (ELEM(NULL, keys, gpf)) {
return;
}
- else {
- BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
- }
+
+ BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
}
/* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */
@@ -359,13 +353,12 @@ static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *mas
if (ELEM(NULL, keys, masklay_shape)) {
return;
}
- else {
- BLI_dlrbTree_add(keys,
- compare_ak_masklayshape,
- nalloc_ak_masklayshape,
- nupdate_ak_masklayshape,
- masklay_shape);
- }
+
+ BLI_dlrbTree_add(keys,
+ compare_ak_masklayshape,
+ nalloc_ak_masklayshape,
+ nupdate_ak_masklayshape,
+ masklay_shape);
}
/* ActKeyBlocks (Long Keyframes) ------------------------------------------ */
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 2dae4e8b4c5..f608038a95a 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -569,9 +569,7 @@ static short ok_bezier_selected(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
if (BEZT_ISSEL_ANY(bezt)) {
return KEYFRAME_OK_ALL;
}
- else {
- return 0;
- }
+ return 0;
}
static short ok_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
@@ -617,9 +615,7 @@ static short ok_bezier_region(KeyframeEditData *ked, BezTriple *bezt)
/* return ok flags */
return ok;
}
- else {
- return 0;
- }
+ return 0;
}
/**
@@ -654,9 +650,7 @@ static short ok_bezier_region_lasso(KeyframeEditData *ked, BezTriple *bezt)
/* return ok flags */
return ok;
}
- else {
- return 0;
- }
+ return 0;
}
static short ok_bezier_channel_lasso(KeyframeEditData *ked, BezTriple *bezt)
@@ -718,9 +712,7 @@ static short ok_bezier_region_circle(KeyframeEditData *ked, BezTriple *bezt)
/* return ok flags */
return ok;
}
- else {
- return 0;
- }
+ return 0;
}
static short ok_bezier_channel_circle(KeyframeEditData *ked, BezTriple *bezt)
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index fc9ec870496..64065d6d633 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -83,7 +83,7 @@ void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc)
if (abs(index) >= fcu->totvert) {
return;
}
- else if (index < 0) {
+ if (index < 0) {
index += fcu->totvert;
}
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 2aa8d468e2d..8c2f4216aa9 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -659,20 +659,17 @@ 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_DONTADD;
}
- else {
- float realVal;
- /* get real value of curve at that point */
- realVal = evaluate_fcurve(fcu, cFrame);
+ float realVal;
- /* compare whether it's the same as proposed */
- if (IS_EQF(realVal, nValue)) {
- return KEYNEEDED_DONTADD;
- }
- else {
- return KEYNEEDED_JUSTADD;
- }
+ /* 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;
}
+ return KEYNEEDED_JUSTADD;
}
/* new keyframe before prev beztriple? */
@@ -684,9 +681,8 @@ 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 {
- return KEYNEEDED_JUSTADD;
- }
+
+ return KEYNEEDED_JUSTADD;
}
}
else {
@@ -728,9 +724,8 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
if (IS_EQF(valA, nValue) && IS_EQF(valA, valB)) {
return KEYNEEDED_DELPREV;
}
- else {
- return KEYNEEDED_JUSTADD;
- }
+
+ return KEYNEEDED_JUSTADD;
}
/* ------------------ RNA Data-Access Functions ------------------ */
@@ -865,7 +860,8 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
printf("%s failed: NULL identifier\n", __func__);
return false;
}
- else if (strstr(identifier, "location")) {
+
+ if (strstr(identifier, "location")) {
searchtype = VISUALKEY_LOC;
}
else if (strstr(identifier, "rotation")) {
@@ -1036,7 +1032,8 @@ static float *visualkey_get_values(
*r_count = 3;
return buffer;
}
- else if (strstr(identifier, "rotation_quaternion")) {
+
+ if (strstr(identifier, "rotation_quaternion")) {
float mat3[3][3];
copy_m3_m4(mat3, tmat);
@@ -1045,14 +1042,16 @@ static float *visualkey_get_values(
*r_count = 4;
return buffer;
}
- else if (strstr(identifier, "rotation_axis_angle")) {
+
+ if (strstr(identifier, "rotation_axis_angle")) {
/* w = 0, x,y,z = 1,2,3 */
mat4_to_axis_angle(buffer + 1, buffer, tmat);
*r_count = 4;
return buffer;
}
- else if (strstr(identifier, "scale")) {
+
+ if (strstr(identifier, "scale")) {
mat4_to_size(buffer, tmat);
*r_count = 3;
@@ -1114,7 +1113,7 @@ static bool insert_keyframe_value(ReportList *reports,
PointerRNA *ptr,
PropertyRNA *prop,
FCurve *fcu,
- float cfra,
+ const AnimationEvalContext *anim_eval_context,
float curval,
eBezTriple_KeyframeType keytype,
eInsertKeyFlags flag)
@@ -1131,13 +1130,15 @@ static bool insert_keyframe_value(ReportList *reports,
return false;
}
+ float cfra = anim_eval_context->eval_time;
+
/* adjust frame on which to add keyframe */
if ((flag & INSERTKEY_DRIVER) && (fcu->driver)) {
PathResolvedRNA anim_rna;
if (RNA_path_resolved_create(ptr, prop, fcu->array_index, &anim_rna)) {
/* for making it easier to add corrective drivers... */
- cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, cfra);
+ cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, anim_eval_context);
}
else {
cfra = 0.0f;
@@ -1181,10 +1182,9 @@ static bool insert_keyframe_value(ReportList *reports,
return true;
}
- else {
- /* just insert keyframe */
- return insert_vert_fcurve(fcu, cfra, curval, keytype, flag) >= 0;
- }
+
+ /* just insert keyframe */
+ return insert_vert_fcurve(fcu, cfra, curval, keytype, flag) >= 0;
}
/* Secondary Keyframing API call:
@@ -1204,7 +1204,7 @@ bool insert_keyframe_direct(ReportList *reports,
PointerRNA ptr,
PropertyRNA *prop,
FCurve *fcu,
- float cfra,
+ const AnimationEvalContext *anim_eval_context,
eBezTriple_KeyframeType keytype,
struct NlaKeyframingContext *nla_context,
eInsertKeyFlags flag)
@@ -1239,10 +1239,9 @@ bool insert_keyframe_direct(ReportList *reports,
fcu->rna_path);
return false;
}
- else {
- /* property found, so overwrite 'ptr' to make later code easier */
- ptr = tmp_ptr;
- }
+
+ /* property found, so overwrite 'ptr' to make later code easier */
+ ptr = tmp_ptr;
}
/* update F-Curve flags to ensure proper behavior for property type */
@@ -1277,7 +1276,7 @@ bool insert_keyframe_direct(ReportList *reports,
MEM_freeN(values);
}
- return insert_keyframe_value(reports, &ptr, prop, fcu, cfra, curval, keytype, flag);
+ return insert_keyframe_value(reports, &ptr, prop, fcu, anim_eval_context, curval, keytype, flag);
}
/* Find or create the FCurve based on the given path, and insert the specified value into it. */
@@ -1289,7 +1288,7 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
const char group[],
const char rna_path[],
int array_index,
- float cfra,
+ const AnimationEvalContext *anim_eval_context,
float curval,
eBezTriple_KeyframeType keytype,
eInsertKeyFlags flag)
@@ -1323,11 +1322,33 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
update_autoflags_fcurve_direct(fcu, prop);
/* insert keyframe */
- return insert_keyframe_value(reports, ptr, prop, fcu, cfra, curval, keytype, flag);
+ return insert_keyframe_value(
+ reports, ptr, prop, fcu, anim_eval_context, curval, keytype, flag);
}
- else {
- return false;
+
+ return false;
+}
+
+static AnimationEvalContext nla_time_remap(const AnimationEvalContext *anim_eval_context,
+ PointerRNA *id_ptr,
+ AnimData *adt,
+ bAction *act,
+ ListBase *nla_cache,
+ NlaKeyframingContext **r_nla_context)
+{
+ if (adt && adt->action == act) {
+ /* Get NLA context for value remapping. */
+ *r_nla_context = BKE_animsys_get_nla_keyframing_context(
+ nla_cache, id_ptr, adt, anim_eval_context, false);
+
+ /* Apply NLA-mapping to frame. */
+ const float remapped_frame = BKE_nla_tweakedit_remap(
+ adt, anim_eval_context->eval_time, NLATIME_CONVERT_UNMAP);
+ return BKE_animsys_eval_context_construct_at(anim_eval_context, remapped_frame);
}
+
+ *r_nla_context = NULL;
+ return *anim_eval_context;
}
/**
@@ -1350,7 +1371,7 @@ int insert_keyframe(Main *bmain,
const char group[],
const char rna_path[],
int array_index,
- float cfra,
+ const AnimationEvalContext *anim_eval_context,
eBezTriple_KeyframeType keytype,
ListBase *nla_cache,
eInsertKeyFlags flag)
@@ -1397,15 +1418,8 @@ int insert_keyframe(Main *bmain,
/* apply NLA-mapping to frame to use (if applicable) */
adt = BKE_animdata_from_id(id);
-
- if (adt && adt->action == act) {
- /* Get NLA context for value remapping. */
- nla_context = BKE_animsys_get_nla_keyframing_context(
- nla_cache ? nla_cache : &tmp_nla_cache, &id_ptr, adt, cfra, false);
-
- /* Apply NLA-mapping to frame. */
- cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
- }
+ const AnimationEvalContext remapped_context = nla_time_remap(
+ anim_eval_context, &id_ptr, adt, act, nla_cache ? nla_cache : &tmp_nla_cache, &nla_context);
/* Obtain values to insert. */
float value_buffer[RNA_MAX_ARRAY_LENGTH];
@@ -1439,7 +1453,7 @@ int insert_keyframe(Main *bmain,
group,
rna_path,
array_index,
- cfra,
+ &remapped_context,
values[array_index],
keytype,
flag)) {
@@ -1462,7 +1476,7 @@ int insert_keyframe(Main *bmain,
group,
rna_path,
array_index,
- cfra,
+ &remapped_context,
values[array_index],
keytype,
flag);
@@ -1481,7 +1495,7 @@ int insert_keyframe(Main *bmain,
group,
rna_path,
array_index,
- cfra,
+ &remapped_context,
values[array_index],
keytype,
flag);
@@ -1499,7 +1513,7 @@ int insert_keyframe(Main *bmain,
group,
rna_path,
array_index,
- cfra,
+ &remapped_context,
values[array_index],
keytype,
flag);
@@ -1851,7 +1865,8 @@ static int insert_key_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
return OPERATOR_CANCELLED;
}
- else if (num_channels > 0) {
+
+ if (num_channels > 0) {
/* 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,
@@ -1961,13 +1976,12 @@ static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UN
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);
- }
+ /* 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)
@@ -2067,7 +2081,8 @@ static int delete_key_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
return OPERATOR_CANCELLED;
}
- else if (num_channels > 0) {
+
+ if (num_channels > 0) {
/* 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,
@@ -2378,7 +2393,8 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
PropertyRNA *prop = NULL;
char *path;
uiBut *but;
- float cfra = (float)CFRA;
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ CTX_data_depsgraph_pointer(C), (float)CFRA);
bool changed = false;
int index;
const bool all = RNA_boolean_get(op->ptr, "all");
@@ -2404,7 +2420,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
if (fcu) {
changed = insert_keyframe_direct(
- op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, 0);
+ op->reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, 0);
}
else {
BKE_report(op->reports,
@@ -2420,8 +2436,14 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
fcu = BKE_fcurve_find_by_rna_context_ui(C, &ptr, prop, index, NULL, NULL, &driven, &special);
if (fcu && driven) {
- changed = insert_keyframe_direct(
- op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, INSERTKEY_DRIVER);
+ changed = insert_keyframe_direct(op->reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context,
+ ts->keyframe_type,
+ NULL,
+ INSERTKEY_DRIVER);
}
}
else {
@@ -2464,7 +2486,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
group,
path,
index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
NULL,
flag) != 0);
@@ -2727,17 +2749,16 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
*/
return id_frame_has_keyframe(id, cfra, ANIMFILTER_KEYS_LOCAL);
}
- else {
- /* Normal Mode (or treat as being normal mode):
- *
- * Just in case the flags aren't set properly (i.e. only on/off is set, without a mode)
- * 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;
- }
+ /* Normal Mode (or treat as being normal mode):
+ *
+ * Just in case the flags aren't set properly (i.e. only on/off is set, without a mode)
+ * 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;
}
/* ******************************************* */
@@ -2773,7 +2794,10 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
}
/* Returns whether the current value of a given property differs from the interpolated value. */
-bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float frame)
+bool fcurve_is_changed(PointerRNA ptr,
+ PropertyRNA *prop,
+ FCurve *fcu,
+ const AnimationEvalContext *anim_eval_context)
{
PathResolvedRNA anim_rna;
anim_rna.ptr = ptr;
@@ -2784,7 +2808,7 @@ bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float fra
int count, index = fcu->array_index;
float *values = setting_get_rna_values(&ptr, prop, buffer, RNA_MAX_ARRAY_LENGTH, &count);
- float fcurve_val = calculate_fcurve(&anim_rna, fcu, frame);
+ float fcurve_val = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
float cur_val = (index >= 0 && index < count) ? values[index] : 0.0f;
if (values != buffer) {
@@ -2950,9 +2974,7 @@ bool ED_autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks
return true;
}
- else {
- return false;
- }
+ return false;
}
bool ED_autokeyframe_pchan(
@@ -2977,14 +2999,13 @@ bool ED_autokeyframe_pchan(
return true;
}
- else {
- /* add unkeyed tags */
- if (pchan->bone) {
- pchan->bone->flag |= BONE_UNKEYED;
- }
- return false;
+ /* add unkeyed tags */
+ if (pchan->bone) {
+ pchan->bone->flag |= BONE_UNKEYED;
}
+
+ return false;
}
/**
@@ -2994,6 +3015,9 @@ bool ED_autokeyframe_property(
bContext *C, Scene *scene, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, float cfra)
{
Main *bmain = CTX_data_main(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
ID *id;
bAction *action;
FCurve *fcu;
@@ -3014,7 +3038,8 @@ bool ED_autokeyframe_property(
ReportList *reports = CTX_wm_reports(C);
ToolSettings *ts = scene->toolsettings;
- changed = insert_keyframe_direct(reports, *ptr, prop, fcu, cfra, ts->keyframe_type, NULL, 0);
+ changed = insert_keyframe_direct(
+ reports, *ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, 0);
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
}
@@ -3027,7 +3052,7 @@ bool ED_autokeyframe_property(
ToolSettings *ts = scene->toolsettings;
changed = insert_keyframe_direct(
- reports, *ptr, prop, fcu, cfra, ts->keyframe_type, NULL, INSERTKEY_DRIVER);
+ reports, *ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, INSERTKEY_DRIVER);
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
}
@@ -3051,7 +3076,7 @@ bool ED_autokeyframe_property(
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path,
rnaindex,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
NULL,
flag) != 0;
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 89c7860982b..876740b889a 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -96,9 +96,8 @@ static bool keyingset_poll_activePath_edit(bContext *C)
if (scene->active_keyingset <= 0) {
return 0;
}
- else {
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
- }
+
+ 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));
@@ -158,13 +157,13 @@ static int remove_active_keyingset_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove");
return OPERATOR_CANCELLED;
}
- else if (scene->active_keyingset < 0) {
+
+ if (scene->active_keyingset < 0) {
BKE_report(op->reports, RPT_ERROR, "Cannot remove built in keying set");
return OPERATOR_CANCELLED;
}
- else {
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
- }
+
+ ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
/* free KeyingSet's data, then remove it from the scene */
BKE_keyingset_free(ks);
@@ -207,9 +206,8 @@ static int add_empty_ks_path_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to");
return OPERATOR_CANCELLED;
}
- else {
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
- }
+
+ 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");
@@ -414,13 +412,13 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from");
return OPERATOR_CANCELLED;
}
- else if (scene->active_keyingset < 0) {
+
+ if (scene->active_keyingset < 0) {
BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set");
return OPERATOR_CANCELLED;
}
- else {
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
- }
+
+ ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
if (ptr.owner_id && ptr.data && prop) {
path = RNA_path_from_ID_to_property(&ptr, prop);
@@ -688,9 +686,7 @@ KeyingSet *ANIM_scene_get_active_keyingset(const Scene *scene)
if (scene->active_keyingset > 0) {
return BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
}
- else {
- return BLI_findlink(&builtin_keyingsets, (-scene->active_keyingset) - 1);
- }
+ return BLI_findlink(&builtin_keyingsets, (-scene->active_keyingset) - 1);
}
/* Get the index of the Keying Set provided, for the given Scene */
@@ -722,9 +718,7 @@ int ANIM_scene_get_keyingset_index(Scene *scene, KeyingSet *ks)
if (index != -1) {
return -(index + 1);
}
- else {
- return 0;
- }
+ return 0;
}
/* Get Keying Set to use for Auto-Keyframing some transforms */
@@ -737,12 +731,10 @@ KeyingSet *ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *tra
if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (scene->active_keyingset)) {
return ANIM_scene_get_active_keyingset(scene);
}
- else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
+ if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
return ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_AVAILABLE_ID);
}
- else {
- return ANIM_builtin_keyingset_get_named(NULL, transformKSName);
- }
+ return ANIM_builtin_keyingset_get_named(NULL, transformKSName);
}
/* Menu of All Keying Sets ----------------------------- */
@@ -1128,6 +1120,9 @@ int ANIM_apply_keyingset(
/* for each possible index, perform operation
* - assume that arraylen is greater than index
*/
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
for (; i < arraylen; i++) {
/* action to take depends on mode */
if (mode == MODIFYKEY_MODE_INSERT) {
@@ -1138,7 +1133,7 @@ int ANIM_apply_keyingset(
groupname,
ksp->rna_path,
i,
- cfra,
+ &anim_eval_context,
keytype,
&nla_cache,
kflag2);
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index 895b4953992..016a00bda56 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -182,9 +182,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
if (flipbone == NULL) {
break;
}
- else {
- SWAP(EditBone *, flipbone, ebone);
- }
+ SWAP(EditBone *, flipbone, ebone);
}
newbone = ED_armature_ebone_add(arm, ebone->name);
@@ -1084,13 +1082,12 @@ static EditBone *get_symmetrized_bone(bArmature *arm, EditBone *bone)
if (bone == NULL) {
return NULL;
}
- else if (bone->temp.ebone != NULL) {
+ if (bone->temp.ebone != NULL) {
return bone->temp.ebone;
}
- else {
- EditBone *mirror = ED_armature_ebone_get_mirrored(arm->edbo, bone);
- return (mirror != NULL) ? mirror : bone;
- }
+
+ EditBone *mirror = ED_armature_ebone_get_mirrored(arm->edbo, bone);
+ return (mirror != NULL) ? mirror : bone;
}
/**
@@ -1417,9 +1414,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
if (flipbone == NULL) {
break;
}
- else {
- SWAP(EditBone *, flipbone, ebone);
- }
+ SWAP(EditBone *, flipbone, ebone);
}
totbone++;
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index a010fbd5e81..113fd54713e 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -728,7 +728,8 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No joints selected");
return OPERATOR_CANCELLED;
}
- else if (mixed_object_error) {
+
+ if (mixed_object_error) {
BKE_report(op->reports, RPT_ERROR, "Bones for different objects selected");
BLI_freelistN(&points);
return OPERATOR_CANCELLED;
@@ -1093,7 +1094,8 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
return OPERATOR_CANCELLED;
}
- else if (arm->flag & ARM_MIRROR_EDIT) {
+
+ 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
* (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 08d82bf13c9..9a04425a083 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -21,8 +21,7 @@
* \ingroup edarmature
*/
-#ifndef __ARMATURE_INTERN_H__
-#define __ARMATURE_INTERN_H__
+#pragma once
/* internal exports only */
struct wmOperatorType;
@@ -289,5 +288,3 @@ int bone_looper(struct Object *ob,
struct Bone *bone,
void *data,
int (*bone_func)(struct Object *, struct Bone *, void *));
-
-#endif /* __ARMATURE_INTERN_H__ */
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index f90d781baca..a737916e9a2 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -207,7 +207,7 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
id, dtar->rna_path, "pose.bones", old_name, new_name, 0, 0, false);
break; /* no need to try any more names for bone path */
}
- else if (STREQ(dtar->pchan_name, old_name)) {
+ if (STREQ(dtar->pchan_name, old_name)) {
/* Change target bone name */
BLI_strncpy(dtar->pchan_name, new_name, sizeof(dtar->pchan_name));
break; /* no need to try any more names for bone subtarget */
@@ -384,6 +384,7 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
BLI_remlink(curarm->edbo, curbone);
BLI_addtail(arm->edbo, curbone);
+ /* Pose channel is moved from one storage to another, its UUID is still unique. */
BLI_remlink(&opose->chanbase, pchan);
BLI_addtail(&pose->chanbase, pchan);
BKE_pose_channels_hash_free(opose);
@@ -636,7 +637,7 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
has_selected_bone = true;
break;
}
- else if (ebone->flag & (BONE_TIPSEL | BONE_ROOTSEL)) {
+ if (ebone->flag & (BONE_TIPSEL | BONE_ROOTSEL)) {
has_selected_any = true;
}
}
@@ -816,7 +817,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
return OPERATOR_CANCELLED;
}
- else if (arm->flag & ARM_MIRROR_EDIT) {
+ 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
* (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index ccd39429704..7fba855ffdb 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -263,10 +263,8 @@ static void *ed_armature_pick_bone_from_selectbuffer_impl(const bool is_editmode
*r_base = firstunSel_base;
return firstunSel;
}
- else {
- *r_base = firstSel_base;
- return firstSel;
- }
+ *r_base = firstSel_base;
+ return firstSel;
}
EditBone *ED_armature_pick_ebone_from_selectbuffer(Base **bases,
@@ -2253,10 +2251,9 @@ static int armature_shortest_path_pick_invoke(bContext *C, wmOperator *op, const
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports, RPT_WARNING, "Unselectable bone in chain");
- return OPERATOR_CANCELLED;
- }
+
+ BKE_report(op->reports, RPT_WARNING, "Unselectable bone in chain");
+ return OPERATOR_CANCELLED;
}
void ARMATURE_OT_shortest_path_pick(wmOperatorType *ot)
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 34f2b4f12be..04c1ec97841 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -229,7 +229,7 @@ EditBone *ED_armature_ebone_find_shared_parent(EditBone *ebone_child[], const ui
return NULL;
}
-void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3])
+void ED_armature_ebone_to_mat3(EditBone *ebone, float r_mat[3][3])
{
float delta[3], roll;
@@ -246,20 +246,20 @@ void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3])
}
}
- vec_roll_to_mat3_normalized(delta, roll, mat);
+ vec_roll_to_mat3_normalized(delta, roll, r_mat);
}
-void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4])
+void ED_armature_ebone_to_mat4(EditBone *ebone, float r_mat[4][4])
{
float m3[3][3];
ED_armature_ebone_to_mat3(ebone, m3);
- copy_m4_m3(mat, m3);
- copy_v3_v3(mat[3], ebone->head);
+ copy_m4_m3(r_mat, m3);
+ copy_v3_v3(r_mat[3], ebone->head);
}
-void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3])
+void ED_armature_ebone_from_mat3(EditBone *ebone, const float mat[3][3])
{
float vec[3], roll;
const float len = len_v3v3(ebone->head, ebone->tail);
@@ -270,7 +270,7 @@ void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3])
ebone->roll = roll;
}
-void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4])
+void ED_armature_ebone_from_mat4(EditBone *ebone, const float mat[4][4])
{
float mat3[3][3];
@@ -915,9 +915,7 @@ int ED_armature_ebone_selectflag_get(const EditBone *ebone)
return ((ebone->flag & (BONE_SELECTED | BONE_TIPSEL)) |
((ebone->parent->flag & BONE_TIPSEL) ? BONE_ROOTSEL : 0));
}
- else {
- return (ebone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL));
- }
+ return (ebone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL));
}
void ED_armature_ebone_selectflag_set(EditBone *ebone, int flag)
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 145071522ed..11066595e2e 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -640,13 +640,11 @@ static float heat_limit_weight(float weight)
if (weight < WEIGHT_LIMIT_END) {
return 0.0f;
}
- else if (weight < WEIGHT_LIMIT_START) {
+ if (weight < WEIGHT_LIMIT_START) {
t = (weight - WEIGHT_LIMIT_END) / (WEIGHT_LIMIT_START - WEIGHT_LIMIT_END);
return t * WEIGHT_LIMIT_START;
}
- else {
- return weight;
- }
+ return weight;
}
void heat_bone_weighting(Object *ob,
@@ -657,7 +655,7 @@ void heat_bone_weighting(Object *ob,
bDeformGroup **dgroupflip,
float (*root)[3],
float (*tip)[3],
- int *selected,
+ const int *selected,
const char **err_str)
{
LaplacianSystem *sys;
@@ -1238,7 +1236,7 @@ static float meshdeform_boundary_phi(const MeshDeformBind *mdb,
}
static float meshdeform_interp_w(MeshDeformBind *mdb,
- float *gridvec,
+ const float *gridvec,
float *UNUSED(vec),
int UNUSED(cagevert))
{
diff --git a/source/blender/editors/armature/meshlaplacian.h b/source/blender/editors/armature/meshlaplacian.h
index ef4759eab4a..0405e361b2f 100644
--- a/source/blender/editors/armature/meshlaplacian.h
+++ b/source/blender/editors/armature/meshlaplacian.h
@@ -20,8 +20,7 @@
* \ingroup edarmature
*/
-#ifndef __MESHLAPLACIAN_H__
-#define __MESHLAPLACIAN_H__
+#pragma once
//#define RIGID_DEFORM
@@ -56,7 +55,7 @@ void heat_bone_weighting(struct Object *ob,
struct bDeformGroup **dgroupflip,
float (*root)[3],
float (*tip)[3],
- int *selected,
+ const int *selected,
const char **error);
#ifdef RIGID_DEFORM
@@ -70,5 +69,3 @@ void rigid_deform_end(int cancel);
/* Harmonic Coordinates */
/* ED_mesh_deform_bind_callback(...) defined in ED_armature.h */
-
-#endif
diff --git a/source/blender/editors/armature/pose_group.c b/source/blender/editors/armature/pose_group.c
index c10e204e3a4..cb7c68178d9 100644
--- a/source/blender/editors/armature/pose_group.c
+++ b/source/blender/editors/armature/pose_group.c
@@ -177,11 +177,10 @@ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U
return OPERATOR_INTERFACE;
}
- else {
- /* just use the active group index, and call the exec callback for the calling operator */
- RNA_int_set(op->ptr, "type", pose->active_group);
- return op->type->exec(C, op);
- }
+
+ /* just use the active group index, and call the exec callback for the calling operator */
+ RNA_int_set(op->ptr, "type", pose->active_group);
+ return op->type->exec(C, op);
}
/* Assign selected pchans to the bone group that the user selects */
@@ -221,9 +220,7 @@ static int pose_group_assign_exec(bContext *C, wmOperator *op)
if (done) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void POSE_OT_group_assign(wmOperatorType *ot)
@@ -272,9 +269,7 @@ static int pose_group_unassign_exec(bContext *C, wmOperator *UNUSED(op))
if (done) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void POSE_OT_group_unassign(wmOperatorType *ot)
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index aa57fb5844d..c9d0478270a 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -87,12 +87,12 @@ static void action_set_activemarker(void *UNUSED(a), void *UNUSED(b), void *UNUS
* It acts as a kind of "glorified clipboard for poses", allowing for naming of poses.
*
* Features:
- * - PoseLibs are simply normal Actions.
- * - Each "pose" is simply a set of keyframes that occur on a particular frame.
- * - A set of TimeMarkers that belong to each Action, help 'label' where a 'pose' can be
+ * - Pose-libs are simply normal Actions.
+ * - Each "pose" is simply a set of key-frames that occur on a particular frame.
+ * - A set of #TimeMarker that belong to each Action, help 'label' where a 'pose' can be
* found in the Action.
- * - The Scrollwheel or PageUp/Down buttons when used in a special mode or after pressing/holding
- * [a modifier] key, cycles through the poses available for the active pose's poselib,
+ * - The Scroll-wheel or PageUp/Down buttons when used in a special mode or after pressing/holding
+ * [a modifier] key, cycles through the poses available for the active pose's pose-lib,
* allowing the animator to preview what action best suits that pose.
*/
/* ************************************************************* */
@@ -141,9 +141,7 @@ static int poselib_get_free_index(bAction *act)
if (low < high) {
return (low + 1);
}
- else {
- return (high + 1);
- }
+ return (high + 1);
}
/* returns the active pose for a poselib */
@@ -152,9 +150,7 @@ static TimeMarker *poselib_get_active_pose(bAction *act)
if ((act) && (act->active_marker)) {
return BLI_findlink(&act->markers, act->active_marker - 1);
}
- else {
- return NULL;
- }
+ return NULL;
}
/* Get object that Pose Lib should be found on */
@@ -173,9 +169,7 @@ static Object *get_poselib_object(bContext *C)
if (area && (area->spacetype == SPACE_PROPERTIES)) {
return ED_object_context(C);
}
- else {
- return BKE_object_pose_armature_get(CTX_data_active_object(C));
- }
+ return BKE_object_pose_armature_get(CTX_data_active_object(C));
}
/* Poll callback for operators that require existing PoseLib data (with poses) to work */
@@ -221,12 +215,10 @@ static bAction *poselib_validate(Main *bmain, Object *ob)
if (ELEM(NULL, ob, ob->pose)) {
return NULL;
}
- else if (ob->poselib == NULL) {
+ if (ob->poselib == NULL) {
return poselib_init_new(bmain, ob);
}
- else {
- return ob->poselib;
- }
+ return ob->poselib;
}
/* ************************************************************* */
@@ -697,12 +689,11 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, const wmEvent *eve
BKE_report(op->reports, RPT_ERROR, "Invalid index for pose");
return OPERATOR_CANCELLED;
}
- else {
- /* Use the existing name of the marker as the name,
- * and use the active marker as the one to rename. */
- RNA_enum_set(op->ptr, "pose", act->active_marker - 1);
- RNA_string_set(op->ptr, "name", marker->name);
- }
+
+ /* Use the existing name of the marker as the name,
+ * and use the active marker as the one to rename. */
+ 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);
@@ -1032,7 +1023,8 @@ static void poselib_backup_free_data(tPoseLib_PreviewData *pld)
* - gets the string to print in the header
* - this code is based on the code for extract_pose_from_action in blenkernel/action.c
*/
-static void poselib_apply_pose(tPoseLib_PreviewData *pld)
+static void poselib_apply_pose(tPoseLib_PreviewData *pld,
+ const AnimationEvalContext *anim_eval_context)
{
PointerRNA *ptr = &pld->rna_ptr;
bArmature *arm = pld->arm;
@@ -1058,6 +1050,8 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
group_ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
ked.f1 = ((float)frame) - 0.5f;
ked.f2 = ((float)frame) + 0.5f;
+ AnimationEvalContext anim_context_at_frame = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, frame);
/* start applying - only those channels which have a key at this point in time! */
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
@@ -1084,7 +1078,7 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
}
if (ok) {
- animsys_evaluate_action_group(ptr, act, agrp, (float)frame);
+ animsys_evaluate_action_group(ptr, act, agrp, &anim_context_at_frame);
}
}
}
@@ -1159,7 +1153,11 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
/* 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));
- poselib_apply_pose(pld);
+ struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, 0.0f /* poselib_apply_pose() determines its own evaluation time. */);
+ poselib_apply_pose(pld, &anim_eval_context);
}
else {
RNA_int_set(op->ptr, "pose_index", -2); /* -2 means don't apply any pose */
@@ -1755,9 +1753,7 @@ static int poselib_preview_exit(bContext *C, wmOperator *op)
if (ELEM(exit_state, PL_PREVIEW_CANCEL, PL_PREVIEW_ERROR)) {
return OPERATOR_CANCELLED;
}
- else {
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
/* Cancel previewing operation (called when exiting Blender) */
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 9525fcf2154..0e766e6a75f 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -1016,7 +1016,7 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex
BKE_report(reports, RPT_ERROR, "No active Keying Set to use");
return false;
}
- else if (ANIM_validate_keyingset(C, NULL, ks) != 0) {
+ if (ANIM_validate_keyingset(C, NULL, ks) != 0) {
if (ks->paths.first == NULL) {
if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
BKE_report(reports,
@@ -1129,9 +1129,7 @@ static int pose_select_grouped_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void POSE_OT_select_grouped(wmOperatorType *ot)
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index d9621dba730..e60270bc3f0 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -251,7 +251,7 @@ static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode)
*/
BLI_dlrbTree_init(&pso->keys);
- /* initialise numeric input */
+ /* Initialize numeric input. */
initNumInput(&pso->num);
pso->num.idx_max = 0; /* one axis */
pso->num.val_flag[0] |= NUM_NO_NEGATIVE;
@@ -1122,7 +1122,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
do_pose_update = true;
break;
}
- else if (event->val == KM_PRESS) {
+ if (event->val == KM_PRESS) {
switch (event->type) {
/* Transform Channel Limits */
/* XXX: Replace these hardcoded hotkeys with a modalmap that can be customised */
@@ -1307,11 +1307,10 @@ static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *ev
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
- /* initialise percentage so that it won't pop on first mouse move */
+ pso = op->customdata;
+
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
@@ -1328,9 +1327,8 @@ static int pose_slide_push_exec(bContext *C, wmOperator *op)
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
+
+ pso = op->customdata;
/* do common exec work */
return pose_slide_exec_common(C, op, pso);
@@ -1369,11 +1367,10 @@ static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *e
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
- /* initialise percentage so that it won't pop on first mouse move */
+ pso = op->customdata;
+
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
@@ -1390,9 +1387,8 @@ static int pose_slide_relax_exec(bContext *C, wmOperator *op)
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
+
+ pso = op->customdata;
/* do common exec work */
return pose_slide_exec_common(C, op, pso);
@@ -1430,11 +1426,10 @@ static int pose_slide_push_rest_invoke(bContext *C, wmOperator *op, const wmEven
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
- /* initialise percentage so that it won't pop on first mouse move */
+ pso = op->customdata;
+
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
@@ -1451,9 +1446,8 @@ static int pose_slide_push_rest_exec(bContext *C, wmOperator *op)
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
+
+ pso = op->customdata;
/* do common exec work */
return pose_slide_exec_common(C, op, pso);
@@ -1492,11 +1486,10 @@ static int pose_slide_relax_rest_invoke(bContext *C, wmOperator *op, const wmEve
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
- /* initialise percentage so that it won't pop on first mouse move */
+ pso = op->customdata;
+
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
@@ -1513,9 +1506,8 @@ static int pose_slide_relax_rest_exec(bContext *C, wmOperator *op)
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
+
+ pso = op->customdata;
/* do common exec work */
return pose_slide_exec_common(C, op, pso);
@@ -1554,11 +1546,10 @@ static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEven
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
- /* initialise percentage so that it won't pop on first mouse move */
+ pso = op->customdata;
+
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
@@ -1575,9 +1566,8 @@ static int pose_slide_breakdown_exec(bContext *C, wmOperator *op)
pose_slide_exit(op);
return OPERATOR_CANCELLED;
}
- else {
- pso = op->customdata;
- }
+
+ pso = op->customdata;
/* do common exec work */
return pose_slide_exec_common(C, op, pso);
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 1d2bf152777..a6cf8552ca4 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -1219,7 +1219,9 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
- float cframe = (float)CFRA;
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
@@ -1240,7 +1242,8 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
workob.adt = ob->adt;
workob.pose = dummyPose;
- BKE_animsys_evaluate_animdata(&workob.id, workob.adt, cframe, ADT_RECALC_ANIM, false);
+ BKE_animsys_evaluate_animdata(
+ &workob.id, workob.adt, &anim_eval_context, ADT_RECALC_ANIM, false);
/* copy back values, but on selected bones only */
for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
@@ -1259,10 +1262,8 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
MEM_freeN(dummyPose);
}
else {
- /* no animation, so just reset whole pose to rest pose
- * (cannot just restore for selected though)
- */
- BKE_pose_rest(ob->pose);
+ /* No animation, so just reset to the rest pose. */
+ BKE_pose_rest(ob->pose, only_select);
}
/* notifiers and updates */
@@ -1279,7 +1280,7 @@ void POSE_OT_user_transforms_clear(wmOperatorType *ot)
/* identifiers */
ot->name = "Clear User Transforms";
ot->idname = "POSE_OT_user_transforms_clear";
- ot->description = "Reset pose on selected bones to keyframed state";
+ ot->description = "Reset pose bone transforms to keyframed state";
/* callbacks */
ot->exec = pose_clear_user_transforms_exec;
diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h
index 7d0a2e5edbc..4426739e421 100644
--- a/source/blender/editors/curve/curve_intern.h
+++ b/source/blender/editors/curve/curve_intern.h
@@ -21,8 +21,7 @@
* \ingroup edcurve
*/
-#ifndef __CURVE_INTERN_H__
-#define __CURVE_INTERN_H__
+#pragma once
/* internal exports only */
struct EditNurb;
@@ -194,5 +193,3 @@ void ED_curve_nurb_vert_selected_find(
/* editcurve_paint.c */
void CURVE_OT_draw(struct wmOperatorType *ot);
-
-#endif /* __CURVE_INTERN_H__ */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index a39c8261b32..72ea52314b9 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1137,7 +1137,7 @@ int ED_curve_updateAnimPaths(Main *bmain, Curve *cu)
/** \name Edit Mode Conversion (Make & Load)
* \{ */
-static int *initialize_index_map(Object *obedit, int *r_old_totvert)
+static int *init_index_map(Object *obedit, int *r_old_totvert)
{
Curve *curve = (Curve *)obedit->data;
EditNurb *editnurb = curve->editnurb;
@@ -1225,7 +1225,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
if ((object->parent) && (object->parent->data == curve) &&
ELEM(object->partype, PARVERT1, PARVERT3)) {
if (old_to_new_map == NULL) {
- old_to_new_map = initialize_index_map(obedit, &old_totvert);
+ old_to_new_map = init_index_map(obedit, &old_totvert);
}
if (object->par1 < old_totvert) {
@@ -1254,7 +1254,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
int i, j;
if (old_to_new_map == NULL) {
- old_to_new_map = initialize_index_map(obedit, &old_totvert);
+ old_to_new_map = init_index_map(obedit, &old_totvert);
}
for (i = j = 0; i < hmd->totindex; i++) {
@@ -2436,12 +2436,12 @@ static void adduplicateflagNurb(
/* actvert in cyclicu selection */
break;
}
- else if (calc_duplicate_actvert(editnurb,
- newnurb,
- cu,
- starta,
- starta + newu,
- cu->actvert - starta + b * newnu->pntsu)) {
+ if (calc_duplicate_actvert(editnurb,
+ newnurb,
+ cu,
+ starta,
+ starta + newu,
+ cu->actvert - starta + b * newnu->pntsu)) {
/* actvert in 'current' iteration selection */
break;
}
@@ -4085,7 +4085,7 @@ static int curve_normals_make_consistent_exec(bContext *C, wmOperator *op)
void CURVE_OT_normals_make_consistent(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Recalc Normals";
+ ot->name = "Recalculate Handles";
ot->description = "Recalculate the direction of selected handles";
ot->idname = "CURVE_OT_normals_make_consistent";
@@ -4544,15 +4544,13 @@ static int make_segment_exec(bContext *C, wmOperator *op)
if (nu_select_num > 1) {
break;
}
- else {
- /* only 1 selected, not first or last, a little complex, but intuitive */
- if (nu->pntsv == 1) {
- if ((nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) {
- /* pass */
- }
- else {
- break;
- }
+ /* only 1 selected, not first or last, a little complex, but intuitive */
+ if (nu->pntsv == 1) {
+ if ((nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) {
+ /* pass */
+ }
+ else {
+ break;
}
}
}
@@ -5500,6 +5498,7 @@ static int ed_editcurve_addvert(Curve *cu,
if (nu) {
nurb_new = BKE_nurb_copy(nu, 1, 1);
+ memcpy(nurb_new->bezt, nu->bezt, sizeof(BezTriple));
}
else {
nurb_new = MEM_callocN(sizeof(Nurb), "BLI_editcurve_addvert new_bezt_nurb 2");
@@ -5593,9 +5592,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -6517,9 +6514,7 @@ static int curve_delete_exec(bContext *C, wmOperator *op)
if (changed_multi) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static const EnumPropertyItem curve_delete_type_items[] = {
diff --git a/source/blender/editors/curve/editcurve_query.c b/source/blender/editors/curve/editcurve_query.c
index 132f7e58e71..774065b06ff 100644
--- a/source/blender/editors/curve/editcurve_query.c
+++ b/source/blender/editors/curve/editcurve_query.c
@@ -191,7 +191,8 @@ void ED_curve_nurb_vert_selected_find(
*r_bezt = NULL;
return;
}
- else if (*r_bezt || *r_bp) {
+
+ if (*r_bezt || *r_bp) {
*r_bp = NULL;
*r_bezt = NULL;
}
@@ -214,7 +215,8 @@ void ED_curve_nurb_vert_selected_find(
*r_nu = NULL;
return;
}
- else if (*r_bezt || *r_bp) {
+
+ if (*r_bezt || *r_bp) {
*r_bp = NULL;
*r_bezt = NULL;
}
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index 73f970876b1..b60eb258916 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -66,12 +66,11 @@ bool select_beztriple(BezTriple *bezt, bool selstatus, short flag, eVisible_Type
bezt->f3 |= flag;
return true;
}
- else { /* deselects */
- bezt->f1 &= ~flag;
- bezt->f2 &= ~flag;
- bezt->f3 &= ~flag;
- return true;
- }
+ /* deselects */
+ bezt->f1 &= ~flag;
+ bezt->f2 &= ~flag;
+ bezt->f3 &= ~flag;
+ return true;
}
return false;
@@ -85,10 +84,8 @@ bool select_bpoint(BPoint *bp, bool selstatus, short flag, bool hidden)
bp->f1 |= flag;
return true;
}
- else {
- bp->f1 &= ~flag;
- return true;
- }
+ bp->f1 &= ~flag;
+ return true;
}
return false;
@@ -99,9 +96,7 @@ static bool swap_selection_beztriple(BezTriple *bezt)
if (bezt->f2 & SELECT) {
return select_beztriple(bezt, DESELECT, SELECT, VISIBLE);
}
- else {
- return select_beztriple(bezt, SELECT, SELECT, VISIBLE);
- }
+ return select_beztriple(bezt, SELECT, SELECT, VISIBLE);
}
static bool swap_selection_bpoint(BPoint *bp)
@@ -109,9 +104,7 @@ static bool swap_selection_bpoint(BPoint *bp)
if (bp->f1 & SELECT) {
return select_bpoint(bp, DESELECT, SELECT, VISIBLE);
}
- else {
- return select_bpoint(bp, SELECT, SELECT, VISIBLE);
- }
+ return select_bpoint(bp, SELECT, SELECT, VISIBLE);
}
bool ED_curve_nurb_select_check(View3D *v3d, Nurb *nu)
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 1bbd4b4a5bc..d78c543f94b 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -76,9 +76,9 @@ static int kill_selection(Object *obedit, int ins);
/** \name Internal Utilities
* \{ */
-static wchar_t findaccent(wchar_t char1, uint code)
+static char32_t findaccent(char32_t char1, uint code)
{
- wchar_t new = 0;
+ char32_t new = 0;
if (char1 == 'a') {
if (code == '`') {
@@ -373,9 +373,7 @@ static wchar_t findaccent(wchar_t char1, uint code)
if (new) {
return new;
}
- else {
- return char1;
- }
+ return char1;
}
static int insert_into_textbuf(Object *obedit, uintptr_t c)
@@ -403,9 +401,7 @@ static int insert_into_textbuf(Object *obedit, uintptr_t c)
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
static void text_update_edited(bContext *C, Object *obedit, int mode)
@@ -686,7 +682,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo");
cu->len = 0;
- cu->len_wchar = nchars - 1;
+ cu->len_char32 = nchars - 1;
cu->pos = 0;
s = cu->str;
@@ -707,7 +703,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
}
}
- cu->pos = cu->len_wchar;
+ cu->pos = cu->len_char32;
*s = '\0';
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, obedit);
@@ -887,9 +883,7 @@ static int font_select_all_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void FONT_OT_select_all(wmOperatorType *ot)
@@ -1015,10 +1009,9 @@ static bool paste_selection(Object *obedit, ReportList *reports)
if (font_paste_wchar(obedit, text_buf, len, info_buf)) {
return true;
}
- else {
- BKE_report(reports, RPT_WARNING, "Text too long");
- return false;
- }
+
+ BKE_report(reports, RPT_WARNING, "Text too long");
+ return false;
}
static int paste_text_exec(bContext *C, wmOperator *op)
@@ -1347,9 +1340,7 @@ static int change_spacing_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void FONT_OT_change_spacing(wmOperatorType *ot)
@@ -1670,7 +1661,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
uintptr_t ascii = event->ascii;
int alt = event->alt, shift = event->shift, ctrl = event->ctrl;
int event_type = event->type, event_val = event->val;
- wchar_t inserted_text[2] = {0};
+ char32_t inserted_text[2] = {0};
if (RNA_struct_property_is_set(op->ptr, "text")) {
return insert_text_exec(C, op);
@@ -1688,9 +1679,8 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if ((alt || ctrl || shift) == 0) {
return OPERATOR_PASS_THROUGH;
}
- else {
- ascii = 9;
- }
+
+ ascii = 9;
}
if (event_type == EVT_BACKSPACEKEY) {
@@ -1743,7 +1733,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* store as utf8 in RNA string */
char inserted_utf8[8] = {0};
- BLI_strncpy_wchar_as_utf8(inserted_utf8, inserted_text, sizeof(inserted_utf8));
+ BLI_str_utf32_as_utf8(inserted_utf8, inserted_text, sizeof(inserted_utf8));
RNA_string_set(op->ptr, "text", inserted_utf8);
}
@@ -1877,7 +1867,7 @@ void ED_curve_editfont_make(Object *obedit)
{
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
- int len_wchar;
+ int len_char32;
if (ef == NULL) {
ef = cu->editfont = MEM_callocN(sizeof(EditFont), "editfont");
@@ -1886,10 +1876,10 @@ void ED_curve_editfont_make(Object *obedit)
ef->textbufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditbufinfo");
}
- /* Convert the original text to wchar_t */
- len_wchar = BLI_str_utf8_as_utf32(ef->textbuf, cu->str, MAXTEXT + 4);
- BLI_assert(len_wchar == cu->len_wchar);
- ef->len = len_wchar;
+ /* Convert the original text to chat32_t. */
+ len_char32 = BLI_str_utf8_as_utf32(ef->textbuf, cu->str, MAXTEXT + 4);
+ BLI_assert(len_char32 == cu->len_char32);
+ ef->len = len_char32;
BLI_assert(ef->len >= 0);
memcpy(ef->textbufinfo, cu->strinfo, ef->len * sizeof(CharInfo));
@@ -1918,7 +1908,7 @@ void ED_curve_editfont_load(Object *obedit)
MEM_freeN(cu->str);
/* Calculate the actual string length in UTF-8 variable characters */
- cu->len_wchar = ef->len;
+ cu->len_char32 = ef->len;
cu->len = BLI_str_utf32_as_utf8_len(ef->textbuf);
/* Alloc memory for UTF-8 variable char length string */
@@ -1930,8 +1920,8 @@ void ED_curve_editfont_load(Object *obedit)
if (cu->strinfo) {
MEM_freeN(cu->strinfo);
}
- cu->strinfo = MEM_callocN((cu->len_wchar + 4) * sizeof(CharInfo), "texteditinfo");
- memcpy(cu->strinfo, ef->textbufinfo, cu->len_wchar * sizeof(CharInfo));
+ cu->strinfo = MEM_callocN((cu->len_char32 + 4) * sizeof(CharInfo), "texteditinfo");
+ memcpy(cu->strinfo, ef->textbufinfo, cu->len_char32 * sizeof(CharInfo));
/* Other vars */
cu->pos = ef->pos;
@@ -2290,9 +2280,7 @@ bool ED_curve_editfont_select_pick(
}
return true;
}
- else {
- return false;
- }
+ return false;
}
/** \} */
diff --git a/source/blender/editors/gizmo_library/gizmo_draw_utils.c b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
index 01e5a7eacfd..033673a99a8 100644
--- a/source/blender/editors/gizmo_library/gizmo_draw_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
@@ -29,7 +29,6 @@
#include "ED_view3d.h"
#include "GPU_batch.h"
-#include "GPU_glew.h"
#include "GPU_immediate.h"
#include "MEM_guardedalloc.h"
@@ -84,7 +83,7 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info,
/* We may want to re-visit this, for now disable
* since it causes issues leaving the GL state modified. */
#if 0
- glEnable(GL_CULL_FACE);
+ GPU_face_culling(GPU_CULL_BACK);
GPU_depth_test(true);
#endif
@@ -92,7 +91,7 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info,
#if 0
GPU_depth_test(false);
- glDisable(GL_CULL_FACE);
+ GPU_face_culling(GPU_CULL_NONE);
#endif
GPU_batch_discard(batch);
diff --git a/source/blender/editors/gizmo_library/gizmo_geometry.h b/source/blender/editors/gizmo_library/gizmo_geometry.h
index a5f61158f66..70f508df8b6 100644
--- a/source/blender/editors/gizmo_library/gizmo_geometry.h
+++ b/source/blender/editors/gizmo_library/gizmo_geometry.h
@@ -27,8 +27,7 @@
* called geom_xxx_gizmo.c
*/
-#ifndef __GIZMO_GEOMETRY_H__
-#define __GIZMO_GEOMETRY_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -48,5 +47,3 @@ extern GizmoGeomInfo wm_gizmo_geom_data_cube;
/* dial gizmo */
extern GizmoGeomInfo wm_gizmo_geom_data_dial;
-
-#endif /* __GIZMO_GEOMETRY_H__ */
diff --git a/source/blender/editors/gizmo_library/gizmo_library_intern.h b/source/blender/editors/gizmo_library/gizmo_library_intern.h
index 31decb71c77..f3670708543 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_intern.h
+++ b/source/blender/editors/gizmo_library/gizmo_library_intern.h
@@ -21,8 +21,7 @@
* \ingroup edgizmolib
*/
-#ifndef __GIZMO_LIBRARY_INTERN_H__
-#define __GIZMO_LIBRARY_INTERN_H__
+#pragma once
/**
* Data for common interactions. Used in gizmo_library_utils.c functions.
@@ -99,5 +98,3 @@ void wm_gizmo_geometryinfo_draw(const struct GizmoGeomInfo *info,
const float color[4]);
void wm_gizmo_vec_draw(
const float color[4], const float (*verts)[3], uint vert_count, uint pos, uint primitive_type);
-
-#endif /* __GIZMO_LIBRARY_INTERN_H__ */
diff --git a/source/blender/editors/gizmo_library/gizmo_library_utils.c b/source/blender/editors/gizmo_library/gizmo_library_utils.c
index 3902c112796..847f3e3916c 100644
--- a/source/blender/editors/gizmo_library/gizmo_library_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_library_utils.c
@@ -211,14 +211,13 @@ bool gizmo_window_project_2d(bContext *C,
}
return false;
}
- else {
- float co[3] = {mval[0], mval[1], 0.0f};
- float imat[4][4];
- invert_m4_m4(imat, mat);
- mul_m4_v3(imat, co);
- copy_v2_v2(r_co, co);
- return true;
- }
+
+ float co[3] = {mval[0], mval[1], 0.0f};
+ float imat[4][4];
+ invert_m4_m4(imat, mat);
+ mul_m4_v3(imat, co);
+ copy_v2_v2(r_co, co);
+ return true;
}
bool gizmo_window_project_3d(
@@ -245,12 +244,11 @@ bool gizmo_window_project_3d(
mul_m4_v3(mat, r_co);
return true;
}
- else {
- float co[3] = {mval[0], mval[1], 0.0f};
- float imat[4][4];
- invert_m4_m4(imat, mat);
- mul_m4_v3(imat, co);
- copy_v2_v2(r_co, co);
- return true;
- }
+
+ float co[3] = {mval[0], mval[1], 0.0f};
+ float imat[4][4];
+ invert_m4_m4(imat, mat);
+ mul_m4_v3(imat, co);
+ copy_v2_v2(r_co, co);
+ return true;
}
diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
index e6333d7d3e0..f31e004264c 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
@@ -88,7 +88,8 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const
const int draw_style = RNA_enum_get(arrow->gizmo.ptr, "draw_style");
const int draw_options = RNA_enum_get(arrow->gizmo.ptr, "draw_options");
- immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
+ immBindBuiltinProgram(select ? GPU_SHADER_3D_UNIFORM_COLOR :
+ GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
float viewport[4];
GPU_viewport_size_get_f(viewport);
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
index fd24149e9ea..406d66dfd8f 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
@@ -637,7 +637,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
}
if (select) {
- /* expand for hotspot */
+ /* Expand for hot-spot. */
const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE) {
@@ -694,7 +694,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
bool show = false;
if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) {
/* Only show if we're drawing the center handle
- * otherwise the entire rectangle is the hotspot. */
+ * otherwise the entire rectangle is the hot-spot. */
if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
show = true;
}
@@ -805,7 +805,7 @@ static int gizmo_cage2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
return -1;
}
- /* expand for hotspot */
+ /* Expand for hots-pot. */
const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
const int transform_flag = RNA_enum_get(gz->ptr, "transform");
@@ -999,7 +999,7 @@ static int gizmo_cage2d_modal(bContext *C,
if (data->dial == NULL) {
MUL_V2_V3_M4_FINAL(test_co, data->orig_matrix_offset[3]);
- data->dial = BLI_dial_initialize(test_co, FLT_EPSILON);
+ data->dial = BLI_dial_init(test_co, FLT_EPSILON);
MUL_V2_V3_M4_FINAL(test_co, data->orig_mouse);
BLI_dial_angle(data->dial, test_co);
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
index b0af8641767..8955a666e22 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
@@ -314,7 +314,7 @@ static void gizmo_cage3d_draw_intern(
}
if (select) {
- /* expand for hotspot */
+ /* Expand for hot-spot. */
#if 0
const float size[3] = {
size_real[0] + margin[0] / 2,
diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
index 262f4b78b95..5d7c3a9e717 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
@@ -461,10 +461,6 @@ static void gizmo_dial_draw_select(const bContext *C, wmGizmo *gz, int select_id
GPU_select_load_id(select_id);
dial_draw_intern(C, gz, true, false, clip_plane);
-
- if (clip_plane) {
- glDisable(GL_CLIP_DISTANCE0);
- }
}
static void gizmo_dial_draw(const bContext *C, wmGizmo *gz)
diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
index 20307e7f809..df479325027 100644
--- a/source/blender/editors/gpencil/annotate_draw.c
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -53,9 +53,8 @@
#include "WM_api.h"
-#include "BIF_glutil.h"
-
#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "GPU_state.h"
#include "ED_gpencil.h"
@@ -555,16 +554,13 @@ static void annotation_draw_strokes(const bGPDframe *gpf,
/* check which stroke-drawer to use */
if (dflag & GP_DRAWDATA_ONLY3D) {
const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY);
- int mask_orig = 0;
if (no_xray) {
- glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
- glDepthMask(0);
GPU_depth_test(true);
/* first arg is normally rv3d->dist, but this isn't
* available here and seems to work quite well without */
- bglPolygonOffset(1.0f, 1.0f);
+ GPU_polygon_offset(1.0f, 1.0f);
}
/* 3D Lines - OpenGL primitives-based */
@@ -578,10 +574,9 @@ static void annotation_draw_strokes(const bGPDframe *gpf,
}
if (no_xray) {
- glDepthMask(mask_orig);
GPU_depth_test(false);
- bglPolygonOffset(0.0, 0.0);
+ GPU_polygon_offset(0.0f, 0.0f);
}
}
else {
@@ -743,12 +738,18 @@ static void annotation_draw_data(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(true);
+ /* Do not write to depth (avoid self-occlusion). */
+ bool prev_depth_mask = GPU_depth_mask_get();
+ GPU_depth_mask(false);
+
/* draw! */
annotation_draw_data_layers(gpd, offsx, offsy, winx, winy, cfra, dflag);
/* turn off alpha blending, then smooth lines */
GPU_blend(false); // alpha blending
GPU_line_smooth(false); // smooth lines
+
+ GPU_depth_mask(prev_depth_mask);
}
/* if we have strokes for scenes (3d view)/clips (movie clip editor)
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index 6f700f6c4b8..ab83abb6b37 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -200,7 +200,7 @@ typedef struct tGPsdata {
/* Macros for accessing sensitivity thresholds... */
/* minimum number of pixels mouse should move before new point created */
-#define MIN_MANHATTEN_PX (U.gp_manhattendist)
+#define MIN_MANHATTAN_PX (U.gp_manhattandist)
/* minimum length of new segment before new point can be added */
#define MIN_EUCLIDEAN_PX (U.gp_euclideandist)
@@ -297,7 +297,7 @@ static bool annotation_stroke_filtermval(tGPsdata *p, const float mval[2], float
return false;
}
- if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) {
+ if ((dx > MIN_MANHATTAN_PX) && (dy > MIN_MANHATTAN_PX)) {
return true;
}
@@ -603,7 +603,7 @@ static short annotation_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(&pt->x, mval);
pt->pressure = pressure;
- /* unused for annotations, but initialise for easier conversions to GP Object */
+ /* Unused for annotations, but initialize for easier conversions to GP Object. */
pt->strength = 1.0f;
/* point time */
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 60fd52db707..9d11c1c2a25 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -60,9 +60,8 @@
#include "WM_api.h"
-#include "BIF_glutil.h"
-
#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "GPU_state.h"
#include "ED_gpencil.h"
@@ -306,6 +305,10 @@ static void gpencil_draw_strokes(tGPDdraw *tgpw)
GPU_program_point_size(true);
+ /* Do not write to depth (avoid self-occlusion). */
+ bool prev_depth_mask = GPU_depth_mask_get();
+ GPU_depth_mask(false);
+
bGPDstroke *gps_init = (tgpw->gps) ? tgpw->gps : tgpw->t_gpf->strokes.first;
for (bGPDstroke *gps = gps_init; gps; gps = gps->next) {
@@ -343,16 +346,13 @@ static void gpencil_draw_strokes(tGPDdraw *tgpw)
/* check which stroke-drawer to use */
if (tgpw->dflag & GP_DRAWDATA_ONLY3D) {
const int no_xray = (tgpw->dflag & GP_DRAWDATA_NO_XRAY);
- int mask_orig = 0;
if (no_xray) {
- glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
- glDepthMask(0);
GPU_depth_test(true);
/* first arg is normally rv3d->dist, but this isn't
* available here and seems to work quite well without */
- bglPolygonOffset(1.0f, 1.0f);
+ GPU_polygon_offset(1.0f, 1.0f);
}
/* 3D Stroke */
@@ -393,10 +393,9 @@ static void gpencil_draw_strokes(tGPDdraw *tgpw)
}
}
if (no_xray) {
- glDepthMask(mask_orig);
GPU_depth_test(false);
- bglPolygonOffset(0.0, 0.0);
+ GPU_polygon_offset(0.0f, 0.0f);
}
}
/* if only one stroke, exit from loop */
@@ -405,6 +404,7 @@ static void gpencil_draw_strokes(tGPDdraw *tgpw)
}
}
+ GPU_depth_mask(prev_depth_mask);
GPU_program_point_size(false);
}
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index e111ce44bc4..21d755bea52 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -48,6 +48,7 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
+#include "BKE_animsys.h"
#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_curve.h"
@@ -399,6 +400,7 @@ static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
PointerRNA ptr,
PropertyRNA *prop,
+ Depsgraph *depsgraph,
FCurve *fcu,
Curve *cu,
tGpTimingData *gtd,
@@ -453,8 +455,16 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
if ((cfra - last_valid_time) < MIN_TIME_DELTA) {
cfra = last_valid_time + MIN_TIME_DELTA;
}
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context,
+ BEZT_KEYTYPE_KEYFRAME,
+ NULL,
+ INSERTKEY_FAST);
last_valid_time = cfra;
}
else if (G.debug & G_DEBUG) {
@@ -466,8 +476,16 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
if ((cfra - last_valid_time) < MIN_TIME_DELTA) {
cfra = last_valid_time + MIN_TIME_DELTA;
}
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context,
+ BEZT_KEYTYPE_KEYFRAME,
+ NULL,
+ INSERTKEY_FAST);
last_valid_time = cfra;
}
else {
@@ -475,8 +493,16 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
* and also far enough from (not yet added!) end_stroke keyframe!
*/
if ((cfra - last_valid_time) > MIN_TIME_DELTA && (end_stroke_time - cfra) > MIN_TIME_DELTA) {
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_BREAKDOWN, NULL, INSERTKEY_FAST);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context,
+ BEZT_KEYTYPE_BREAKDOWN,
+ NULL,
+ INSERTKEY_FAST);
last_valid_time = cfra;
}
else if (G.debug & G_DEBUG) {
@@ -496,6 +522,7 @@ static void gpencil_stroke_path_animation(bContext *C,
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
bAction *act;
FCurve *fcu;
PointerRNA ptr;
@@ -537,8 +564,16 @@ static void gpencil_stroke_path_animation(bContext *C,
cu->ctime = 0.0f;
cfra = (float)gtd->start_frame;
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST);
+ AnimationEvalContext anim_eval_context_start = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context_start,
+ BEZT_KEYTYPE_KEYFRAME,
+ NULL,
+ INSERTKEY_FAST);
cu->ctime = cu->pathlen;
if (gtd->realtime) {
@@ -547,8 +582,16 @@ static void gpencil_stroke_path_animation(bContext *C,
else {
cfra = (float)gtd->end_frame;
}
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST);
+ AnimationEvalContext anim_eval_context_end = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context_end,
+ BEZT_KEYTYPE_KEYFRAME,
+ NULL,
+ INSERTKEY_FAST);
}
else {
/* Use actual recorded timing! */
@@ -575,7 +618,7 @@ static void gpencil_stroke_path_animation(bContext *C,
}
gpencil_stroke_path_animation_add_keyframes(
- reports, ptr, prop, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time);
+ reports, ptr, prop, depsgraph, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time);
BLI_rng_free(rng);
}
@@ -1664,7 +1707,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
0,
0,
32,
- "Bevel_Resolution",
+ "Bevel Resolution",
"Bevel resolution when depth is non-zero",
0,
32);
@@ -1679,7 +1722,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
1.0f,
0.0f,
1000.0f,
- "Radius Fac",
+ "Radius Factor",
"Multiplier for the points' radii (set from stroke width)",
0.0f,
10.0f);
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 96b0296a7de..348fb614977 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -861,6 +861,154 @@ void GPENCIL_OT_frame_clean_loose(wmOperatorType *ot)
INT_MAX);
}
+/* ********************* Clean Duplicated Frames ************************** */
+static bool gpencil_frame_is_equal(bGPDframe *gpf_a, bGPDframe *gpf_b)
+{
+ if ((gpf_a == NULL) || (gpf_b == NULL)) {
+ return false;
+ }
+ /* If the number of strokes is different, cannot be equal. */
+ int totstrokes_a = BLI_listbase_count(&gpf_a->strokes);
+ int totstrokes_b = BLI_listbase_count(&gpf_b->strokes);
+ if ((totstrokes_a == 0) || (totstrokes_b == 0) || (totstrokes_a != totstrokes_b)) {
+ return false;
+ }
+ /* Loop all strokes and check. */
+ bGPDstroke *gps_a = gpf_a->strokes.first;
+ bGPDstroke *gps_b = gpf_b->strokes.first;
+ for (int i = 0; i < totstrokes_a; i++) {
+ /* If the number of points is different, cannot be equal. */
+ if (gps_a->totpoints != gps_b->totpoints) {
+ return false;
+ }
+ /* Check other variables. */
+ if (!equals_v4v4(gps_a->vert_color_fill, gps_b->vert_color_fill)) {
+ return false;
+ }
+ if (gps_a->thickness != gps_b->thickness) {
+ return false;
+ }
+ if (gps_a->mat_nr != gps_b->mat_nr) {
+ return false;
+ }
+ if (gps_a->caps[0] != gps_b->caps[0]) {
+ return false;
+ }
+ if (gps_a->caps[1] != gps_b->caps[1]) {
+ return false;
+ }
+ if (gps_a->hardeness != gps_b->hardeness) {
+ return false;
+ }
+ if (!equals_v2v2(gps_a->aspect_ratio, gps_b->aspect_ratio)) {
+ return false;
+ }
+ if (gps_a->uv_rotation != gps_b->uv_rotation) {
+ return false;
+ }
+ if (!equals_v2v2(gps_a->uv_translation, gps_b->uv_translation)) {
+ return false;
+ }
+ if (gps_a->uv_scale != gps_b->uv_scale) {
+ return false;
+ }
+
+ /* Loop points and check if equals or not. */
+ for (int p = 0; p < gps_a->totpoints; p++) {
+ bGPDspoint *pt_a = &gps_a->points[p];
+ bGPDspoint *pt_b = &gps_b->points[p];
+ if (!equals_v3v3(&pt_a->x, &pt_b->x)) {
+ return false;
+ }
+ if (pt_a->pressure != pt_b->pressure) {
+ return false;
+ }
+ if (pt_a->strength != pt_b->strength) {
+ return false;
+ }
+ if (pt_a->uv_fac != pt_b->uv_fac) {
+ return false;
+ }
+ if (pt_a->uv_rot != pt_b->uv_rot) {
+ return false;
+ }
+ if (!equals_v4v4(pt_a->vert_color, pt_b->vert_color)) {
+ return false;
+ }
+ }
+
+ /* Look at next pair of strokes. */
+ gps_a = gps_a->next;
+ gps_b = gps_b->next;
+ }
+
+ return true;
+}
+
+static int gpencil_frame_clean_duplicate_exec(bContext *C, wmOperator *op)
+{
+#define SELECTED 1
+
+ bool changed = false;
+ Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = (bGPdata *)ob->data;
+ const int type = RNA_enum_get(op->ptr, "type");
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* Only editable and visible layers are considered. */
+ if (BKE_gpencil_layer_is_editable(gpl) && (gpl->frames.first != NULL)) {
+ bGPDframe *gpf = gpl->frames.first;
+
+ if ((type == SELECTED) && ((gpf->flag & GP_FRAME_SELECT) == 0)) {
+ continue;
+ }
+
+ while (gpf != NULL) {
+ if (gpencil_frame_is_equal(gpf, gpf->next)) {
+ /* Remove frame. */
+ BKE_gpencil_layer_frame_delete(gpl, gpf->next);
+ /* Tag for recalc. */
+ changed = true;
+ }
+ else {
+ gpf = gpf->next;
+ }
+ }
+ }
+ }
+
+ /* notifiers */
+ if (changed) {
+ DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_frame_clean_duplicate(wmOperatorType *ot)
+{
+ static const EnumPropertyItem clean_type[] = {
+ {0, "ALL", 0, "All Frames", ""},
+ {1, "SELECTED", 0, "Selected Frames", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* identifiers */
+ ot->name = "Clean Duplicated Frames";
+ ot->idname = "GPENCIL_OT_frame_clean_duplicate";
+ ot->description = "Remove any duplicated frame";
+
+ /* callbacks */
+ ot->exec = gpencil_frame_clean_duplicate_exec;
+ ot->poll = gpencil_active_layer_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "type", clean_type, 0, "Type", "");
+}
+
/* *********************** Hide Layers ******************************** */
static int gpencil_hide_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index f8010edfcdd..9658dc04b52 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -94,6 +94,8 @@
/** \name Stroke Edit Mode Management
* \{ */
+static void gpencil_flip_stroke(bGPDstroke *gps);
+
/* poll callback for all stroke editing operators */
static bool gpencil_stroke_edit_poll(bContext *C)
{
@@ -1126,6 +1128,11 @@ static void gpencil_add_move_points(bGPDframe *gpf, bGPDstroke *gps)
pt->flag |= GP_SPOINT_SELECT;
}
+ /* Flip stroke if it was only one point to consider extrude point as last point. */
+ if (gps->totpoints == 2) {
+ gpencil_flip_stroke(gps);
+ }
+
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gps);
@@ -1764,7 +1771,7 @@ static int gpencil_blank_frame_add_exec(bContext *C, wmOperator *op)
const bool all_layers = RNA_boolean_get(op->ptr, "all_layers");
- /* Initialise datablock and an active layer if nothing exists yet */
+ /* Initialize data-block and an active layer if nothing exists yet. */
if (ELEM(NULL, gpd, active_gpl)) {
/* Let's just be lazy, and call the "Add New Layer" operator,
* which sets everything up as required. */
@@ -4283,11 +4290,14 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_prev, dupflag);
ob_dst = base_new->object;
ob_dst->mode = OB_MODE_OBJECT;
- /* create new grease pencil datablock */
+ /* Duplication will increment #bGPdata user-count, but since we create a new grease-pencil
+ * data-block for ob_dst (which gets its own user automatically),
+ * we have to decrement the user-count again. */
gpd_dst = BKE_gpencil_data_addnew(bmain, gpd_src->id.name + 2);
+ id_us_min(ob_dst->data);
ob_dst->data = (bGPdata *)gpd_dst;
- /* loop old datablock and separate parts */
+ /* Loop old data-block and separate parts. */
if ((mode == GP_SEPARATE_POINT) || (mode == GP_SEPARATE_STROKE)) {
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
gpl_dst = NULL;
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 8c901da100d..7db25ef817b 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -104,6 +104,8 @@ typedef struct tGPDfill {
struct bGPdata *gpd;
/** current material */
struct Material *mat;
+ /** current brush */
+ struct Brush *brush;
/** layer */
struct bGPDlayer *gpl;
/** frame */
@@ -233,6 +235,8 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
Object *ob = tgpf->ob;
bGPdata *gpd = tgpf->gpd;
+ Brush *brush = tgpf->brush;
+ BrushGpencilSettings *brush_settings = brush->gpencil_settings;
tGPDdraw tgpw;
tgpw.rv3d = tgpf->rv3d;
@@ -249,6 +253,12 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
GPU_blend(true);
+ bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
+ BLI_assert(gpl_active != NULL);
+
+ const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active);
+ BLI_assert(gpl_active_index >= 0);
+
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* calculate parent position */
BKE_gpencil_parent_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
@@ -258,6 +268,44 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
continue;
}
+ /* Decide if layer is included or not depending of the layer mode. */
+ const int gpl_index = BLI_findindex(&gpd->layers, gpl);
+ switch (brush_settings->fill_layer_mode) {
+ case GP_FILL_GPLMODE_ACTIVE: {
+ if (gpl_index != gpl_active_index) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ABOVE: {
+ if (gpl_index != gpl_active_index + 1) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_BELOW: {
+ if (gpl_index != gpl_active_index - 1) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ALL_ABOVE: {
+ if (gpl_index <= gpl_active_index) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ALL_BELOW: {
+ if (gpl_index >= gpl_active_index) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_VISIBLE:
+ default:
+ break;
+ }
+
/* if active layer and no keyframe, create a new one */
if (gpl == tgpf->gpl) {
if ((gpl->actframe == NULL) || (gpl->actframe->framenum != tgpf->active_cfra)) {
@@ -398,8 +446,8 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
GPU_matrix_push();
GPU_matrix_identity_set();
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
+ GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT);
ED_view3d_update_viewmat(
tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->region, NULL, winmat, NULL, true);
@@ -416,10 +464,10 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
/* create a image to see result of template */
if (ibuf->rect_float) {
- GPU_offscreen_read_pixels(offscreen, GL_FLOAT, ibuf->rect_float);
+ GPU_offscreen_read_pixels(offscreen, GPU_DATA_FLOAT, ibuf->rect_float);
}
else if (ibuf->rect) {
- GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, ibuf->rect);
+ GPU_offscreen_read_pixels(offscreen, GPU_DATA_UNSIGNED_BYTE, ibuf->rect);
}
if (ibuf->rect_float && ibuf->rect) {
IMB_rect_from_float(ibuf);
@@ -1247,6 +1295,7 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
/* save filling parameters */
Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
+ tgpf->brush = brush;
tgpf->flag = brush->gpencil_settings->flag;
tgpf->fill_leak = brush->gpencil_settings->fill_leak;
tgpf->fill_threshold = brush->gpencil_settings->fill_threshold;
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index bd697dbc768..fa75c2a7cee 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -21,8 +21,7 @@
* \ingroup edgpencil
*/
-#ifndef __GPENCIL_INTERN_H__
-#define __GPENCIL_INTERN_H__
+#pragma once
#include "DNA_vec_types.h"
@@ -485,6 +484,7 @@ void GPENCIL_OT_active_frames_delete_all(struct wmOperatorType *ot);
void GPENCIL_OT_frame_duplicate(struct wmOperatorType *ot);
void GPENCIL_OT_frame_clean_fill(struct wmOperatorType *ot);
void GPENCIL_OT_frame_clean_loose(struct wmOperatorType *ot);
+void GPENCIL_OT_frame_clean_duplicate(struct wmOperatorType *ot);
void GPENCIL_OT_convert(struct wmOperatorType *ot);
void GPENCIL_OT_bake_mesh_animation(struct wmOperatorType *ot);
@@ -731,5 +731,3 @@ struct GP_EditableStrokes_Iter {
(void)0
/* ****************************************************** */
-
-#endif /* __GPENCIL_INTERN_H__ */
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 179f621205b..3a7029b1288 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -136,15 +136,17 @@ static void gpencil_interpolate_free_temp_strokes(bGPDframe *gpf)
}
/* Helper: Untag all strokes. */
-static void gpencil_interpolate_untag_strokes(bGPDframe *gpf)
+static void gpencil_interpolate_untag_strokes(bGPDlayer *gpl)
{
- if (gpf == NULL) {
+ if (gpl == NULL) {
return;
}
- LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- if (gps->flag & GP_STROKE_TAG) {
- gps->flag &= ~GP_STROKE_TAG;
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ if (gps->flag & GP_STROKE_TAG) {
+ gps->flag &= ~GP_STROKE_TAG;
+ }
}
}
}
@@ -263,15 +265,6 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
/* set layers */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
tGPDinterpolate_layer *tgpil;
-
- /* Untag strokes to be sure nothing is pending. This must be done for
- * all layer because it could be anything tagged and it would be removed
- * at the end of the process when all tagged strokes are removed. */
- if (gpl->actframe != NULL) {
- gpencil_interpolate_untag_strokes(gpl->actframe);
- gpencil_interpolate_untag_strokes(gpl->actframe->next);
- }
-
/* all layers or only active */
if (!(tgpi->flag & GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS) && (gpl != active_gpl)) {
continue;
@@ -483,6 +476,11 @@ static bool gpencil_interpolate_set_init_values(bContext *C, wmOperator *op, tGP
/* set layers */
gpencil_interpolate_set_points(C, tgpi);
+ /* Untag strokes to be sure nothing is pending due any canceled process. */
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &tgpi->gpd->layers) {
+ gpencil_interpolate_untag_strokes(gpl);
+ }
+
return 1;
}
@@ -606,6 +604,8 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
/* make copy of source stroke, then adjust pointer to points too */
gps_dst = BKE_gpencil_stroke_duplicate(gps_src, true);
+ gps_dst->flag &= ~GP_STROKE_TAG;
+
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gps_dst);
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
index 763f5687edf..11f42f7d3ac 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -82,7 +82,7 @@ static bool gpencil_bake_mesh_animation_poll(bContext *C)
}
typedef struct GpBakeOb {
- struct GPBakelist *next, *prev;
+ struct GpBakeOb *next, *prev;
Object *ob;
} GpBakeOb;
@@ -104,9 +104,10 @@ static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *o
free_object_duplilist(lb);
}
-static void gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene, ListBase *list)
+static bool gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene, ListBase *list)
{
GpBakeOb *elem = NULL;
+ bool simple_material = false;
/* Add active object. In some files this could not be in selected array. */
Object *obact = CTX_data_active_object(C);
@@ -119,6 +120,7 @@ static void gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene
/* Add duplilist. */
else if (obact->type == OB_EMPTY) {
gpencil_bake_duplilist(depsgraph, scene, obact, list);
+ simple_material |= true;
}
/* Add other selected objects. */
@@ -139,6 +141,8 @@ static void gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene
}
}
CTX_DATA_END;
+
+ return simple_material;
}
static void gpencil_bake_free_ob_list(ListBase *list)
@@ -158,7 +162,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
Object *ob_gpencil = NULL;
ListBase list = {NULL, NULL};
- gpencil_bake_ob_list(C, depsgraph, scene, &list);
+ const bool simple_material = gpencil_bake_ob_list(C, depsgraph, scene, &list);
/* Cannot check this in poll because the active object changes. */
if (list.first == NULL) {
@@ -260,7 +264,8 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
ob_eval->obmat,
frame_offset,
use_seams,
- use_faces);
+ use_faces,
+ simple_material);
/* Reproject all untaged created strokes. */
if (project_type != GP_REPROJECT_KEEP) {
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index efee05f7da3..3892f451e18 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -600,6 +600,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_frame_duplicate);
WM_operatortype_append(GPENCIL_OT_frame_clean_fill);
WM_operatortype_append(GPENCIL_OT_frame_clean_loose);
+ WM_operatortype_append(GPENCIL_OT_frame_clean_duplicate);
WM_operatortype_append(GPENCIL_OT_convert);
WM_operatortype_append(GPENCIL_OT_bake_mesh_animation);
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index d3ff7f8a4d2..9ec04bbb553 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -268,7 +268,7 @@ typedef struct tGPsdata {
/* Macros for accessing sensitivity thresholds... */
/* minimum number of pixels mouse should move before new point created */
-#define MIN_MANHATTEN_PX (U.gp_manhattendist)
+#define MIN_MANHATTEN_PX (U.gp_manhattandist)
/* minimum length of new segment before new point can be added */
#define MIN_EUCLIDEAN_PX (U.gp_euclideandist)
@@ -836,7 +836,7 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
}
/* color strength */
- if (brush_settings->flag & GP_BRUSH_USE_STENGTH_PRESSURE) {
+ if (brush_settings->flag & GP_BRUSH_USE_STRENGTH_PRESSURE) {
pt->strength *= BKE_curvemapping_evaluateF(brush_settings->curve_strength, 0, pressure);
CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
}
@@ -1817,15 +1817,15 @@ static void gpencil_init_drawing_brush(bContext *C, tGPsdata *p)
changed = true;
}
/* Be sure curves are initializated. */
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_sensitivity);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_strength);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_jitter);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_pressure);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_strength);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_uv);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_hue);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_saturation);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_value);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_sensitivity);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_strength);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_jitter);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_pressure);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_strength);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_uv);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_hue);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_saturation);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_value);
/* assign to temp tGPsdata */
p->brush = paint->brush;
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index f206f5c832a..f44dbd1a752 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -412,7 +412,8 @@ static void gpencil_primitive_status_indicators(bContext *C, tGPDprimitive *tgpi
}
else if (tgpi->type == GP_STROKE_POLYLINE) {
BLI_strncpy(msg_str,
- TIP_("Line: ESC to cancel, LMB to set, Enter/MMB to confirm, Shift to align"),
+ TIP_("Polyline: ESC to cancel, LMB to set, Enter/MMB to confirm, WHEEL/+- to "
+ "adjust subdivision number, Shift to align"),
UI_MAX_DRAW_STR);
}
else if (tgpi->type == GP_STROKE_BOX) {
@@ -695,7 +696,6 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
bool is_depth = (bool)(*align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE));
const bool is_camera = (bool)(ts->gp_sculpt.lock_axis == 0) &&
(tgpi->rv3d->persp == RV3D_CAMOB) && (!is_depth);
- const bool is_vertex_stroke = GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush);
if (tgpi->type == GP_STROKE_BOX) {
gps->totpoints = (tgpi->tot_edges * 4 + tgpi->tot_stored_edges);
@@ -741,13 +741,13 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
gpencil_session_validatebuffer(tgpi);
gpencil_init_colors(tgpi);
if (gset->flag & GP_SCULPT_SETT_FLAG_PRIMITIVE_CURVE) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_primitive);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_primitive);
}
if (brush_settings->flag & GP_BRUSH_USE_JITTER_PRESSURE) {
- BKE_curvemapping_initialize(brush_settings->curve_jitter);
+ BKE_curvemapping_init(brush_settings->curve_jitter);
}
- if (brush_settings->flag & GP_BRUSH_USE_STENGTH_PRESSURE) {
- BKE_curvemapping_initialize(brush_settings->curve_strength);
+ if (brush_settings->flag & GP_BRUSH_USE_STRENGTH_PRESSURE) {
+ BKE_curvemapping_init(brush_settings->curve_strength);
}
/* get an array of depths, far depths are blended */
@@ -912,7 +912,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
}
/* color strength */
- if (brush_settings->flag & GP_BRUSH_USE_STENGTH_PRESSURE) {
+ if (brush_settings->flag & GP_BRUSH_USE_STRENGTH_PRESSURE) {
float curvef = BKE_curvemapping_evaluateF(brush_settings->curve_strength, 0, curve_pressure);
strength *= curvef;
strength *= brush_settings->draw_strength;
@@ -1020,12 +1020,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
pt->time = 0.0f;
pt->flag = 0;
pt->uv_fac = tpt->uv_fac;
- if (is_vertex_stroke) {
- copy_v4_v4(pt->vert_color, tpt->vert_color);
- }
- else {
- zero_v4(pt->vert_color);
- }
+ ED_gpencil_point_vertex_color_set(ts, brush, pt, tpt);
if (gps->dvert != NULL) {
MDeformVert *dvert = &gps->dvert[i];
@@ -1091,7 +1086,7 @@ static void gpencil_primitive_update(bContext *C, wmOperator *op, tGPDprimitive
gpencil_primitive_update_strokes(C, tgpi);
}
-/* Initialise mouse points */
+/* Initialize mouse points. */
static void gpencil_primitive_interaction_begin(tGPDprimitive *tgpi, const wmEvent *event)
{
copy_v2fl_v2i(tgpi->mval, event->mval);
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 20eeab65623..43c8b766c52 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -444,7 +444,9 @@ typedef struct tGPSB_Grab_StrokeData {
int size;
} tGPSB_Grab_StrokeData;
-/* initialise custom data for handling this stroke */
+/**
+ * Initialize custom data for handling this stroke.
+ */
static void gpencil_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps)
{
tGPSB_Grab_StrokeData *data = NULL;
@@ -910,13 +912,13 @@ typedef struct tGPSB_CloneBrushData {
GHash *new_colors;
} tGPSB_CloneBrushData;
-/* Initialise "clone" brush data */
+/* Initialize "clone" brush data. */
static void gpencil_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data;
bGPDstroke *gps;
- /* init custom data */
+ /* Initialize custom-data. */
gso->customdata = data = MEM_callocN(sizeof(tGPSB_CloneBrushData), "CloneBrushData");
/* compute midpoint of strokes on clipboard */
@@ -1188,7 +1190,7 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
Paint *paint = &ts->gp_sculptpaint->paint;
gso->brush = paint->brush;
- BKE_curvemapping_initialize(gso->brush->curve);
+ BKE_curvemapping_init(gso->brush->curve);
/* save mask */
gso->mask = ts->gpencil_selectmode_sculpt;
@@ -1200,10 +1202,10 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
/* Init multi-edit falloff curve data before doing anything,
* so we won't have to do it again later. */
if (gso->is_multiframe) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_falloff);
}
- /* initialise custom data for brushes */
+ /* Initialize custom data for brushes. */
char tool = gso->brush->gpencil_sculpt_tool;
switch (tool) {
case GPSCULPT_TOOL_CLONE: {
@@ -1229,13 +1231,13 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
op->customdata = NULL;
return false;
}
- /* initialise customdata */
+ /* Initialize custom-data. */
gpencil_brush_clone_init(C, gso);
break;
}
case GPSCULPT_TOOL_GRAB: {
- /* initialise the cache needed for this brush */
+ /* Initialize the cache needed for this brush. */
gso->stroke_customdata = BLI_ghash_ptr_new("GP Grab Brush - Strokes Hash");
break;
}
@@ -1936,7 +1938,7 @@ static int gpencil_sculpt_brush_invoke(bContext *C, wmOperator *op, const wmEven
gso = op->customdata;
- /* initialise type-specific data (used for the entire session) */
+ /* Initialize type-specific data (used for the entire session). */
char tool = gso->brush->gpencil_sculpt_tool;
switch (tool) {
/* Brushes requiring timer... */
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index dd5e16a9d9b..f2ccbd6d2cf 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -1500,7 +1500,7 @@ void ED_gpencil_add_defaults(bContext *C, Object *ob)
if (ts->gp_sculpt.cur_falloff == NULL) {
ts->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_falloff_curve = ts->gp_sculpt.cur_falloff;
- BKE_curvemapping_initialize(gp_falloff_curve);
+ BKE_curvemapping_init(gp_falloff_curve);
BKE_curvemap_reset(gp_falloff_curve->cm,
&gp_falloff_curve->clipr,
CURVE_PRESET_GAUSS,
@@ -1761,7 +1761,8 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y)
GPU_line_smooth(true);
GPU_blend(true);
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
immUniformColor4ub(255, 100, 100, 20);
imm_draw_circle_fill_2d(shdr_pos, x, y, radius, 40);
@@ -1771,7 +1772,7 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y)
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
- glGetFloatv(GL_VIEWPORT, viewport_size);
+ GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
immUniformColor4f(1.0f, 0.39f, 0.39f, 0.78f);
@@ -2245,7 +2246,7 @@ static void gpencil_copy_points(
}
static void gpencil_insert_point(
- bGPDstroke *gps, bGPDspoint *a_pt, bGPDspoint *b_pt, const float co_a[3], float co_b[3])
+ bGPDstroke *gps, bGPDspoint *a_pt, bGPDspoint *b_pt, const float co_a[3], const float co_b[3])
{
bGPDspoint *temp_points;
int totnewpoints, oldtotpoints;
@@ -2687,7 +2688,11 @@ void ED_gpencil_tag_scene_gpencil(Scene *scene)
void ED_gpencil_fill_vertex_color_set(ToolSettings *ts, Brush *brush, bGPDstroke *gps)
{
- if (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush)) {
+ const bool is_vertex = (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) ||
+ (!GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR));
+ if (is_vertex) {
copy_v3_v3(gps->vert_color_fill, brush->rgb);
gps->vert_color_fill[3] = brush->gpencil_settings->vertex_factor;
srgb_to_linearrgb_v4(gps->vert_color_fill, gps->vert_color_fill);
@@ -2702,7 +2707,12 @@ void ED_gpencil_point_vertex_color_set(ToolSettings *ts,
bGPDspoint *pt,
tGPspoint *tpt)
{
- if (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush)) {
+ const bool is_vertex = (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) ||
+ (!GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR));
+
+ if (is_vertex) {
if (tpt == NULL) {
copy_v3_v3(pt->vert_color, brush->rgb);
pt->vert_color[3] = brush->gpencil_settings->vertex_factor;
@@ -2764,7 +2774,7 @@ void ED_gpencil_init_random_settings(Brush *brush,
}
static void gpencil_sbuffer_vertex_color_random(
- bGPdata *gpd, Brush *brush, tGPspoint *tpt, float random_color[3], float pen_pressure)
+ bGPdata *gpd, Brush *brush, tGPspoint *tpt, const float random_color[3], float pen_pressure)
{
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
if (brush_settings->flag & GP_BRUSH_GROUP_RANDOM) {
@@ -2858,6 +2868,18 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
bGPdata *gpd_eval = (bGPdata *)ob_eval->data;
MaterialGPencilStyle *gp_style = material->gp_style;
+ const bool is_vertex_fill =
+ (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) ||
+ (!GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR));
+
+ const bool is_vertex_stroke =
+ (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) ||
+ (!GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR));
+
int idx = gpd->runtime.sbuffer_used;
tGPspoint *tpt = (tGPspoint *)gpd->runtime.sbuffer + idx;
@@ -2867,14 +2889,14 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
srgb_to_linearrgb_v4(vertex_color, vertex_color);
/* Copy fill vertex color. */
- if (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush)) {
+ if (is_vertex_fill) {
copy_v4_v4(gpd->runtime.vert_color_fill, vertex_color);
}
else {
copy_v4_v4(gpd->runtime.vert_color_fill, gp_style->fill_rgba);
}
/* Copy stroke vertex color. */
- if (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush)) {
+ if (is_vertex_stroke) {
copy_v4_v4(tpt->vert_color, vertex_color);
}
else {
@@ -2895,7 +2917,7 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
/* Check if the stroke collides with brush. */
bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
bGPDstroke *gps,
- float mouse[2],
+ const float mouse[2],
const int radius,
const float diff_mat[4][4])
{
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index 99d55350527..b0dff6589da 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -348,7 +348,7 @@ static void gpencil_grid_cell_average_color_idx_get(tGP_BrushVertexpaintData *gs
}
}
-static int gpencil_grid_cell_index_get(tGP_BrushVertexpaintData *gso, int pc[2])
+static int gpencil_grid_cell_index_get(tGP_BrushVertexpaintData *gso, const int pc[2])
{
float bottom[2], top[2];
@@ -408,8 +408,6 @@ static void gpencil_grid_colors_calc(tGP_BrushVertexpaintData *gso)
round_v2i_v2fl(gso->grid_sample, gso->mval);
gso->grid_ready = true;
-
- return;
}
/* ************************************************ */
@@ -729,7 +727,7 @@ static bool gpencil_vertexpaint_brush_init(bContext *C, wmOperator *op)
gso->brush = paint->brush;
srgb_to_linearrgb_v3_v3(gso->linear_color, gso->brush->rgb);
- BKE_curvemapping_initialize(gso->brush->curve);
+ BKE_curvemapping_init(gso->brush->curve);
gso->is_painting = false;
gso->first = true;
@@ -761,7 +759,7 @@ static bool gpencil_vertexpaint_brush_init(bContext *C, wmOperator *op)
/* Init multi-edit falloff curve data before doing anything,
* so we won't have to do it again later. */
if (gso->is_multiframe) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_falloff);
}
/* Setup space conversions. */
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index e41146575e4..9d3e9c6ae45 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -295,7 +295,7 @@ static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op)
gso->bmain = CTX_data_main(C);
gso->brush = paint->brush;
- BKE_curvemapping_initialize(gso->brush->curve);
+ BKE_curvemapping_init(gso->brush->curve);
gso->is_painting = false;
gso->first = true;
@@ -326,7 +326,7 @@ static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op)
/* Init multi-edit falloff curve data before doing anything,
* so we won't have to do it again later. */
if (gso->is_multiframe) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_falloff);
}
/* Setup space conversions. */
@@ -453,9 +453,9 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
/* To each point individually... */
pt = &gps->points[i];
- pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
- index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
+ pt_active = pt->runtime.pt_orig;
if (pt_active != NULL) {
+ index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
gpencil_save_selected_point(gso, gps_active, index, pc1);
}
@@ -469,9 +469,9 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
*/
if (i + 1 == gps->totpoints - 1) {
pt = &gps->points[i + 1];
- pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
- index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i + 1;
+ pt_active = pt->runtime.pt_orig;
if (pt_active != NULL) {
+ index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i + 1;
gpencil_save_selected_point(gso, gps_active, index, pc2);
include_last = false;
}
@@ -487,9 +487,9 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
* (but wasn't added then, to avoid double-ups).
*/
pt = &gps->points[i];
- pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
- index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
+ pt_active = pt->runtime.pt_orig;
if (pt_active != NULL) {
+ index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
gpencil_save_selected_point(gso, gps_active, index, pc1);
include_last = false;
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 04f9edeaf3a..3b7eb01f92c 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -21,8 +21,9 @@
* \ingroup editorui
*/
-#ifndef __BIF_GLUTIL_H__
-#define __BIF_GLUTIL_H__
+#pragma once
+
+#include "GPU_texture.h"
#ifdef __cplusplus
extern "C" {
@@ -66,9 +67,8 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float xzoom,
float yzoom,
@@ -78,9 +78,8 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float clip_min_x,
float clip_min_y,
@@ -94,9 +93,8 @@ void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
@@ -108,9 +106,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
@@ -133,7 +130,7 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
void ED_draw_imbuf(struct ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
struct ColorManagedViewSettings *view_settings,
struct ColorManagedDisplaySettings *display_settings,
float zoom_x,
@@ -141,7 +138,7 @@ void ED_draw_imbuf(struct ImBuf *ibuf,
void ED_draw_imbuf_clipping(struct ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
struct ColorManagedViewSettings *view_settings,
struct ColorManagedDisplaySettings *display_settings,
float clip_min_x,
@@ -155,14 +152,14 @@ void ED_draw_imbuf_ctx(const struct bContext *C,
struct ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
float zoom_x,
float zoom_y);
void ED_draw_imbuf_ctx_clipping(const struct bContext *C,
struct ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
float clip_min_x,
float clip_min_y,
float clip_max_x,
@@ -172,17 +169,8 @@ void ED_draw_imbuf_ctx_clipping(const struct bContext *C,
int ED_draw_imbuf_method(struct ImBuf *ibuf);
-/* OpenGL drawing utility functions. Do not use these in new code, these
- * are intended to be moved or removed in the future. */
-
-/* own working polygon offset */
-float bglPolygonOffsetCalc(const float winmat[16], float viewdist, float dist);
-void bglPolygonOffset(float viewdist, float dist);
-
void immDrawBorderCorners(unsigned int pos, const struct rcti *border, float zoomx, float zoomy);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BIF_GLUTIL_H__ */
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 3aecec0d6b6..36990414e6d 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_ANIM_API_H__
-#define __ED_ANIM_API_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -95,6 +94,8 @@ typedef struct bAnimContext {
struct Scene *scene;
/** active scene layer */
struct ViewLayer *view_layer;
+ /** active dependency graph */
+ struct Depsgraph *depsgraph;
/** active object */
struct Object *obact;
/** active set of markers */
@@ -708,7 +709,7 @@ void getcolor_fcurve_rainbow(int cur, int tot, float out[3]);
/* ----------------- NLA Drawing ----------------------- */
/* NOTE: Technically, this is not in the animation module (it's in space_nla)
- * but these are sometimes needed by various animation apis.
+ * but these are sometimes needed by various animation API's.
*/
/* Get color to use for NLA Action channel's background */
@@ -878,5 +879,3 @@ void animviz_get_object_motionpaths(struct Object *ob, ListBase *targets);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_ANIM_API_H__ */
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index d82c7126cf2..62f4c068de0 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_ARMATURE_H__
-#define __ED_ARMATURE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -225,10 +224,10 @@ void ED_armature_ebone_remove(struct bArmature *arm, EditBone *exBone);
bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child);
EditBone *ED_armature_ebone_find_shared_parent(EditBone *ebone_child[],
const unsigned int ebone_child_tot);
-void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]);
-void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]);
-void ED_armature_ebone_from_mat3(EditBone *ebone, float mat[3][3]);
-void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]);
+void ED_armature_ebone_to_mat3(EditBone *ebone, float r_mat[3][3]);
+void ED_armature_ebone_to_mat4(EditBone *ebone, float r_mat[4][4]);
+void ED_armature_ebone_from_mat3(EditBone *ebone, const float mat[3][3]);
+void ED_armature_ebone_from_mat4(EditBone *ebone, const float mat[4][4]);
EditBone *ED_armature_ebone_find_name(const struct ListBase *edbo, const char *name);
EditBone *ED_armature_ebone_get_mirrored(const struct ListBase *edbo, EditBone *ebo);
void ED_armature_ebone_transform_mirror_update(struct bArmature *arm,
@@ -298,5 +297,3 @@ void ED_mesh_deform_bind_callback(struct MeshDeformModifierData *mmd,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_ARMATURE_H__ */
diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h
index 2eaef5e82e0..ccef62eb8d2 100644
--- a/source/blender/editors/include/ED_buttons.h
+++ b/source/blender/editors/include/ED_buttons.h
@@ -20,15 +20,16 @@
* \ingroup editors
*/
-#ifndef __ED_BUTTONS_H__
-#define __ED_BUTTONS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
#endif
+struct SpaceProperties;
+
+int ED_buttons_tabs_list(struct SpaceProperties *sbuts, int *context_tabs_array);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_BUTTONS_H__ */
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
index f270a0324f9..0a66c439f79 100644
--- a/source/blender/editors/include/ED_clip.h
+++ b/source/blender/editors/include/ED_clip.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_CLIP_H__
-#define __ED_CLIP_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -106,5 +105,3 @@ void ED_operatormacros_clip(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_CLIP_H__ */
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index 79f5f62f293..f9b1d9cdc64 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_CURVE_H__
-#define __ED_CURVE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -111,5 +110,3 @@ void printknots(struct Object *obedit);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_CURVE_H__ */
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index ad1cde5406d..ba77da24406 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_DATAFILES_H__
-#define __ED_DATAFILES_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -301,5 +300,3 @@ extern char datatoc_gp_brush_erase_stroke_png[];
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_DATAFILES_H__ */
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index a523e924e54..deda0861b60 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_FILESELECT_H__
-#define __ED_FILESELECT_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -106,7 +105,7 @@ struct FileSelectParams *ED_fileselect_get_params(struct SpaceFile *sfile);
short ED_fileselect_set_params(struct SpaceFile *sfile);
void ED_fileselect_set_params_from_userdef(struct SpaceFile *sfile);
void ED_fileselect_params_to_userdef(struct SpaceFile *sfile,
- int temp_win_size[],
+ const int temp_win_size[],
const bool is_maximized);
void ED_fileselect_reset_params(struct SpaceFile *sfile);
@@ -214,5 +213,3 @@ void ED_fsmenu_entry_set_icon(struct FSMenuEntry *fsentry, const int icon);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_FILESELECT_H__ */
diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h
index a1a5d65b61d..0ee3b00e426 100644
--- a/source/blender/editors/include/ED_gizmo_library.h
+++ b/source/blender/editors/include/ED_gizmo_library.h
@@ -22,8 +22,7 @@
* This is exposes pre-defined gizmos for re-use.
*/
-#ifndef __ED_GIZMO_LIBRARY_H__
-#define __ED_GIZMO_LIBRARY_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -278,5 +277,3 @@ short ED_gizmotypes_snap_3d_update(struct wmGizmo *gz,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_GIZMO_LIBRARY_H__ */
diff --git a/source/blender/editors/include/ED_gizmo_utils.h b/source/blender/editors/include/ED_gizmo_utils.h
index 70ff8a8d32f..0cfc3df9d54 100644
--- a/source/blender/editors/include/ED_gizmo_utils.h
+++ b/source/blender/editors/include/ED_gizmo_utils.h
@@ -20,8 +20,7 @@
* \name Generic Gizmo Utilities.
*/
-#ifndef __ED_GIZMO_UTILS_H__
-#define __ED_GIZMO_UTILS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -46,5 +45,3 @@ bool ED_gizmo_poll_or_unlink_delayed_from_tool(const struct bContext *C,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_GIZMO_UTILS_H__ */
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index f961f835f12..06839276027 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_GPENCIL_H__
-#define __ED_GPENCIL_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -351,7 +350,7 @@ void ED_gpencil_init_random_settings(struct Brush *brush,
bool ED_gpencil_stroke_check_collision(struct GP_SpaceConversion *gsc,
struct bGPDstroke *gps,
- float mouse[2],
+ const float mouse[2],
const int radius,
const float diff_mat[4][4]);
bool ED_gpencil_stroke_point_is_inside(struct bGPDstroke *gps,
@@ -362,5 +361,3 @@ bool ED_gpencil_stroke_point_is_inside(struct bGPDstroke *gps,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_GPENCIL_H__ */
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index a8476e3d1ca..65ca181e160 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_IMAGE_H__
-#define __ED_IMAGE_H__
+#pragma once
#include "DNA_listBase.h"
#include "DNA_space_types.h"
@@ -125,8 +124,8 @@ void ED_image_draw_info(struct Scene *scene,
const unsigned char cp[4],
const float fp[4],
const float linearcol[4],
- int *zp,
- float *zpf);
+ const int *zp,
+ const float *zpf);
bool ED_space_image_show_cache(struct SpaceImage *sima);
@@ -157,5 +156,3 @@ ListBase ED_image_filesel_detect_sequences(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_IMAGE_H__ */
diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h
index 1146c49bef2..df6b6a20ddc 100644
--- a/source/blender/editors/include/ED_info.h
+++ b/source/blender/editors/include/ED_info.h
@@ -20,8 +20,7 @@
* \ingroup editors
*/
-#ifndef __ED_INFO_H__
-#define __ED_INFO_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -31,12 +30,12 @@ struct Main;
/* info_stats.c */
void ED_info_stats_clear(struct ViewLayer *view_layer);
-const char *ED_info_footer_string(struct ViewLayer *view_layer);
+const char *ED_info_statusbar_string(struct Main *bmain,
+ struct bScreen *screen,
+ struct bContext *C);
void ED_info_draw_stats(
- Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height);
+ struct Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_INFO_H__ */
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 7000075d4b5..adc1e09821e 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_KEYFRAMES_DRAW_H__
-#define __ED_KEYFRAMES_DRAW_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -273,5 +272,3 @@ int actkeyblock_get_valid_hold(ActKeyColumn *ab);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_KEYFRAMES_DRAW_H__ */
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index 28bc0b22790..b08ab57545f 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_KEYFRAMES_EDIT_H__
-#define __ED_KEYFRAMES_EDIT_H__
+#pragma once
#include "ED_anim_api.h" /* for enum eAnimFilter_Flags */
@@ -340,5 +339,3 @@ short paste_animedit_keys(struct bAnimContext *ac,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_KEYFRAMES_EDIT_H__ */
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 5635ef2800a..7f833cd59bf 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_KEYFRAMING_H__
-#define __ED_KEYFRAMING_H__
+#pragma once
#include "DNA_anim_types.h"
#include "RNA_types.h"
@@ -38,6 +37,7 @@ struct Scene;
struct KeyingSet;
+struct AnimationEvalContext;
struct BezTriple;
struct FCurve;
struct bAction;
@@ -118,7 +118,7 @@ bool insert_keyframe_direct(struct ReportList *reports,
struct PointerRNA ptr,
struct PropertyRNA *prop,
struct FCurve *fcu,
- float cfra,
+ const struct AnimationEvalContext *anim_eval_context,
eBezTriple_KeyframeType keytype,
struct NlaKeyframingContext *nla,
eInsertKeyFlags flag);
@@ -136,7 +136,7 @@ int insert_keyframe(struct Main *bmain,
const char group[],
const char rna_path[],
int array_index,
- float cfra,
+ const struct AnimationEvalContext *anim_eval_context,
eBezTriple_KeyframeType keytype,
struct ListBase *nla_cache,
eInsertKeyFlags flag);
@@ -458,7 +458,7 @@ bool fcurve_frame_has_keyframe(struct FCurve *fcu, float frame, short filter);
bool fcurve_is_changed(struct PointerRNA ptr,
struct PropertyRNA *prop,
struct FCurve *fcu,
- float frame);
+ const struct AnimationEvalContext *anim_eval_context);
/**
* Main Keyframe Checking API call:
@@ -515,5 +515,3 @@ bool ED_autokeyframe_property(struct bContext *C,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_KEYFRAMING_H__ */
diff --git a/source/blender/editors/include/ED_lattice.h b/source/blender/editors/include/ED_lattice.h
index 2e4b9472ce7..6982ad20f07 100644
--- a/source/blender/editors/include/ED_lattice.h
+++ b/source/blender/editors/include/ED_lattice.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_LATTICE_H__
-#define __ED_LATTICE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -51,5 +50,3 @@ void ED_lattice_undosys_type(struct UndoType *ut);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_LATTICE_H__ */
diff --git a/source/blender/editors/include/ED_markers.h b/source/blender/editors/include/ED_markers.h
index 54a5d0cb0e1..8c10a8e36fd 100644
--- a/source/blender/editors/include/ED_markers.h
+++ b/source/blender/editors/include/ED_markers.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_MARKERS_H__
-#define __ED_MARKERS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -77,5 +76,3 @@ void debug_markers_print_list(struct ListBase *markers);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_MARKERS_H__ */
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index 5aafc0702da..80510d3afa1 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_MASK_H__
-#define __ED_MASK_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -125,5 +124,3 @@ void mirror_masklayer_frames(struct MaskLayer *mask_layer, short mode);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_MASK_H__ */
diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h
index 5c2106b934c..7648af159c9 100644
--- a/source/blender/editors/include/ED_mball.h
+++ b/source/blender/editors/include/ED_mball.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_MBALL_H__
-#define __ED_MBALL_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -65,5 +64,3 @@ void ED_mball_undosys_type(struct UndoType *ut);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_MBALL_H__ */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 046eadb2ec3..f2cad1acc84 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_MESH_H__
-#define __ED_MESH_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -123,7 +122,6 @@ struct BMFace *EDBM_uv_active_face_get(struct BMEditMesh *em,
void BM_uv_vert_map_free(struct UvVertMap *vmap);
struct UvMapVert *BM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v);
struct UvVertMap *BM_uv_vert_map_create(struct BMesh *bm,
- const float limit[2],
const bool use_select,
const bool use_winding);
@@ -518,5 +516,3 @@ void EDBM_mesh_elem_index_ensure_multi(struct Object **objects,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_MESH_H__ */
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index 47ccc0788c2..ecb98a46f99 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_NODE_H__
-#define __ED_NODE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -121,11 +120,9 @@ void ED_operatormacros_node(void);
bool ED_space_node_color_sample(struct Main *bmain,
struct SpaceNode *snode,
struct ARegion *region,
- int mval[2],
+ const int mval[2],
float r_col[3]);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_NODE_H__ */
diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h
index 8c8f3e6f4a3..6c5aacafc7a 100644
--- a/source/blender/editors/include/ED_numinput.h
+++ b/source/blender/editors/include/ED_numinput.h
@@ -18,8 +18,7 @@
* \ingroup editors
*/
-#ifndef __ED_NUMINPUT_H__
-#define __ED_NUMINPUT_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -103,13 +102,15 @@ bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event
#define NUM_MODAL_INCREMENT_UP 18
#define NUM_MODAL_INCREMENT_DOWN 19
-bool user_string_to_number(
- bContext *C, const char *str, const struct UnitSettings *unit, int type, double *r_value);
+bool user_string_to_number(bContext *C,
+ const char *str,
+ const struct UnitSettings *unit,
+ int type,
+ const char *error_prefix,
+ double *r_value);
/** \} */
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_NUMINPUT_H__ */
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 10cd6980c90..4c7dd4fe66c 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_OBJECT_H__
-#define __ED_OBJECT_H__
+#pragma once
#include "BLI_compiler_attrs.h"
#include "DNA_object_enums.h"
@@ -58,9 +57,9 @@ struct wmWindowManager;
/* object_edit.c */
/* context.object */
-struct Object *ED_object_context(struct bContext *C);
+struct Object *ED_object_context(const struct bContext *C);
/* context.object or context.active_object */
-struct Object *ED_object_active_context(struct bContext *C);
+struct Object *ED_object_active_context(const struct bContext *C);
void ED_collection_hide_menu_draw(const struct bContext *C, struct uiLayout *layout);
/* object_utils.c */
@@ -362,9 +361,10 @@ struct ModifierData *ED_object_modifier_add(struct ReportList *reports,
int type);
bool ED_object_modifier_remove(struct ReportList *reports,
struct Main *bmain,
+ struct Scene *scene,
struct Object *ob,
struct ModifierData *md);
-void ED_object_modifier_clear(struct Main *bmain, struct Object *ob);
+void ED_object_modifier_clear(struct Main *bmain, struct Scene *scene, struct Object *ob);
bool ED_object_modifier_move_down(struct ReportList *reports,
struct Object *ob,
struct ModifierData *md);
@@ -389,8 +389,11 @@ bool ED_object_modifier_apply(struct Main *bmain,
struct Scene *scene,
struct Object *ob,
struct ModifierData *md,
- int mode);
+ int mode,
+ bool keep_modifier);
int ED_object_modifier_copy(struct ReportList *reports,
+ struct Main *bmain,
+ struct Scene *scene,
struct Object *ob,
struct ModifierData *md);
@@ -488,7 +491,7 @@ struct XFormObjectData *ED_object_data_xform_create_ex(struct ID *id, bool is_ed
struct XFormObjectData *ED_object_data_xform_create(struct ID *id);
struct XFormObjectData *ED_object_data_xform_create_from_edit_mode(ID *id);
-void ED_object_data_xform_destroy(struct XFormObjectData *xod);
+void ED_object_data_xform_destroy(struct XFormObjectData *xod_base);
void ED_object_data_xform_by_mat4(struct XFormObjectData *xod, const float mat[4][4]);
@@ -498,5 +501,3 @@ void ED_object_data_xform_tag_update(struct XFormObjectData *xod);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_OBJECT_H__ */
diff --git a/source/blender/editors/include/ED_outliner.h b/source/blender/editors/include/ED_outliner.h
index 0325ad9fdba..9853b4644c1 100644
--- a/source/blender/editors/include/ED_outliner.h
+++ b/source/blender/editors/include/ED_outliner.h
@@ -20,8 +20,7 @@
* \ingroup editors
*/
-#ifndef __ED_OUTLINER_H__
-#define __ED_OUTLINER_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -53,5 +52,3 @@ void ED_outliner_select_sync_flag_outliners(const struct bContext *C);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_OUTLINER_H__ */
diff --git a/source/blender/editors/include/ED_paint.h b/source/blender/editors/include/ED_paint.h
index 4159f22703f..3412d62317e 100644
--- a/source/blender/editors/include/ED_paint.h
+++ b/source/blender/editors/include/ED_paint.h
@@ -18,8 +18,7 @@
* \ingroup editors
*/
-#ifndef __ED_PAINT_H__
-#define __ED_PAINT_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -104,5 +103,3 @@ void ED_paintcurve_undosys_type(struct UndoType *ut);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_PAINT_H__ */
diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h
index 789db5ae56e..e84298bd9c2 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_PARTICLE_H__
-#define __ED_PARTICLE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -83,5 +82,3 @@ void ED_particle_undosys_type(struct UndoType *ut);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_PARTICLE_H__ */
diff --git a/source/blender/editors/include/ED_physics.h b/source/blender/editors/include/ED_physics.h
index ebd7e387c83..f9c56f31ebd 100644
--- a/source/blender/editors/include/ED_physics.h
+++ b/source/blender/editors/include/ED_physics.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_PHYSICS_H__
-#define __ED_PHYSICS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -63,5 +62,3 @@ void ED_keymap_physics(struct wmKeyConfig *keyconf);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_PHYSICS_H__ */
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index ba70abcc055..d580e36d0ce 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_RENDER_H__
-#define __ED_RENDER_H__
+#pragma once
#include "DNA_vec_types.h"
@@ -110,5 +109,3 @@ void ED_render_internal_init(void);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/editors/include/ED_scene.h b/source/blender/editors/include/ED_scene.h
index 27c2e9d0df8..e3abd26a4cd 100644
--- a/source/blender/editors/include/ED_scene.h
+++ b/source/blender/editors/include/ED_scene.h
@@ -18,8 +18,7 @@
* \ingroup editors
*/
-#ifndef __ED_SCENE_H__
-#define __ED_SCENE_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -46,5 +45,3 @@ void ED_operatortypes_scene(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_SCENE_H__ */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index bc6a4b23609..29fe766b2d0 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_SCREEN_H__
-#define __ED_SCREEN_H__
+#pragma once
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -73,7 +72,7 @@ void ED_region_exit(struct bContext *C, struct ARegion *region);
void ED_region_remove(struct bContext *C, struct ScrArea *area, struct ARegion *region);
void ED_region_pixelspace(struct ARegion *region);
void ED_region_update_rect(struct ARegion *region);
-void ED_region_floating_initialize(struct ARegion *region);
+void ED_region_floating_init(struct ARegion *region);
void ED_region_tag_redraw(struct ARegion *region);
void ED_region_tag_redraw_partial(struct ARegion *region, const struct rcti *rct, bool rebuild);
void ED_region_tag_redraw_cursor(struct ARegion *region);
@@ -171,7 +170,7 @@ void ED_spacetypes_keymap(struct wmKeyConfig *keyconf);
int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *block, int yco);
/* areas */
-void ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area);
+void ED_area_init(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area);
void ED_area_exit(struct bContext *C, struct ScrArea *area);
int ED_screen_area_active(const struct bContext *C);
void ED_screen_global_areas_refresh(struct wmWindow *win);
@@ -221,7 +220,7 @@ ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area);
vert_name->next)
/* screens */
-void ED_screens_initialize(struct Main *bmain, struct wmWindowManager *wm);
+void ED_screens_init(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 *area, const int dir, const float fac);
@@ -287,6 +286,12 @@ bool ED_workspace_delete(struct WorkSpace *workspace,
struct bContext *C,
struct wmWindowManager *wm) ATTR_NONNULL();
void ED_workspace_scene_data_sync(struct WorkSpaceInstanceHook *hook, Scene *scene) ATTR_NONNULL();
+struct WorkSpaceLayout *ED_workspace_screen_change_ensure_unused_layout(
+ struct Main *bmain,
+ struct WorkSpace *workspace,
+ struct WorkSpaceLayout *layout_new,
+ const struct WorkSpaceLayout *layout_fallback_base,
+ struct wmWindow *win) ATTR_NONNULL();
struct WorkSpaceLayout *ED_workspace_layout_add(struct Main *bmain,
struct WorkSpace *workspace,
struct wmWindow *win,
@@ -349,6 +354,7 @@ bool ED_operator_console_active(struct bContext *C);
bool ED_operator_object_active(struct bContext *C);
bool ED_operator_object_active_editable_ex(struct bContext *C, const Object *ob);
bool ED_operator_object_active_editable(struct bContext *C);
+bool ED_operator_object_active_local_editable(struct bContext *C);
bool ED_operator_object_active_editable_mesh(struct bContext *C);
bool ED_operator_object_active_editable_font(struct bContext *C);
bool ED_operator_editable_mesh(struct bContext *C);
@@ -476,5 +482,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_SCREEN_H__ */
diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h
index 9826ec8c3b8..0185de426f3 100644
--- a/source/blender/editors/include/ED_screen_types.h
+++ b/source/blender/editors/include/ED_screen_types.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_SCREEN_TYPES_H__
-#define __ED_SCREEN_TYPES_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -140,5 +139,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_SCREEN_TYPES_H__ */
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index e61c7be5216..c3abde479f1 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_SCULPT_H__
-#define __ED_SCULPT_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -62,5 +61,3 @@ void ED_sculpt_undo_push_multires_mesh_end(struct bContext *C, const char *str);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_SCULPT_H__ */
diff --git a/source/blender/editors/include/ED_select_utils.h b/source/blender/editors/include/ED_select_utils.h
index 9c7cc0ef7a2..049ea7a092f 100644
--- a/source/blender/editors/include/ED_select_utils.h
+++ b/source/blender/editors/include/ED_select_utils.h
@@ -18,8 +18,7 @@
* \ingroup editors
*/
-#ifndef __ED_SELECT_UTILS_H__
-#define __ED_SELECT_UTILS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -78,5 +77,3 @@ eSelectOp ED_select_op_modal(const eSelectOp sel_op, const bool is_first);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_SELECT_UTILS_H__ */
diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h
index f35ed12cdb9..11eff2d583b 100644
--- a/source/blender/editors/include/ED_sequencer.h
+++ b/source/blender/editors/include/ED_sequencer.h
@@ -20,8 +20,7 @@
* \ingroup editors
*/
-#ifndef __ED_SEQUENCER_H__
-#define __ED_SEQUENCER_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -53,5 +52,3 @@ void ED_sequencer_special_preview_clear(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_SEQUENCER_H__ */
diff --git a/source/blender/editors/include/ED_sound.h b/source/blender/editors/include/ED_sound.h
index f7632bc81cb..022c7784ed3 100644
--- a/source/blender/editors/include/ED_sound.h
+++ b/source/blender/editors/include/ED_sound.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_SOUND_H__
-#define __ED_SOUND_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -33,5 +32,3 @@ void ED_operatortypes_sound(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_SOUND_H__ */
diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h
index ae4add2fca2..f3e867e8360 100644
--- a/source/blender/editors/include/ED_space_api.h
+++ b/source/blender/editors/include/ED_space_api.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_SPACE_API_H__
-#define __ED_SPACE_API_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -83,5 +82,3 @@ void ED_region_draw_mouse_line_cb(const struct bContext *C,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_SPACE_API_H__ */
diff --git a/source/blender/editors/include/ED_text.h b/source/blender/editors/include/ED_text.h
index 4f7b76675f0..6742561735e 100644
--- a/source/blender/editors/include/ED_text.h
+++ b/source/blender/editors/include/ED_text.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_TEXT_H__
-#define __ED_TEXT_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -51,5 +50,3 @@ bool ED_text_is_syntax_highlight_supported(struct Text *text);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_TEXT_H__ */
diff --git a/source/blender/editors/include/ED_time_scrub_ui.h b/source/blender/editors/include/ED_time_scrub_ui.h
index 483dce56577..216e67dd820 100644
--- a/source/blender/editors/include/ED_time_scrub_ui.h
+++ b/source/blender/editors/include/ED_time_scrub_ui.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_TIME_SCRUB_UI_H__
-#define __ED_TIME_SCRUB_UI_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -51,5 +50,3 @@ void ED_time_scrub_channel_search_draw(const struct bContext *C,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_TIME_SCRUB_UI_H__ */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 29ed0485490..4c4672edffc 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_TRANSFORM_H__
-#define __ED_TRANSFORM_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -215,5 +214,3 @@ int ED_transform_calc_gizmo_stats(const struct bContext *C,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_TRANSFORM_H__ */
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 8feb73436a6..ebaa32941f2 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -18,8 +18,7 @@
* \ingroup editors
*/
-#ifndef __ED_TRANSFORM_SNAP_OBJECT_CONTEXT_H__
-#define __ED_TRANSFORM_SNAP_OBJECT_CONTEXT_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -157,5 +156,3 @@ bool ED_transform_snap_object_project_all_view3d_ex(SnapObjectContext *sctx,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_TRANSFORM_SNAP_OBJECT_CONTEXT_H__ */
diff --git a/source/blender/editors/include/ED_transverts.h b/source/blender/editors/include/ED_transverts.h
index 062658a562b..bff31149b75 100644
--- a/source/blender/editors/include/ED_transverts.h
+++ b/source/blender/editors/include/ED_transverts.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_TRANSVERTS_H__
-#define __ED_TRANSVERTS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -75,5 +74,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_TRANSVERTS_H__ */
diff --git a/source/blender/editors/include/ED_types.h b/source/blender/editors/include/ED_types.h
index 4abb7d446d1..ab9098a33c5 100644
--- a/source/blender/editors/include/ED_types.h
+++ b/source/blender/editors/include/ED_types.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_TYPES_H__
-#define __ED_TYPES_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -42,5 +41,3 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_TYPES_H__ */
diff --git a/source/blender/editors/include/ED_undo.h b/source/blender/editors/include/ED_undo.h
index 983e0c4f14a..dbd374415b0 100644
--- a/source/blender/editors/include/ED_undo.h
+++ b/source/blender/editors/include/ED_undo.h
@@ -18,8 +18,7 @@
* \ingroup editors
*/
-#ifndef __ED_UNDO_H__
-#define __ED_UNDO_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -89,5 +88,3 @@ struct MemFile *ED_undosys_stack_memfile_get_active(struct UndoStack *ustack);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_UNDO_H__ */
diff --git a/source/blender/editors/include/ED_userpref.h b/source/blender/editors/include/ED_userpref.h
index 1d43009e37c..e588fa31ad5 100644
--- a/source/blender/editors/include/ED_userpref.h
+++ b/source/blender/editors/include/ED_userpref.h
@@ -18,8 +18,7 @@
* \ingroup editors
*/
-#ifndef __ED_USERPREF_H__
-#define __ED_USERPREF_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -30,5 +29,3 @@ void ED_operatortypes_userpref(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_USERPREF_H__ */
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 1f2706957a7..68ae3589064 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_UTIL_H__
-#define __ED_UTIL_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -71,5 +70,3 @@ void unpack_menu(struct bContext *C,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_UTIL_H__ */
diff --git a/source/blender/editors/include/ED_util_imbuf.h b/source/blender/editors/include/ED_util_imbuf.h
index 76171383b49..d142d3d6425 100644
--- a/source/blender/editors/include/ED_util_imbuf.h
+++ b/source/blender/editors/include/ED_util_imbuf.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_UTIL_IMBUF_H__
-#define __ED_UTIL_IMBUF_H__
+#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_sys_types.h"
@@ -48,5 +47,3 @@ bool ED_imbuf_sample_poll(struct bContext *C);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_UTIL_IMBUF_H__ */
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index f656aaf9c07..53fb79bb012 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_UVEDIT_H__
-#define __ED_UVEDIT_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -47,6 +46,7 @@ struct wmKeyConfig;
/* uvedit_ops.c */
void ED_operatortypes_uvedit(void);
+void ED_operatormacros_uvedit(void);
void ED_keymap_uvedit(struct wmKeyConfig *keyconf);
bool ED_uvedit_minmax(const struct Scene *scene,
@@ -114,51 +114,72 @@ bool uvedit_uv_select_test(const struct Scene *scene,
struct BMLoop *l,
const int cd_loop_uv_offset);
/* uv face */
-bool uvedit_face_select_set(const struct Scene *scene,
+void uvedit_face_select_set_with_sticky(const struct SpaceImage *sima,
+ const struct Scene *scene,
+ struct BMEditMesh *em,
+ struct BMFace *efa,
+ const bool select,
+ const bool do_history,
+ const int cd_loop_uv_offset);
+void uvedit_face_select_set(const struct Scene *scene,
struct BMEditMesh *em,
struct BMFace *efa,
const bool select,
const bool do_history,
const int cd_loop_uv_offset);
-bool uvedit_face_select_enable(const struct Scene *scene,
+void uvedit_face_select_enable(const struct Scene *scene,
struct BMEditMesh *em,
struct BMFace *efa,
const bool do_history,
const int cd_loop_uv_offset);
-bool uvedit_face_select_disable(const struct Scene *scene,
+void uvedit_face_select_disable(const struct Scene *scene,
struct BMEditMesh *em,
struct BMFace *efa,
const int cd_loop_uv_offset);
/* uv edge */
-void uvedit_edge_select_set(struct BMEditMesh *em,
- const struct Scene *scene,
+void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima,
+ const struct Scene *scene,
+ struct BMEditMesh *em,
+ struct BMLoop *l,
+ const bool select,
+ const bool do_history,
+ const uint cd_loop_uv_offset);
+void uvedit_edge_select_set(const struct Scene *scene,
+ struct BMEditMesh *em,
struct BMLoop *l,
const bool select,
const bool do_history,
const int cd_loop_uv_offset);
-void uvedit_edge_select_enable(struct BMEditMesh *em,
- const struct Scene *scene,
+void uvedit_edge_select_enable(const struct Scene *scene,
+ struct BMEditMesh *em,
struct BMLoop *l,
const bool do_history,
const int cd_loop_uv_offset);
-void uvedit_edge_select_disable(struct BMEditMesh *em,
- const struct Scene *scene,
+void uvedit_edge_select_disable(const struct Scene *scene,
+ struct BMEditMesh *em,
struct BMLoop *l,
const int cd_loop_uv_offset);
/* uv vert */
-void uvedit_uv_select_set(struct BMEditMesh *em,
- const struct Scene *scene,
+void uvedit_uv_select_set_with_sticky(const struct SpaceImage *sima,
+ const struct Scene *scene,
+ struct BMEditMesh *em,
+ struct BMLoop *l,
+ const bool select,
+ const bool do_history,
+ const uint cd_loop_uv_offset);
+void uvedit_uv_select_set(const struct Scene *scene,
+ struct BMEditMesh *em,
struct BMLoop *l,
const bool select,
const bool do_history,
const int cd_loop_uv_offset);
-void uvedit_uv_select_enable(struct BMEditMesh *em,
- const struct Scene *scene,
+void uvedit_uv_select_enable(const struct Scene *scene,
+ struct BMEditMesh *em,
struct BMLoop *l,
const bool do_history,
const int cd_loop_uv_offset);
-void uvedit_uv_select_disable(struct BMEditMesh *em,
- const struct Scene *scene,
+void uvedit_uv_select_disable(const struct Scene *scene,
+ struct BMEditMesh *em,
struct BMLoop *l,
const int cd_loop_uv_offset);
@@ -174,8 +195,29 @@ bool ED_uvedit_nearest_uv_multi(const struct Scene *scene,
float *dist_sq,
float r_uv[2]);
-void ED_uvedit_get_aspect(
- const struct Scene *scene, struct Object *ob, struct BMesh *em, float *r_aspx, float *r_aspy);
+struct BMFace **ED_uvedit_selected_faces(struct Scene *scene,
+ struct BMesh *bm,
+ int len_max,
+ int *r_faces_len);
+struct BMLoop **ED_uvedit_selected_edges(struct Scene *scene,
+ struct BMesh *bm,
+ int len_max,
+ int *r_edges_len);
+struct BMLoop **ED_uvedit_selected_verts(struct Scene *scene,
+ struct BMesh *bm,
+ int len_max,
+ int *r_verts_len);
+
+void ED_uvedit_get_aspect(struct Object *obedit, float *r_aspx, float *r_aspy);
+
+void ED_uvedit_active_vert_loop_set(struct BMesh *bm, struct BMLoop *l);
+struct BMLoop *ED_uvedit_active_vert_loop_get(struct BMesh *bm);
+
+void ED_uvedit_active_edge_loop_set(struct BMesh *bm, struct BMLoop *l);
+struct BMLoop *ED_uvedit_active_edge_loop_get(struct BMesh *bm);
+
+char ED_uvedit_select_mode_get(const Scene *scene);
+void ED_uvedit_select_sync_flush(const ToolSettings *ts, struct BMEditMesh *em, const bool select);
/* uvedit_unwrap_ops.c */
void ED_uvedit_live_unwrap_begin(struct Scene *scene, struct Object *obedit);
@@ -200,5 +242,3 @@ void ED_uvedit_buttons_register(struct ARegionType *art);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_UVEDIT_H__ */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 5e706856738..ddbea592238 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_VIEW3D_H__
-#define __ED_VIEW3D_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -135,13 +134,13 @@ bool ED_view3d_has_workbench_in_texture_color(const struct Scene *scene,
void ED_view3d_cursor3d_position(struct bContext *C,
const int mval[2],
const bool use_depth,
- float cursor_co[3]);
+ float r_cursor_co[3]);
void ED_view3d_cursor3d_position_rotation(struct bContext *C,
const int mval[2],
const bool use_depth,
enum eV3DCursorOrient orientation,
- float cursor_co[3],
- float cursor_quat[4]);
+ float r_cursor_co[3],
+ float r_cursor_quat[4]);
void ED_view3d_cursor3d_update(struct bContext *C,
const int mval[2],
const bool use_depth,
@@ -150,7 +149,7 @@ void ED_view3d_cursor3d_update(struct bContext *C,
struct Camera *ED_view3d_camera_data_get(struct View3D *v3d, struct RegionView3D *rv3d);
void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist);
-void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], float *dist);
+void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], const float *dist);
void ED_view3d_from_object(
const struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens);
@@ -403,10 +402,10 @@ bool ED_view3d_win_to_segment_clipped(struct Depsgraph *depsgraph,
const bool do_clip);
void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d,
struct Object *ob,
- float pmat[4][4]);
+ float r_pmat[4][4]);
void ED_view3d_ob_project_mat_get_from_obmat(const struct RegionView3D *rv3d,
- float obmat[4][4],
- float pmat[4][4]);
+ const float obmat[4][4],
+ float r_pmat[4][4]);
void ED_view3d_project(const struct ARegion *region, const float world[3], float r_region_co[3]);
bool ED_view3d_unproject(
@@ -460,13 +459,10 @@ void ED_view3d_clipping_calc(struct BoundBox *bb,
const struct ARegion *region,
const struct Object *ob,
const struct rcti *rect);
-void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]);
+void ED_view3d_clipping_local(struct RegionView3D *rv3d, const float mat[4][4]);
bool ED_view3d_clipping_test(const struct RegionView3D *rv3d,
const float co[3],
const bool is_local);
-void ED_view3d_clipping_set(struct RegionView3D *rv3d);
-void ED_view3d_clipping_enable(void);
-void ED_view3d_clipping_disable(void);
float ED_view3d_radius_to_dist_persp(const float angle, const float radius);
float ED_view3d_radius_to_dist_ortho(const float lens, const float radius);
@@ -502,7 +498,7 @@ bool ED_view3d_autodist_simple(struct ARegion *region,
const int mval[2],
float mouse_worldloc[3],
int margin,
- float *force_depth);
+ const float *force_depth);
bool ED_view3d_autodist_depth(struct ARegion *region, const int mval[2], int margin, float *depth);
bool ED_view3d_autodist_depth_seg(struct ARegion *region,
const int mval_sta[2],
@@ -604,8 +600,8 @@ void ED_view3d_draw_setup_view(const struct wmWindowManager *wm,
struct Scene *scene,
struct ARegion *region,
struct View3D *v3d,
- float viewmat[4][4],
- float winmat[4][4],
+ const float viewmat[4][4],
+ const float winmat[4][4],
const struct rcti *rect);
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
@@ -616,11 +612,11 @@ void ED_view3d_update_viewmat(struct Depsgraph *depsgraph,
const struct Scene *scene,
struct View3D *v3d,
struct ARegion *region,
- float viewmat[4][4],
- float winmat[4][4],
+ const float viewmat[4][4],
+ const float winmat[4][4],
const struct rcti *rect,
bool offscreen);
-bool ED_view3d_quat_from_axis_view(const char view, const char view_axis_roll, float quat[4]);
+bool ED_view3d_quat_from_axis_view(const char view, const char view_axis_roll, float r_quat[4]);
bool ED_view3d_quat_to_axis_view(const float viewquat[4],
const float epsilon,
char *r_view,
@@ -679,7 +675,9 @@ void ED_view3d_lock_clear(struct View3D *v3d);
#define VIEW3D_MARGIN 1.4f
#define VIEW3D_DIST_FALLBACK 1.0f
-float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float dist_fallback);
+float ED_view3d_offset_distance(const float mat[4][4],
+ const float ofs[3],
+ const float dist_fallback);
void ED_view3d_distance_set(struct RegionView3D *rv3d, const float dist);
bool ED_view3d_distance_set_from_location(struct RegionView3D *rv3d,
const float dist_co[3],
@@ -700,17 +698,6 @@ float ED_view3d_grid_view_scale(struct Scene *scene,
void ED_scene_draw_fps(const struct Scene *scene, int xoffset, int *yoffset);
-/* view matrix properties utilities */
-/* unused */
-#if 0
-void ED_view3d_operator_properties_viewmat(struct wmOperatorType *ot);
-void ED_view3d_operator_properties_viewmat_set(struct bContext *C, struct wmOperator *op);
-void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op,
- int *winx,
- int *winy,
- float persmat[4][4]);
-#endif
-
/* render */
void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion *region);
void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *area);
@@ -762,5 +749,3 @@ bool ED_view3d_is_region_xr_mirror_active(const struct wmWindowManager *wm,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_VIEW3D_H__ */
diff --git a/source/blender/editors/include/ED_view3d_offscreen.h b/source/blender/editors/include/ED_view3d_offscreen.h
index 11d1aed1e73..2833d205e77 100644
--- a/source/blender/editors/include/ED_view3d_offscreen.h
+++ b/source/blender/editors/include/ED_view3d_offscreen.h
@@ -21,8 +21,7 @@
* \ingroup editors
*/
-#ifndef __ED_VIEW3D_OFFSCREEN_H__
-#define __ED_VIEW3D_OFFSCREEN_H__
+#pragma once
#include "DNA_object_enums.h"
#include "DNA_view3d_types.h"
@@ -49,8 +48,8 @@ void ED_view3d_draw_offscreen(struct Depsgraph *depsgraph,
struct ARegion *region,
int winx,
int winy,
- float viewmat[4][4],
- float winmat[4][4],
+ const float viewmat[4][4],
+ const float winmat[4][4],
bool is_image_render,
bool do_sky,
bool is_persp,
@@ -65,8 +64,8 @@ void ED_view3d_draw_offscreen_simple(struct Depsgraph *depsgraph,
int winx,
int winy,
unsigned int draw_flags,
- float viewmat[4][4],
- float winmat[4][4],
+ const float viewmat[4][4],
+ const float winmat[4][4],
float clip_start,
float clip_end,
bool is_image_render,
@@ -106,5 +105,3 @@ struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Depsgraph *depsgraph,
#ifdef __cplusplus
}
#endif
-
-#endif /* __ED_VIEW3D_H__ */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 050eb62aa80..e8352bc6b21 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -21,8 +21,7 @@
* \ingroup editorui
*/
-#ifndef __UI_INTERFACE_H__
-#define __UI_INTERFACE_H__
+#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_sys_types.h" /* size_t */
@@ -102,7 +101,7 @@ typedef struct uiPopupBlockHandle uiPopupBlockHandle;
/* use for clamping popups within the screen */
#define UI_SCREEN_MARGIN 10
-/* uiBlock->dt and uiBut->dt */
+/** #uiBlock.emboss and #uiBut.emboss */
enum {
UI_EMBOSS = 0, /* use widget style for drawing */
UI_EMBOSS_NONE = 1, /* Nothing, only icon and/or text */
@@ -176,13 +175,6 @@ enum {
UI_RETURN_POPUP_OK = 1 << 5,
};
-/* panel controls */
-enum {
- UI_PNL_SOLID = 1 << 1,
- UI_PNL_CLOSE = 1 << 5,
- UI_PNL_SCALE = 1 << 9,
-};
-
/* but->flag - general state flags. */
enum {
/** Warning, the first 6 flags are internal. */
@@ -301,12 +293,13 @@ enum {
/* 16 to copy ICON_DEFAULT_HEIGHT */
#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_FAC)
-/* Button types, bits stored in 1 value... and a short even!
- * - bits 0-4: bitnr (0-31)
+/**
+ * Button types, bits stored in 1 value... and a short even!
+ * - bits 0-4: #uiBut.bitnr (0-31)
* - bits 5-7: pointer type
* - bit 8: for 'bit'
* - bit 9-15: button type (now 6 bits, 64 types)
- * */
+ */
typedef enum {
UI_BUT_POIN_CHAR = 32,
UI_BUT_POIN_SHORT = 64,
@@ -663,7 +656,7 @@ bool UI_popup_block_name_exists(const struct bScreen *screen, const char *name);
uiBlock *UI_block_begin(const struct bContext *C,
struct ARegion *region,
const char *name,
- short dt);
+ char emboss);
void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2], int r_xy[2]);
void UI_block_end(const struct bContext *C, uiBlock *block);
void UI_block_draw(const struct bContext *C, struct uiBlock *block);
@@ -677,7 +670,7 @@ enum {
};
void UI_block_theme_style_set(uiBlock *block, char theme_style);
char UI_block_emboss_get(uiBlock *block);
-void UI_block_emboss_set(uiBlock *block, char dt);
+void UI_block_emboss_set(uiBlock *block, char emboss);
void UI_block_free(const struct bContext *C, uiBlock *block);
void UI_blocklist_free(const struct bContext *C, struct ListBase *lb);
@@ -1512,7 +1505,7 @@ uiBut *uiDefHotKeyevtButS(uiBlock *block,
short width,
short height,
short *keypoin,
- short *modkeypoin,
+ const short *modkeypoin,
const char *tip);
uiBut *uiDefSearchBut(uiBlock *block,
@@ -1581,7 +1574,13 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
const bool compact);
/* use inside searchfunc to add items */
-bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int state);
+bool UI_search_item_add(uiSearchItems *items,
+ const char *name,
+ void *poin,
+ int iconid,
+ int state,
+ uint8_t name_prefix_offset);
+
void UI_but_func_search_set(uiBut *but,
uiButSearchCreateFn search_create_fn,
uiButSearchUpdateFn search_update_fn,
@@ -2575,5 +2574,3 @@ void UI_interface_tag_script_reload(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __UI_INTERFACE_H__ */
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 0529ee08da6..7b59d45b203 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -21,8 +21,7 @@
* \ingroup editorui
*/
-#ifndef __UI_INTERFACE_ICONS_H__
-#define __UI_INTERFACE_ICONS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -111,5 +110,3 @@ int UI_library_icon_get(const struct ID *id);
#ifdef __cplusplus
}
#endif
-
-#endif /* __UI_INTERFACE_ICONS_H__ */
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index c5c4ca79f14..3f548f98e97 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -21,8 +21,7 @@
* \ingroup editorui
*/
-#ifndef __UI_RESOURCES_H__
-#define __UI_RESOURCES_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -458,5 +457,3 @@ void UI_make_axis_color(const unsigned char *src_col, unsigned char *dst_col, co
#ifdef __cplusplus
}
#endif
-
-#endif /* __UI_RESOURCES_H__ */
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 0ddc45f4878..6e0f4434b7b 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -23,8 +23,7 @@
* \ingroup editorui
*/
-#ifndef __UI_VIEW2D_H__
-#define __UI_VIEW2D_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -288,5 +287,3 @@ void VIEW2D_GGT_navigate_impl(struct wmGizmoGroupType *gzgt, const char *idname)
#ifdef __cplusplus
}
#endif
-
-#endif /* __UI_VIEW2D_H__ */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index bc3d9b59583..a84ca33a7d7 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -44,6 +44,7 @@
#include "BLI_utildefines.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_main.h"
@@ -51,7 +52,6 @@
#include "BKE_screen.h"
#include "BKE_unit.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
@@ -737,8 +737,8 @@ static bool ui_but_update_from_old_block(const bContext *C,
#else
BLI_assert(*but_old_p == NULL || BLI_findindex(&oldblock->buttons, *but_old_p) != -1);
- /* fastpath - avoid loop-in-loop, calling 'ui_but_find_old'
- * as long as old/new buttons are aligned */
+ /* Fast-path - avoid loop-in-loop, calling #ui_but_find_old
+ * as long as old/new buttons are aligned. */
if (LIKELY(*but_old_p && ui_but_equals_old(but, *but_old_p))) {
oldbut = *but_old_p;
}
@@ -897,6 +897,12 @@ bool UI_but_active_only_ex(
}
}
if ((activate == true) || (found == false)) {
+ /* There might still be another active button. */
+ uiBut *old_active = ui_region_find_active_but(region);
+ if (old_active) {
+ ui_but_active_free(C, old_active);
+ }
+
ui_but_activate_event((bContext *)C, region, but);
}
else if ((found == true) && (isactive == false)) {
@@ -1491,7 +1497,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
continue;
}
}
- else if (but->dt != UI_EMBOSS_PULLDOWN) {
+ else if (but->emboss != UI_EMBOSS_PULLDOWN) {
continue;
}
@@ -1505,10 +1511,10 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
}
}
-void ui_but_override_flag(uiBut *but)
+void ui_but_override_flag(Main *bmain, uiBut *but)
{
const uint override_status = RNA_property_override_library_status(
- &but->rnapoin, but->rnaprop, but->rnaindex);
+ bmain, &but->rnapoin, but->rnaprop, but->rnaindex);
if (override_status & RNA_OVERRIDE_STATUS_OVERRIDDEN) {
but->flag |= UI_BUT_OVERRIDEN;
@@ -1738,6 +1744,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
wmWindow *window = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
uiBut *but;
BLI_assert(block->active);
@@ -1766,8 +1773,10 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
}
}
- ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
- ui_but_override_flag(but);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, (scene) ? scene->r.cfra : 0.0f);
+ ui_but_anim_flag(but, &anim_eval_context);
+ ui_but_override_flag(CTX_data_main(C), but);
if (UI_but_is_decorator(but)) {
ui_but_anim_decorate_update_from_flag((uiButDecorator *)but);
}
@@ -2314,7 +2323,7 @@ bool ui_but_is_rna_valid(uiBut *but)
}
/**
- * Checks if the button supports ctrl+mousewheel cycling
+ * Checks if the button supports cycling next/previous menu items (ctrl+mouse-wheel).
*/
bool ui_but_supports_cycling(const uiBut *but)
{
@@ -2804,25 +2813,39 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size)
return str;
}
-static bool ui_set_but_string_eval_num_unit(bContext *C,
- uiBut *but,
- const char *str,
- double *r_value)
+/**
+ * Report a generic error prefix when evaluating a string with #BPY_execute_string_as_number
+ * as the Python error on it's own doesn't provide enough context.
+ */
+#define UI_NUMBER_EVAL_ERROR_PREFIX IFACE_("Error evaluating number, see Info editor for details")
+
+static bool ui_number_from_string_units(
+ bContext *C, const char *str, const int unit_type, const UnitSettings *unit, double *r_value)
+{
+ return user_string_to_number(C, str, unit, unit_type, UI_NUMBER_EVAL_ERROR_PREFIX, r_value);
+}
+
+static bool ui_number_from_string_units_with_but(bContext *C,
+ const char *str,
+ const uiBut *but,
+ double *r_value)
{
+ const int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
const UnitSettings *unit = but->block->unit;
- int type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
- return user_string_to_number(C, str, unit, type, r_value);
+ return ui_number_from_string_units(C, str, unit_type, unit, r_value);
}
static bool ui_number_from_string(bContext *C, const char *str, double *r_value)
{
+ bool ok;
#ifdef WITH_PYTHON
- return BPY_execute_string_as_number(C, NULL, str, true, r_value);
+ ok = BPY_execute_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value);
#else
UNUSED_VARS(C);
*r_value = atof(str);
- return true;
+ ok = true;
#endif
+ return ok;
}
static bool ui_number_from_string_factor(bContext *C, const char *str, double *r_value)
@@ -2856,7 +2879,7 @@ static bool ui_number_from_string_percentage(bContext *C, const char *str, doubl
return ui_number_from_string(C, str, r_value);
}
-bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *r_value)
+bool ui_but_string_eval_number(bContext *C, const uiBut *but, const char *str, double *r_value)
{
if (str[0] == '\0') {
*r_value = 0.0;
@@ -2870,7 +2893,7 @@ bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double
if (ui_but_is_float(but)) {
if (ui_but_is_unit(but)) {
- return ui_set_but_string_eval_num_unit(C, but, str, r_value);
+ return ui_number_from_string_units_with_but(C, str, but, r_value);
}
if (subtype == PROP_FACTOR) {
return ui_number_from_string_factor(C, str, r_value);
@@ -3014,7 +3037,7 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
/* number editing */
double value;
- if (ui_but_string_set_eval_num(C, but, str, &value) == false) {
+ if (ui_but_string_eval_number(C, but, str, &value) == false) {
WM_report_banner_show();
return false;
}
@@ -3086,8 +3109,38 @@ static double soft_range_round_down(double value, double max)
return newmax;
}
+void ui_but_range_set_hard(uiBut *but)
+{
+ if (but->rnaprop) {
+ const PropertyType type = RNA_property_type(but->rnaprop);
+ double hardmin, hardmax;
+
+ /* clamp button range to something reasonable in case
+ * we get -inf/inf from RNA properties */
+ if (type == PROP_INT) {
+ int imin, imax;
+
+ RNA_property_int_range(&but->rnapoin, but->rnaprop, &imin, &imax);
+ hardmin = (imin == INT_MIN) ? -1e4 : imin;
+ hardmax = (imin == INT_MAX) ? 1e4 : imax;
+ }
+ else if (type == PROP_FLOAT) {
+ float fmin, fmax;
+
+ RNA_property_float_range(&but->rnapoin, but->rnaprop, &fmin, &fmax);
+ hardmin = (fmin == -FLT_MAX) ? (float)-1e4 : fmin;
+ hardmax = (fmax == FLT_MAX) ? (float)1e4 : fmax;
+ }
+ else {
+ return;
+ }
+ but->hardmin = hardmin;
+ but->hardmax = hardmax;
+ }
+}
+
/* note: this could be split up into functions which handle arrays and not */
-static void ui_set_but_soft_range(uiBut *but)
+void ui_but_range_set_soft(uiBut *but)
{
/* ideally we would not limit this but practically, its more than
* enough worst case is very long vectors wont use a smart soft-range
@@ -3364,7 +3417,7 @@ void UI_block_region_set(uiBlock *block, ARegion *region)
block->oldblock = oldblock;
}
-uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, short dt)
+uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, char emboss)
{
uiBlock *block;
wmWindow *window;
@@ -3375,7 +3428,7 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
block = MEM_callocN(sizeof(uiBlock), "uiBlock");
block->active = 1;
- block->dt = dt;
+ block->emboss = emboss;
block->evil_C = (void *)C; /* XXX */
if (scn) {
@@ -3414,12 +3467,12 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
char UI_block_emboss_get(uiBlock *block)
{
- return block->dt;
+ return block->emboss;
}
-void UI_block_emboss_set(uiBlock *block, char dt)
+void UI_block_emboss_set(uiBlock *block, char emboss)
{
- block->dt = dt;
+ block->emboss = emboss;
}
void UI_block_theme_style_set(uiBlock *block, char theme_style)
@@ -3507,7 +3560,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
/* only update soft range while not editing */
if (!ui_but_is_editing(but)) {
if ((but->rnaprop != NULL) || (but->poin && (but->pointype & UI_BUT_POIN_TYPES))) {
- ui_set_but_soft_range(but);
+ ui_but_range_set_soft(but);
}
}
@@ -3892,7 +3945,7 @@ static uiBut *ui_def_but(uiBlock *block,
but->tip = tip;
but->disabled_info = block->lockstr;
- but->dt = block->dt;
+ but->emboss = block->emboss;
but->pie_dir = UI_RADIAL_NONE;
but->block = block; /* pointer back, used for frontbuffer status, and picker */
@@ -4426,7 +4479,7 @@ static uiBut *ui_def_but_rna(uiBlock *block,
}
if (type == UI_BTYPE_MENU) {
- if (but->dt == UI_EMBOSS_PULLDOWN) {
+ if (but->emboss == UI_EMBOSS_PULLDOWN) {
ui_but_submenu_enable(block, but);
}
}
@@ -6383,7 +6436,7 @@ uiBut *uiDefHotKeyevtButS(uiBlock *block,
short width,
short height,
short *keypoin,
- short *modkeypoin,
+ const short *modkeypoin,
const char *tip)
{
uiBut *but = ui_def_but(block,
@@ -6553,7 +6606,8 @@ static void operator_enum_search_update_fn(const struct bContext *C,
/* note: need to give the index rather than the
* identifier because the enum can be freed */
if (BLI_strcasestr(item->name, str)) {
- if (!UI_search_item_add(items, item->name, POINTER_FROM_INT(item->value), item->icon, 0)) {
+ if (!UI_search_item_add(
+ items, item->name, POINTER_FROM_INT(item->value), item->icon, 0, 0)) {
break;
}
}
diff --git a/source/blender/editors/interface/interface_align.c b/source/blender/editors/interface/interface_align.c
index 32cae609395..4981ef111e0 100644
--- a/source/blender/editors/interface/interface_align.c
+++ b/source/blender/editors/interface/interface_align.c
@@ -31,6 +31,8 @@
#include "interface_intern.h"
+#include "MEM_guardedalloc.h"
+
#ifdef USE_UIBUT_SPATIAL_ALIGN
/**
@@ -122,26 +124,6 @@ bool ui_but_can_align(const uiBut *but)
(BLI_rctf_size_y(&but->rect) > 0.0f));
}
-int ui_but_align_opposite_to_area_align_get(const ARegion *region)
-{
- const ARegion *align_region = (region->alignment & RGN_SPLIT_PREV && region->prev) ?
- region->prev :
- region;
-
- switch (RGN_ALIGN_ENUM_FROM_MASK(align_region->alignment)) {
- case RGN_ALIGN_TOP:
- return UI_BUT_ALIGN_DOWN;
- case RGN_ALIGN_BOTTOM:
- return UI_BUT_ALIGN_TOP;
- case RGN_ALIGN_LEFT:
- return UI_BUT_ALIGN_RIGHT;
- case RGN_ALIGN_RIGHT:
- return UI_BUT_ALIGN_LEFT;
- }
-
- return 0;
-}
-
/**
* This function checks a pair of buttons (assumed in a same align group),
* and if they are neighbors, set needed data accordingly.
@@ -389,7 +371,7 @@ static void ui_block_align_but_to_region(uiBut *but, const ARegion *region)
rect->xmin = rect->xmax - but_width;
break;
default:
- BLI_assert(0);
+ /* Tabs may be shown in unaligned regions too, they just appear as regular buttons then. */
break;
}
}
@@ -436,7 +418,16 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region)
return;
}
- butal_array = alloca(sizeof(*butal_array) * (size_t)num_buttons);
+ /* Note that this is typically less than ~20, and almost always under ~100.
+ * Even so, we can't ensure this value won't exceed available stack memory.
+ * Fallback to allocation instead of using #alloca, see: T78636. */
+ ButAlign butal_array_buf[256];
+ if (num_buttons <= ARRAY_SIZE(butal_array_buf)) {
+ butal_array = butal_array_buf;
+ }
+ else {
+ butal_array = MEM_mallocN(sizeof(*butal_array) * num_buttons, __func__);
+ }
memset(butal_array, 0, sizeof(*butal_array) * (size_t)num_buttons);
/* Second loop: we initialize our ButAlign data for each button. */
@@ -535,6 +526,9 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region)
}
}
}
+ if (butal_array_buf != butal_array) {
+ MEM_freeN(butal_array);
+ }
}
# undef SIDE_TO_UI_BUT_ALIGN
@@ -545,9 +539,9 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region)
# undef STITCH
# undef MAX_DELTA
-#else
+#else /* !USE_UIBUT_SPATIAL_ALIGN */
-bool ui_but_can_align(uiBut *but)
+bool ui_but_can_align(const uiBut *but)
{
return !ELEM(but->type,
UI_BTYPE_LABEL,
@@ -730,7 +724,7 @@ static void ui_block_align_calc_but(uiBut *first, short nr)
}
}
-void ui_block_align_calc(uiBlock *block)
+void ui_block_align_calc(uiBlock *block, const struct ARegion *UNUSED(region))
{
uiBut *but;
short nr;
@@ -755,4 +749,25 @@ void ui_block_align_calc(uiBlock *block)
}
}
}
-#endif
+
+#endif /* !USE_UIBUT_SPATIAL_ALIGN */
+
+int ui_but_align_opposite_to_area_align_get(const ARegion *region)
+{
+ const ARegion *align_region = (region->alignment & RGN_SPLIT_PREV && region->prev) ?
+ region->prev :
+ region;
+
+ switch (RGN_ALIGN_ENUM_FROM_MASK(align_region->alignment)) {
+ case RGN_ALIGN_TOP:
+ return UI_BUT_ALIGN_DOWN;
+ case RGN_ALIGN_BOTTOM:
+ return UI_BUT_ALIGN_TOP;
+ case RGN_ALIGN_LEFT:
+ return UI_BUT_ALIGN_RIGHT;
+ case RGN_ALIGN_RIGHT:
+ return UI_BUT_ALIGN_LEFT;
+ }
+
+ return 0;
+}
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index b3b3937723a..cc58082cb02 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -33,6 +33,7 @@
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_fcurve_driver.h"
@@ -65,7 +66,7 @@ static FCurve *ui_but_get_fcurve(
but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special);
}
-void ui_but_anim_flag(uiBut *but, float cfra)
+void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context)
{
AnimData *adt;
bAction *act;
@@ -95,6 +96,7 @@ void ui_but_anim_flag(uiBut *but, float cfra)
* we need to correct the frame number to "look inside" the
* remapped action
*/
+ float cfra = anim_eval_context->eval_time;
if (adt) {
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
}
@@ -105,7 +107,9 @@ void ui_but_anim_flag(uiBut *but, float cfra)
/* XXX: this feature is totally broken and useless with NLA */
if (adt == NULL || adt->nla_tracks.first == NULL) {
- if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, cfra)) {
+ const AnimationEvalContext remapped_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, cfra);
+ if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, &remapped_context)) {
but->drawflag |= UI_BUT_ANIMATED_CHANGED;
}
}
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 78e379176cc..46876fca9a5 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -407,7 +407,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
"'%s').label",
idname);
char *expr_result = NULL;
- if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
+ if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
STRNCPY(drawstr, expr_result);
MEM_freeN(expr_result);
}
@@ -560,7 +560,8 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
const bool is_array_component = (is_array && but->rnaindex != -1);
const bool is_whole_array = (is_array && but->rnaindex == -1);
- const uint override_status = RNA_property_override_library_status(ptr, prop, -1);
+ const uint override_status = RNA_property_override_library_status(
+ CTX_data_main(C), ptr, prop, -1);
const bool is_overridable = (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
/* Set the (button_pointer, button_prop)
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 720a5bcff37..df11a78e657 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -773,9 +773,8 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
(float)rect->ymin,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
ibuf->rect,
1.0f,
1.0f,
@@ -867,7 +866,7 @@ static void histogram_draw_one(float r,
}
GPU_line_smooth(true);
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
+ GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE, GPU_ONE, GPU_ONE);
immUniformColor4fv(color);
@@ -1168,7 +1167,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
}
if (scopes->ok && scopes->waveform_1 != NULL) {
- glBlendFunc(GL_ONE, GL_ONE);
+ GPU_blend_set_func(GPU_ONE, GPU_ONE);
GPU_point_size(1.0);
/* LUMA (1 channel) */
@@ -1468,7 +1467,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region),
/* pixel point cloud */
float col[3] = {alpha, alpha, alpha};
- glBlendFunc(GL_ONE, GL_ONE);
+ GPU_blend_set_func(GPU_ONE, GPU_ONE);
GPU_point_size(1.0);
GPU_matrix_push();
@@ -1783,8 +1782,7 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec
UI_draw_roundbox_3ub_alpha(
true, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f, wcol->inner, 255);
- glCullFace(GL_BACK);
- glEnable(GL_CULL_FACE);
+ GPU_face_culling(GPU_CULL_BACK);
/* setup lights */
ui_but_v3_get(but, light);
@@ -1809,7 +1807,7 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec
GPU_batch_draw(sphere);
/* restore */
- glDisable(GL_CULL_FACE);
+ GPU_face_culling(GPU_CULL_NONE);
/* AA circle */
GPUVertFormat *format = immVertexFormat();
@@ -2258,12 +2256,12 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
/* Also add the last points on the right and bottom edges to close off the fill polygon. */
bool add_left_tri = profile->view_rect.xmin < 0.0f;
bool add_bottom_tri = profile->view_rect.ymin < 0.0f;
- uint tot_points = (uint)PROF_N_TABLE(profile->path_len) + 1 + add_left_tri + add_bottom_tri;
+ uint tot_points = (uint)PROF_TABLE_LEN(profile->path_len) + 1 + add_left_tri + add_bottom_tri;
uint tot_triangles = tot_points - 2;
/* Create array of the positions of the table's points. */
float(*table_coords)[2] = MEM_mallocN(sizeof(*table_coords) * tot_points, "table x coords");
- for (i = 0; i < (uint)PROF_N_TABLE(profile->path_len);
+ for (i = 0; i < (uint)PROF_TABLE_LEN(profile->path_len);
i++) { /* Only add the points from the table here. */
table_coords[i][0] = pts[i].x;
table_coords[i][1] = pts[i].y;
@@ -2546,9 +2544,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
rect.ymin + 1,
drawibuf->x,
drawibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_LINEAR,
+ GPU_RGBA8,
+ true,
drawibuf->rect,
1.0f,
1.0f,
diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c
index 93b052b3b69..5da82b5be9c 100644
--- a/source/blender/editors/interface/interface_eyedropper_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_color.c
@@ -39,8 +39,6 @@
#include "RNA_access.h"
-#include "GPU_glew.h"
-
#include "UI_interface.h"
#include "IMB_colormanagement.h"
diff --git a/source/blender/editors/interface/interface_eyedropper_intern.h b/source/blender/editors/interface/interface_eyedropper_intern.h
index cabf997b725..fd60dcb7c86 100644
--- a/source/blender/editors/interface/interface_eyedropper_intern.h
+++ b/source/blender/editors/interface/interface_eyedropper_intern.h
@@ -20,8 +20,7 @@
* Share between interface_eyedropper_*.c files.
*/
-#ifndef __INTERFACE_EYEDROPPER_INTERN_H__
-#define __INTERFACE_EYEDROPPER_INTERN_H__
+#pragma once
/* interface_eyedropper.c */
void eyedropper_draw_cursor_text(const struct bContext *C,
@@ -48,5 +47,3 @@ enum {
EYE_MODAL_POINT_RESET,
EYE_MODAL_POINT_REMOVE_LAST,
};
-
-#endif /* __INTERFACE_EYEDROPPER_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index a2170de8422..791e7ad7bb7 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -47,6 +47,7 @@
#include "PIL_time.h"
+#include "BKE_animsys.h"
#include "BKE_blender_undo.h"
#include "BKE_brush.h"
#include "BKE_colorband.h"
@@ -1393,6 +1394,9 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl
static bool ui_drag_toggle_but_is_supported(const uiBut *but)
{
+ if (but->flag & UI_BUT_DISABLED) {
+ return false;
+ }
if (ui_but_is_bool(but)) {
return true;
}
@@ -1764,21 +1768,21 @@ static void ui_selectcontext_apply(bContext *C,
RNA_property_int_range(&but->rnapoin, prop, &min.i, &max.i);
}
else if (rna_type == PROP_ENUM) {
- /* not a delta infact */
+ /* Not a delta in fact. */
delta.i = RNA_property_enum_get(&but->rnapoin, prop);
}
else if (rna_type == PROP_BOOLEAN) {
if (is_array) {
- /* not a delta infact */
+ /* Not a delta in fact. */
delta.b = RNA_property_boolean_get_index(&but->rnapoin, prop, index);
}
else {
- /* not a delta infact */
+ /* Not a delta in fact. */
delta.b = RNA_property_boolean_get(&but->rnapoin, prop);
}
}
else if (rna_type == PROP_POINTER) {
- /* not a delta infact */
+ /* Not a delta in fact. */
delta.p = RNA_property_pointer_get(&but->rnapoin, prop);
}
@@ -2376,7 +2380,7 @@ static void ui_but_paste_numeric_value(bContext *C,
{
double value;
- if (ui_but_string_set_eval_num(C, but, buf_paste, &value)) {
+ if (ui_but_string_eval_number(C, but, buf_paste, &value)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
data->value = value;
ui_but_string_set(C, but, buf_paste);
@@ -4401,7 +4405,7 @@ static int ui_do_but_TEX(
if (ELEM(event->type, EVT_PADENTER, EVT_RETKEY) && (!UI_but_is_utf8(but))) {
/* pass - allow filesel, enter to execute */
}
- else if (but->dt == UI_EMBOSS_NONE && !event->ctrl) {
+ else if (but->emboss == UI_EMBOSS_NONE && !event->ctrl) {
/* pass */
}
else {
@@ -7142,7 +7146,7 @@ static int ui_do_but_CURVEPROFILE(
dist_min_sq = square_f(U.dpi_fac * 8.0f); /* 8 pixel radius from each table point. */
/* Loop through the path's high resolution table and find what's near the click. */
- for (int i = 1; i <= PROF_N_TABLE(profile->path_len); i++) {
+ for (int i = 1; i <= PROF_TABLE_LEN(profile->path_len); i++) {
copy_v2_v2(f_xy_prev, f_xy);
BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &table[i].x);
@@ -8009,6 +8013,9 @@ static void button_activate_init(bContext *C,
{
uiHandleButtonData *data;
+ /* Only ever one active button! */
+ BLI_assert(ui_region_find_active_but(region) == NULL);
+
/* setup struct */
data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData");
data->wm = CTX_wm_manager(C);
@@ -8420,6 +8427,9 @@ void UI_context_update_anim_flag(const bContext *C)
{
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
+ struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, (scene) ? scene->r.cfra : 0.0f);
uiBlock *block;
uiBut *but, *activebut;
@@ -8429,8 +8439,8 @@ void UI_context_update_anim_flag(const bContext *C)
for (block = region->uiblocks.first; block; block = block->next) {
for (but = block->buttons.first; but; but = but->next) {
- ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
- ui_but_override_flag(but);
+ ui_but_anim_flag(but, &anim_eval_context);
+ ui_but_override_flag(CTX_data_main(C), but);
if (UI_but_is_decorator(but)) {
ui_but_anim_decorate_update_from_flag((uiButDecorator *)but);
}
@@ -8908,6 +8918,11 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
/* for jumping to the next button with tab while text editing */
if (post_but) {
+ /* The post_but still has previous ranges (without the changes in active button considered),
+ * needs refreshing the ranges. */
+ ui_but_range_set_soft(post_but);
+ ui_but_range_set_hard(post_but);
+
button_activate_init(C, region, post_but, post_type);
}
else if (!((event->type == EVT_BUT_CANCEL) && (event->val == 1))) {
@@ -8947,11 +8962,11 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi
my = event->y;
ui_window_to_block(region, listbox->block, &mx, &my);
- /* convert pan to scrollwheel */
+ /* Convert pan to scroll-wheel. */
if (type == MOUSEPAN) {
ui_pan_to_scroll(event, &type, &val);
- /* if type still is mousepan, we call it handled, since delta-y accumulate */
+ /* If type still is mouse-pan, we call it handled, since delta-y accumulate. */
/* also see wm_event_system.c do_wheel_ui hack */
if (type == MOUSEPAN) {
retval = WM_UI_HANDLER_BREAK;
@@ -9678,7 +9693,7 @@ static int ui_handle_menu_event(bContext *C,
int type = event->type;
int val = event->val;
- /* convert pan to scrollwheel */
+ /* Convert pan to scroll-wheel. */
if (type == MOUSEPAN) {
ui_pan_to_scroll(event, &type, &val);
}
@@ -9703,7 +9718,7 @@ static int ui_handle_menu_event(bContext *C,
case EVT_PAGEDOWNKEY:
case EVT_HOMEKEY:
case EVT_ENDKEY:
- /* arrowkeys: only handle for block_loop blocks */
+ /* Arrow-keys: only handle for block_loop blocks. */
if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
/* pass */
}
@@ -9711,7 +9726,7 @@ static int ui_handle_menu_event(bContext *C,
int type = event->type;
int val = event->val;
- /* convert pan to scrollwheel */
+ /* Convert pan to scroll-wheel. */
if (type == MOUSEPAN) {
ui_pan_to_scroll(event, &type, &val);
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index e1f72cd2898..a7b7bad2fe6 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -31,6 +31,7 @@
#include "GPU_immediate.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
+#include "GPU_texture.h"
#include "BLI_blenlib.h"
#include "BLI_fileops_types.h"
@@ -134,7 +135,7 @@ typedef struct DrawInfo {
} DrawInfo;
typedef struct IconTexture {
- GLuint id[2];
+ struct GPUTexture *tex[2];
int num_textures;
int w;
int h;
@@ -151,7 +152,7 @@ typedef struct IconType {
/* Static here to cache results of icon directory scan, so it's not
* scanning the file-system each time the menu is drawn. */
static struct ListBase iconfilelist = {NULL, NULL};
-static IconTexture icongltex = {{0, 0}, 0, 0, 0, 0.0f, 0.0f};
+static IconTexture icongltex = {{NULL, NULL}, 0, 0, 0, 0.0f, 0.0f};
#ifndef WITH_HEADLESS
@@ -802,9 +803,12 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf,
static void free_icons_textures(void)
{
if (icongltex.num_textures > 0) {
- glDeleteTextures(icongltex.num_textures, icongltex.id);
- icongltex.id[0] = 0;
- icongltex.id[1] = 0;
+ for (int i = 0; i < 2; i++) {
+ if (icongltex.tex[i]) {
+ GPU_texture_free(icongltex.tex[i]);
+ icongltex.tex[i] = NULL;
+ }
+ }
icongltex.num_textures = 0;
}
}
@@ -854,69 +858,40 @@ void UI_icons_reload_internal_textures(void)
/* Allocate OpenGL texture. */
icongltex.num_textures = need_icons_with_border ? 2 : 1;
- glGenTextures(icongltex.num_textures, icongltex.id);
/* Note the filter and LOD bias were tweaked to better preserve icon
* sharpness at different UI scales. */
- if (icongltex.id[0]) {
+ if (icongltex.tex[0] == NULL) {
icongltex.w = b32buf->x;
icongltex.h = b32buf->y;
icongltex.invw = 1.0f / b32buf->x;
icongltex.invh = 1.0f / b32buf->y;
- glBindTexture(GL_TEXTURE_2D, icongltex.id[0]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA8,
- b32buf->x,
- b32buf->y,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- b32buf->rect);
- glTexImage2D(GL_TEXTURE_2D,
- 1,
- GL_RGBA8,
- b16buf->x,
- b16buf->y,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- b16buf->rect);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.5f);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
- glBindTexture(GL_TEXTURE_2D, 0);
+ icongltex.tex[0] = GPU_texture_create_nD(b32buf->x,
+ b32buf->y,
+ 0,
+ 2,
+ b32buf->rect,
+ GPU_RGBA8,
+ GPU_DATA_UNSIGNED_BYTE,
+ 0,
+ false,
+ NULL);
+ GPU_texture_add_mipmap(icongltex.tex[0], GPU_DATA_UNSIGNED_BYTE, 1, b16buf->rect);
}
- if (need_icons_with_border && icongltex.id[1]) {
- glBindTexture(GL_TEXTURE_2D, icongltex.id[1]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA8,
- b32buf_border->x,
- b32buf_border->y,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- b32buf_border->rect);
- glTexImage2D(GL_TEXTURE_2D,
- 1,
- GL_RGBA8,
- b16buf_border->x,
- b16buf_border->y,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- b16buf_border->rect);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.5f);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
- glBindTexture(GL_TEXTURE_2D, 0);
+ if (need_icons_with_border && icongltex.tex[1] == NULL) {
+ icongltex.tex[1] = GPU_texture_create_nD(b32buf_border->x,
+ b32buf_border->y,
+ 0,
+ 2,
+ b32buf_border->rect,
+ GPU_RGBA8,
+ GPU_DATA_UNSIGNED_BYTE,
+ 0,
+ false,
+ NULL);
+ GPU_texture_add_mipmap(icongltex.tex[1], GPU_DATA_UNSIGNED_BYTE, 1, b16buf_border->rect);
}
}
@@ -1542,18 +1517,8 @@ static void icon_draw_rect(float x,
immUniform1f("factor", desaturate);
}
- immDrawPixelsTex(&state,
- draw_x,
- draw_y,
- draw_w,
- draw_h,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
- rect,
- 1.0f,
- 1.0f,
- col);
+ immDrawPixelsTex(
+ &state, draw_x, draw_y, draw_w, draw_h, GPU_RGBA8, false, rect, 1.0f, 1.0f, col);
if (ima) {
IMB_freeImBuf(ima);
@@ -1590,28 +1555,27 @@ void UI_icon_draw_cache_begin(void)
g_icon_draw_cache.enabled = true;
}
-static void icon_draw_cache_texture_flush_ex(GLuint texture,
+static void icon_draw_cache_texture_flush_ex(GPUTexture *texture,
IconTextureDrawCall *texture_draw_calls)
{
if (texture_draw_calls->calls == 0) {
return;
}
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture);
-
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR);
GPU_shader_bind(shader);
- int img_loc = GPU_shader_get_uniform(shader, "image");
+ int img_binding = GPU_shader_get_texture_binding(shader, "image");
int data_loc = GPU_shader_get_uniform(shader, "calls_data");
- glUniform1i(img_loc, 0);
- glUniform4fv(data_loc, ICON_DRAW_CACHE_SIZE * 3, (float *)texture_draw_calls->drawcall_cache);
+ GPU_texture_bind(texture, img_binding);
+ GPU_sampler_icon_bind(img_binding);
+ GPU_shader_uniform_vector(
+ shader, data_loc, 4, ICON_DRAW_CACHE_SIZE * 3, (float *)texture_draw_calls->drawcall_cache);
GPU_draw_primitive(GPU_PRIM_TRIS, 6 * texture_draw_calls->calls);
- glBindTexture(GL_TEXTURE_2D, 0);
+ GPU_texture_unbind(texture);
texture_draw_calls->calls = 0;
}
@@ -1634,11 +1598,11 @@ static void icon_draw_cache_flush_ex(bool only_full_caches)
GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
if (!only_full_caches || g_icon_draw_cache.normal.calls == ICON_DRAW_CACHE_SIZE) {
- icon_draw_cache_texture_flush_ex(icongltex.id[0], &g_icon_draw_cache.normal);
+ icon_draw_cache_texture_flush_ex(icongltex.tex[0], &g_icon_draw_cache.normal);
}
if (!only_full_caches || g_icon_draw_cache.border.calls == ICON_DRAW_CACHE_SIZE) {
- icon_draw_cache_texture_flush_ex(icongltex.id[1], &g_icon_draw_cache.border);
+ icon_draw_cache_texture_flush_ex(icongltex.tex[1], &g_icon_draw_cache.border);
}
GPU_blend_set_func_separate(
@@ -1735,28 +1699,32 @@ static void icon_draw_texture(float x,
y1 = iy * icongltex.invh;
y2 = (iy + ih) * icongltex.invh;
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, with_border ? icongltex.id[1] : icongltex.id[0]);
+ GPUTexture *texture = with_border ? icongltex.tex[1] : icongltex.tex[0];
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
GPU_shader_bind(shader);
+ int img_binding = GPU_shader_get_texture_binding(shader, "image");
+ int color_loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR);
+ int rect_tex_loc = GPU_shader_get_uniform(shader, "rect_icon");
+ int rect_geom_loc = GPU_shader_get_uniform(shader, "rect_geom");
+
if (rgb) {
- glUniform4f(
- GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), rgb[0], rgb[1], rgb[2], alpha);
+ GPU_shader_uniform_vector(shader, color_loc, 4, 1, (float[4]){UNPACK3(rgb), alpha});
}
else {
- glUniform4f(
- GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
+ GPU_shader_uniform_vector(shader, color_loc, 4, 1, (float[4]){alpha, alpha, alpha, alpha});
}
- glUniform1i(GPU_shader_get_uniform(shader, "image"), 0);
- glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), x1, y1, x2, y2);
- glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), x, y, x + w, y + h);
+ GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, (float[4]){x1, y1, x2, y2});
+ GPU_shader_uniform_vector(shader, rect_geom_loc, 4, 1, (float[4]){x, y, x + w, y + h});
+
+ GPU_texture_bind(texture, img_binding);
+ GPU_sampler_icon_bind(img_binding);
GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4);
- glBindTexture(GL_TEXTURE_2D, 0);
+ GPU_texture_unbind(texture);
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 8cb485b8fba..41110883729 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -21,8 +21,7 @@
* \ingroup edinterface
*/
-#ifndef __INTERFACE_INTERN_H__
-#define __INTERFACE_INTERN_H__
+#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_rect.h"
@@ -32,6 +31,7 @@
#include "UI_interface.h"
#include "UI_resources.h"
+struct AnimationEvalContext;
struct ARegion;
struct ID;
struct ImBuf;
@@ -219,8 +219,8 @@ struct uiBut {
const char *disabled_info;
BIFIconID icon;
- /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the block */
- char dt;
+ /** emboss: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the #uiBlock.emboss */
+ char emboss;
/** direction in a pie menu, used for collision detection (RadialDirection) */
signed char pie_dir;
/** could be made into a single flag */
@@ -433,8 +433,8 @@ struct uiBlock {
char direction;
/** UI_BLOCK_THEME_STYLE_* */
char theme_style;
- /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to buttons */
- char dt;
+ /** UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to #uiBut.emboss */
+ char emboss;
bool auto_open;
char _pad[5];
double auto_open_last;
@@ -547,10 +547,10 @@ extern void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) ATTR_N
extern char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size);
extern void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL();
extern bool ui_but_string_set(struct bContext *C, uiBut *but, const char *str) ATTR_NONNULL();
-extern bool ui_but_string_set_eval_num(struct bContext *C,
- uiBut *but,
- const char *str,
- double *value) ATTR_NONNULL();
+extern bool ui_but_string_eval_number(struct bContext *C,
+ const uiBut *but,
+ const char *str,
+ double *value) ATTR_NONNULL();
extern int ui_but_string_get_max_length(uiBut *but);
/* Clear & exit the active button's string. */
extern void ui_but_active_string_clear_and_exit(struct bContext *C, uiBut *but) ATTR_NONNULL();
@@ -567,6 +567,9 @@ extern void ui_but_rna_menu_convert_to_panel_type(struct uiBut *but, const char
extern void ui_but_rna_menu_convert_to_menu_type(struct uiBut *but, const char *menu_type);
extern bool ui_but_menu_draw_as_popover(const uiBut *but);
+void ui_but_range_set_hard(uiBut *but);
+void ui_but_range_set_soft(uiBut *but);
+
extern void ui_but_update(uiBut *but);
extern void ui_but_update_edited(uiBut *but);
extern bool ui_but_is_float(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
@@ -579,7 +582,7 @@ extern bool ui_but_supports_cycling(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
extern int ui_but_is_pushed_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT;
extern int ui_but_is_pushed(uiBut *but) ATTR_WARN_UNUSED_RESULT;
-void ui_but_override_flag(uiBut *but);
+void ui_but_override_flag(struct Main *bmain, uiBut *but);
extern void ui_block_bounds_calc(uiBlock *block);
@@ -970,7 +973,7 @@ int ui_but_align_opposite_to_area_align_get(const struct ARegion *region) ATTR_W
void ui_block_align_calc(uiBlock *block, const struct ARegion *region);
/* interface_anim.c */
-void ui_but_anim_flag(uiBut *but, float cfra);
+void ui_but_anim_flag(uiBut *but, const struct AnimationEvalContext *anim_eval_context);
void ui_but_anim_copy_driver(struct bContext *C);
void ui_but_anim_paste_driver(struct bContext *C);
bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen);
@@ -1106,5 +1109,3 @@ bool ui_jump_to_target_button_poll(struct bContext *C);
/* interface_queries.c */
void ui_interface_tag_script_reload_queries(void);
-
-#endif /* __INTERFACE_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 56062601b27..888cacb64eb 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -674,7 +674,7 @@ static void ui_item_array(uiLayout *layout,
/* show checkboxes for rna on a non-emboss block (menu for eg) */
if (type == PROP_BOOLEAN &&
- ELEM(layout->root->block->dt, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) {
+ ELEM(layout->root->block->emboss, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) {
boolarr = MEM_callocN(sizeof(bool) * len, __func__);
RNA_property_boolean_get_array(ptr, prop, boolarr);
}
@@ -937,7 +937,7 @@ static uiBut *ui_item_with_label(uiLayout *layout,
int h,
int flag)
{
- uiLayout *sub;
+ uiLayout *sub = layout;
uiBut *but = NULL;
PropertyType type;
PropertySubType subtype;
@@ -945,11 +945,20 @@ static uiBut *ui_item_with_label(uiLayout *layout,
#ifdef UI_PROP_DECORATE
uiLayout *layout_prop_decorate = NULL;
const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
+ const bool use_prop_decorate = use_prop_sep && (layout->item.flag & UI_ITEM_PROP_DECORATE) &&
+ (layout->item.flag & UI_ITEM_PROP_DECORATE_NO_PAD) == 0;
#endif
- /* Always align item with label since text is already given enough space not to overlap. */
- sub = uiLayoutRow(layout, true);
- UI_block_layout_set_current(block, sub);
+ UI_block_layout_set_current(block, layout);
+
+ /* Only add new row if more than 1 item will be added. */
+ if (name[0] || use_prop_decorate) {
+ /* Also avoid setting 'align' if possible. Set the space to zero instead as aligning a large
+ * number of labels can end up aligning thousands of buttons when displaying key-map search (a
+ * heavy operation), see: T78636. */
+ sub = uiLayoutRow(layout, layout->align);
+ sub->space = 0;
+ }
#ifdef UI_PROP_DECORATE
if (name[0]) {
@@ -1047,11 +1056,8 @@ static uiBut *ui_item_with_label(uiLayout *layout,
#ifdef UI_PROP_DECORATE
/* Only for alignment. */
- if (use_prop_sep) { /* Flag may have been unset meanwhile. */
- if ((layout->item.flag & UI_ITEM_PROP_DECORATE) &&
- (layout->item.flag & UI_ITEM_PROP_DECORATE_NO_PAD) == 0) {
- uiItemL(layout_prop_decorate ? layout_prop_decorate : sub, NULL, ICON_BLANK1);
- }
+ if (use_prop_decorate) { /* Note that sep flag may have been unset meanwhile. */
+ uiItemL(layout_prop_decorate ? layout_prop_decorate : sub, NULL, ICON_BLANK1);
}
#endif /* UI_PROP_DECORATE */
@@ -2327,7 +2333,7 @@ void uiItemFullR(uiLayout *layout,
/* Mark non-embossed textfields inside a listbox. */
if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == UI_BTYPE_TEXT) &&
- (but->dt & UI_EMBOSS_NONE)) {
+ (but->emboss & UI_EMBOSS_NONE)) {
UI_but_flag_enable(but, UI_BUT_LIST_ITEM);
}
@@ -3832,7 +3838,7 @@ static void ui_litem_layout_radial(uiLayout *litem)
bitem->but->rect.xmax += 1.5f * UI_UNIT_X;
/* enable drawing as pie item if supported by widget */
if (ui_item_is_radial_drawable(bitem)) {
- bitem->but->dt = UI_EMBOSS_RADIAL;
+ bitem->but->emboss = UI_EMBOSS_RADIAL;
bitem->but->drawflag |= UI_BUT_ICON_LEFT;
}
}
@@ -5036,7 +5042,7 @@ float uiLayoutGetUnitsY(uiLayout *layout)
int uiLayoutGetEmboss(uiLayout *layout)
{
if (layout->emboss == UI_EMBOSS_UNDEFINED) {
- return layout->root->block->dt;
+ return layout->root->block->emboss;
}
return layout->emboss;
}
@@ -5412,7 +5418,7 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
}
if (layout->emboss != UI_EMBOSS_UNDEFINED) {
- but->dt = layout->emboss;
+ but->emboss = layout->emboss;
}
}
@@ -5565,6 +5571,26 @@ void UI_menutype_draw(bContext *C, MenuType *mt, struct uiLayout *layout)
}
}
+static bool ui_layout_has_panel_label(const uiLayout *layout, const PanelType *pt)
+{
+ LISTBASE_FOREACH (uiItem *, subitem, &layout->items) {
+ if (subitem->type == ITEM_BUTTON) {
+ uiButtonItem *bitem = (uiButtonItem *)subitem;
+ if (!(bitem->but->flag & UI_HIDDEN) && STREQ(bitem->but->str, pt->label)) {
+ return true;
+ }
+ }
+ else {
+ uiLayout *litem = (uiLayout *)subitem;
+ if (ui_layout_has_panel_label(litem, pt)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout, bool show_header)
{
Panel *panel = MEM_callocN(sizeof(Panel), "popover panel");
@@ -5581,7 +5607,13 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout,
pt->draw_header(C, panel);
panel->layout = NULL;
}
- uiItemL(row, CTX_IFACE_(pt->translation_context, pt->label), ICON_NONE);
+
+ /* draw_header() is often used to add a checkbox to the header. If we add the label like below
+ * the label is disconnected from the checkbox, adding a weird looking gap. As workaround, let
+ * the checkbox add the label instead. */
+ if (!ui_layout_has_panel_label(row, pt)) {
+ uiItemL(row, CTX_IFACE_(pt->translation_context, pt->label), ICON_NONE);
+ }
}
panel->layout = layout;
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 83506fd5d5e..5a49f3e70d0 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -510,7 +510,8 @@ static bool override_type_set_button_poll(bContext *C)
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- const uint override_status = RNA_property_override_library_status(&ptr, prop, index);
+ const uint override_status = RNA_property_override_library_status(
+ CTX_data_main(C), &ptr, prop, index);
return (ptr.data && prop && (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE));
}
@@ -556,7 +557,7 @@ static int override_type_set_button_exec(bContext *C, wmOperator *op)
}
IDOverrideLibraryPropertyOperation *opop = RNA_property_override_property_operation_get(
- &ptr, prop, operation, index, true, NULL, &created);
+ CTX_data_main(C), &ptr, prop, operation, index, true, NULL, &created);
if (!created) {
opop->operation = operation;
}
@@ -610,7 +611,8 @@ static bool override_remove_button_poll(bContext *C)
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- const uint override_status = RNA_property_override_library_status(&ptr, prop, index);
+ const uint override_status = RNA_property_override_library_status(
+ CTX_data_main(C), &ptr, prop, index);
return (ptr.data && ptr.owner_id && prop && (override_status & RNA_OVERRIDE_STATUS_OVERRIDDEN));
}
@@ -627,7 +629,7 @@ static int override_remove_button_exec(bContext *C, wmOperator *op)
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
ID *id = ptr.owner_id;
- IDOverrideLibraryProperty *oprop = RNA_property_override_property_find(&ptr, prop, &id);
+ IDOverrideLibraryProperty *oprop = RNA_property_override_property_find(bmain, &ptr, prop, &id);
BLI_assert(oprop != NULL);
BLI_assert(id != NULL && id->override_library != NULL);
@@ -1806,7 +1808,7 @@ static void UI_OT_drop_color(wmOperatorType *ot)
ot->flag = OPTYPE_INTERNAL;
RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0);
- RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected ");
+ RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected");
}
/** \} */
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 95c804eaccb..799a3b7fd5e 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -321,7 +321,7 @@ void UI_list_panel_unique_str(Panel *panel, char *r_name)
* Remove the #uiBlock corresponding to a panel. The lookup is needed because panels don't store
* a reference to their corresponding #uiBlock.
*/
-static void panel_free_block(ARegion *region, Panel *panel)
+static void panel_free_block(const bContext *C, ARegion *region, Panel *panel)
{
BLI_assert(panel->type);
@@ -334,7 +334,7 @@ static void panel_free_block(ARegion *region, Panel *panel)
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
if (STREQ(block->name, block_name)) {
BLI_remlink(&region->uiblocks, block);
- UI_block_free(NULL, block);
+ UI_block_free(C, block);
break; /* Only delete one block for this panel. */
}
}
@@ -347,15 +347,15 @@ static void panel_free_block(ARegion *region, Panel *panel)
* \note The only panels that should need to be deleted at runtime are panels with the
* #PNL_INSTANCED flag set.
*/
-static void panel_delete(ARegion *region, ListBase *panels, Panel *panel)
+static void panel_delete(const bContext *C, ARegion *region, ListBase *panels, Panel *panel)
{
/* Recursively delete children. */
LISTBASE_FOREACH_MUTABLE (Panel *, child, &panel->children) {
- panel_delete(region, &panel->children, child);
+ panel_delete(C, region, &panel->children, child);
}
BLI_freelistN(&panel->children);
- panel_free_block(region, panel);
+ panel_free_block(C, region, panel);
BLI_remlink(panels, panel);
if (panel->activedata) {
@@ -386,7 +386,7 @@ void UI_panels_free_instanced(bContext *C, ARegion *region)
}
/* Free the panel and its sub-panels. */
- panel_delete(region, &region->panels, panel);
+ panel_delete(C, region, &region->panels, panel);
}
}
}
@@ -878,79 +878,8 @@ void UI_draw_icon_tri(float x, float y, char dir, const float color[4])
}
}
-static void ui_draw_anti_x(uint pos, float x1, float y1, float x2, float y2)
-{
-
- /* set antialias line */
- GPU_line_smooth(true);
- GPU_blend(true);
-
- GPU_line_width(2.0);
-
- immBegin(GPU_PRIM_LINES, 4);
-
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x2, y2);
-
- immVertex2f(pos, x1, y2);
- immVertex2f(pos, x2, y1);
-
- immEnd();
-
- GPU_line_smooth(false);
- GPU_blend(false);
-}
-
-/* x 'icon' for panel header */
-static void ui_draw_x_icon(uint pos, float x, float y)
-{
-
- ui_draw_anti_x(pos, x, y, x + 9.375f, y + 9.375f);
-}
-
#define PNL_ICON UI_UNIT_X /* could be UI_UNIT_Y too */
-static void ui_draw_panel_scalewidget(uint pos, const rcti *rect)
-{
- float xmin, xmax, dx;
- float ymin, ymax, dy;
-
- xmin = rect->xmax - PNL_HEADER + 2;
- xmax = rect->xmax - 3;
- ymin = rect->ymin + 3;
- ymax = rect->ymin + PNL_HEADER - 2;
-
- dx = 0.5f * (xmax - xmin);
- dy = 0.5f * (ymax - ymin);
-
- GPU_blend(true);
- immUniformColor4ub(255, 255, 255, 50);
-
- immBegin(GPU_PRIM_LINES, 4);
-
- immVertex2f(pos, xmin, ymin);
- immVertex2f(pos, xmax, ymax);
-
- immVertex2f(pos, xmin + dx, ymin);
- immVertex2f(pos, xmax, ymax - dy);
-
- immEnd();
-
- immUniformColor4ub(0, 0, 0, 50);
-
- immBegin(GPU_PRIM_LINES, 4);
-
- immVertex2f(pos, xmin, ymin + 1);
- immVertex2f(pos, xmax, ymax + 1);
-
- immVertex2f(pos, xmin + dx, ymin + 1);
- immVertex2f(pos, xmax, ymax - dy + 1);
-
- immEnd();
-
- GPU_blend(false);
-}
-
/* For button layout next to label. */
void UI_panel_label_offset(uiBlock *block, int *r_x, int *r_y)
{
@@ -977,12 +906,7 @@ static void ui_draw_aligned_panel_header(
uchar col_title[4];
/* + 0.001f to avoid flirting with float inaccuracy */
- if (panel->control & UI_PNL_CLOSE) {
- pnl_icons = (panel->labelofs + (2.0f * PNL_ICON)) / block->aspect + 0.001f;
- }
- else {
- pnl_icons = (panel->labelofs + (1.1f * PNL_ICON)) / block->aspect + 0.001f;
- }
+ pnl_icons = (panel->labelofs + (1.1f * PNL_ICON)) / block->aspect + 0.001f;
/* draw text label */
panel_title_color_get(show_background, col_title);
@@ -1178,11 +1102,7 @@ void ui_draw_aligned_panel(uiStyle *style,
/* in some occasions, draw a border */
if (panel->flag & PNL_SELECT && !is_subpanel) {
float radius;
- if (panel->control & UI_PNL_SOLID) {
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- radius = 8.0f;
- }
- else if (draw_box_style) {
+ if (draw_box_style) {
UI_draw_roundbox_corner_set(UI_CNR_ALL);
radius = box_wcol->roundness * U.widget_unit;
}
@@ -1233,26 +1153,12 @@ void ui_draw_aligned_panel(uiStyle *style,
}
}
- if (panel->control & UI_PNL_SCALE) {
- ui_draw_panel_scalewidget(pos, rect);
- }
-
immUnbindProgram();
}
uchar col_title[4];
panel_title_color_get(show_background, col_title);
- /* draw optional close icon */
-
- if (panel->control & UI_PNL_CLOSE) {
- const int ofsx = 6;
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3ubv(col_title);
- ui_draw_x_icon(pos, rect->xmin + 2 + ofsx, rect->ymax + 2);
- immUnbindProgram();
- }
-
/* draw collapse icon */
/* itemrect smaller */
@@ -1731,48 +1637,6 @@ void UI_panels_scale(ARegion *region, float new_width)
}
}
-/* ------------ panel merging ---------------- */
-
-static void check_panel_overlap(ARegion *region, Panel *panel)
-{
- Panel *panel_list;
-
- /* also called with (panel == NULL) for clear */
-
- for (panel_list = region->panels.first; panel_list; panel_list = panel_list->next) {
- panel_list->flag &= ~PNL_OVERLAP;
- if (panel && (panel_list != panel)) {
- if (panel_list->runtime_flag & PNL_ACTIVE) {
- float safex = 0.2, safey = 0.2;
-
- if (panel_list->flag & PNL_CLOSEDX) {
- safex = 0.05;
- }
- else if (panel_list->flag & PNL_CLOSEDY) {
- safey = 0.05;
- }
- else if (panel->flag & PNL_CLOSEDX) {
- safex = 0.05;
- }
- else if (panel->flag & PNL_CLOSEDY) {
- safey = 0.05;
- }
-
- if (panel_list->ofsx > panel->ofsx - safex * panel->sizex) {
- if (panel_list->ofsx + panel_list->sizex < panel->ofsx + (1.0f + safex) * panel->sizex) {
- if (panel_list->ofsy > panel->ofsy - safey * panel->sizey) {
- if (panel_list->ofsy + panel_list->sizey <
- panel->ofsy + (1.0f + safey) * panel->sizey) {
- panel_list->flag |= PNL_OVERLAP;
- }
- }
- }
- }
- }
- }
- }
-}
-
/************************ panel dragging ****************************/
#define DRAG_REGION_PAD (PNL_HEADER * 0.5)
@@ -1813,7 +1677,6 @@ static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
dy += ((float)region->v2d.cur.ymin - data->start_cur_ymin);
panel->ofsx = data->startofsx + round_fl_to_int(dx);
panel->ofsy = data->startofsy + round_fl_to_int(dy);
- check_panel_overlap(region, panel);
if (align) {
uiAlignPanelStep(area, region, 0.2f, true);
@@ -1846,13 +1709,6 @@ static uiPanelMouseState ui_panel_mouse_state_get(const uiBlock *block,
}
/* open panel */
else if (!(panel->flag & PNL_CLOSEDY)) {
- if (panel->control & UI_PNL_SCALE) {
- if (block->rect.xmax - PNL_HEADER <= mx) {
- if (block->rect.ymin + PNL_HEADER >= my) {
- return PANEL_MOUSE_INSIDE_SCALE;
- }
- }
- }
if ((block->rect.xmin <= mx) && (block->rect.xmax >= mx)) {
if ((block->rect.ymin <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
return PANEL_MOUSE_INSIDE_CONTENT;
@@ -2038,15 +1894,6 @@ static void ui_handle_panel_header(
button = 1;
}
}
- else if (block->panel->control & UI_PNL_CLOSE) {
- /* whole of header can be used to collapse panel (except top-right corner) */
- if (mx <= block->rect.xmax - 8 - PNL_ICON) {
- button = 2;
- }
- // else if (mx <= block->rect.xmin + 10 + 2 * PNL_ICON + 2) {
- // button = 1;
- //}
- }
else if (mx < rect_leftmost) {
button = 1;
}
@@ -2847,51 +2694,6 @@ int ui_handler_panel_region(bContext *C,
break;
}
}
- else if (event->type == EVT_ESCKEY) {
- /*XXX 2.50*/
-#if 0
- if (block->handler) {
- rem_blockhandler(area, block->handler);
- ED_region_tag_redraw(region);
- retval = WM_UI_HANDLER_BREAK;
- }
-#endif
- }
- else if (event->type == EVT_PADPLUSKEY || event->type == EVT_PADMINUS) {
-#if 0 /* XXX make float panel exception? */
- int zoom = 0;
-
- /* if panel is closed, only zoom if mouse is over the header */
- if (panel->flag & (PNL_CLOSEDX | PNL_CLOSEDY)) {
- if (inside_header) {
- zoom = 1;
- }
- }
- else {
- zoom = 1;
- }
-
- if (zoom) {
- ScrArea *area = CTX_wm_area(C);
- SpaceLink *sl = area->spacedata.first;
-
- if (area->spacetype != SPACE_PROPERTIES) {
- if (!(panel->control & UI_PNL_SCALE)) {
- if (event->type == PADPLUSKEY) {
- sl->blockscale += 0.1;
- }
- else {
- sl->blockscale -= 0.1;
- }
- CLAMP(sl->blockscale, 0.6, 1.0);
-
- ED_region_tag_redraw(region);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
- }
-#endif
- }
}
}
}
@@ -3014,17 +2816,6 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS
/* Set selection state for the panel and its sub-panels, which need to know they are selected
* too so they can be drawn above their parent when it's dragged. */
if (state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) {
- if (data && data->state != PANEL_STATE_ANIMATION) {
- /* XXX:
- * - the panel tabbing function call below (test_add_new_tabs()) has been commented out
- * "It is too easy to do by accident when reordering panels,
- * is very hard to control and use, and has no real benefit." - BillRey
- * Aligorith, 2009Sep
- */
- // test_add_new_tabs(region); // also copies locations of tabs in dragged panel
- check_panel_overlap(region, NULL); /* clears */
- }
-
panel_set_flag_recursive(panel, PNL_SELECT, false);
}
else {
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 40dee22429b..edb5d51a392 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -90,7 +90,7 @@ bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
if (but->flag & UI_SCROLLED) {
return false;
}
- if ((but->type == UI_BTYPE_TEXT) && (but->dt == UI_EMBOSS_NONE) && !labeledit) {
+ if ((but->type == UI_BTYPE_TEXT) && (but->emboss == UI_EMBOSS_NONE) && !labeledit) {
return false;
}
if ((but->type == UI_BTYPE_LISTROW) && labeledit) {
diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.c
index 1f8af7b9e6e..1773a7b3057 100644
--- a/source/blender/editors/interface/interface_region_hud.c
+++ b/source/blender/editors/interface/interface_region_hud.c
@@ -367,7 +367,7 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
ED_area_update_region_sizes(wm, win, area);
}
- ED_region_floating_initialize(region);
+ ED_region_floating_init(region);
ED_region_tag_redraw(region);
/* Reset zoom level (not well supported). */
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 2ad7e517c60..13c85952f52 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -759,7 +759,7 @@ uiBlock *ui_popup_block_refresh(bContext *C,
ui_popup_block_scrolltest(block);
/* adds subwindow */
- ED_region_floating_initialize(region);
+ ED_region_floating_init(region);
/* get winmat now that we actually have the subwindow */
wmGetProjectionMatrix(block->winmat, &region->winrct);
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 5c519368cca..2010d89165e 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -76,6 +76,7 @@ struct uiSearchItems {
void **pointers;
int *icons;
int *states;
+ uint8_t *name_prefix_offsets;
/** Is there any item with an icon? */
bool has_icon;
@@ -117,7 +118,12 @@ typedef struct uiSearchboxData {
* typically #UI_BUT_DISABLED / #UI_BUT_INACTIVE.
* \return false if there is nothing to add.
*/
-bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int state)
+bool UI_search_item_add(uiSearchItems *items,
+ const char *name,
+ void *poin,
+ int iconid,
+ int state,
+ const uint8_t name_prefix_offset)
{
/* hijack for autocomplete */
if (items->autocpl) {
@@ -159,6 +165,15 @@ bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int
items->icons[items->totitem] = iconid;
}
+ if (name_prefix_offset != 0) {
+ /* Lazy initialize, as this isn't used often. */
+ if (items->name_prefix_offsets == NULL) {
+ items->name_prefix_offsets = MEM_callocN(
+ items->maxitem * sizeof(*items->name_prefix_offsets), "search name prefix offsets");
+ }
+ items->name_prefix_offsets[items->totitem] = name_prefix_offset;
+ }
+
/* Limit flags that can be set so flags such as 'UI_SELECT' aren't accidentally set
* which will cause problems, add others as needed. */
BLI_assert(
@@ -184,10 +199,18 @@ int UI_searchbox_size_x(void)
int UI_search_items_find_index(uiSearchItems *items, const char *name)
{
- int i;
- for (i = 0; i < items->totitem; i++) {
- if (STREQ(name, items->names[i])) {
- return i;
+ if (items->name_prefix_offsets != NULL) {
+ for (int i = 0; i < items->totitem; i++) {
+ if (STREQ(name, items->names[i] + items->name_prefix_offsets[i])) {
+ return i;
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < items->totitem; i++) {
+ if (STREQ(name, items->names[i])) {
+ return i;
+ }
}
}
return -1;
@@ -286,7 +309,12 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
search_but->item_active = NULL;
if (data->active != -1) {
- const char *name = data->items.names[data->active];
+ const char *name = data->items.names[data->active] +
+ /* Never include the prefix in the button. */
+ (data->items.name_prefix_offsets ?
+ data->items.name_prefix_offsets[data->active] :
+ 0);
+
const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
@@ -489,7 +517,10 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
int a;
for (a = 0; a < data->items.totitem; a++) {
- const char *name = data->items.names[a];
+ const char *name = data->items.names[a] +
+ /* Never include the prefix in the button. */
+ (data->items.name_prefix_offsets ? data->items.name_prefix_offsets[a] :
+ 0);
const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
data->active = a;
@@ -654,6 +685,10 @@ static void ui_searchbox_region_free_cb(ARegion *region)
MEM_freeN(data->items.icons);
MEM_freeN(data->items.states);
+ if (data->items.name_prefix_offsets != NULL) {
+ MEM_freeN(data->items.name_prefix_offsets);
+ }
+
MEM_freeN(data);
region->regiondata = NULL;
}
@@ -805,7 +840,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearc
}
/* adds subwindow */
- ED_region_floating_initialize(region);
+ ED_region_floating_init(region);
/* notify change and redraw */
ED_region_tag_redraw(region);
@@ -823,6 +858,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearc
data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers");
data->items.icons = MEM_callocN(data->items.maxitem * sizeof(int), "search icons");
data->items.states = MEM_callocN(data->items.maxitem * sizeof(int), "search flags");
+ data->items.name_prefix_offsets = NULL; /* Lazy initialized as needed. */
for (i = 0; i < data->items.maxitem; i++) {
data->items.names[i] = MEM_callocN(but->hardmax + 1, "search pointers");
}
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 46814e11b9e..41b41cb3d75 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -433,7 +433,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
expr_result = BLI_strdup(has_valid_context_error);
}
- else if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
+ else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
if (STREQ(expr_result, "")) {
MEM_freeN(expr_result);
expr_result = NULL;
@@ -490,7 +490,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
expr_result = BLI_strdup(has_valid_context_error);
}
- else if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
+ else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
if (STREQ(expr_result, ".")) {
MEM_freeN(expr_result);
expr_result = NULL;
@@ -594,7 +594,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
shortcut = BLI_strdup(has_valid_context_error);
}
- else if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) {
+ else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
if (expr_result != 0) {
wmKeyMap *keymap = (wmKeyMap *)expr_result;
LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
@@ -659,7 +659,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
/* pass */
}
else if (BPY_execute_string_as_string_and_size(
- C, expr_imports, expr, true, &expr_result, &expr_result_len)) {
+ C, expr_imports, expr, __func__, &expr_result, &expr_result_len)) {
/* pass. */
}
}
@@ -736,7 +736,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
/* pass */
}
- else if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) {
+ else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
if (expr_result != 0) {
{
uiTooltipField *field = text_field_add(data,
@@ -1386,7 +1386,7 @@ static ARegion *ui_tooltip_create_with_data(bContext *C,
}
/* adds subwindow */
- ED_region_floating_initialize(region);
+ ED_region_floating_init(region);
/* notify change and redraw */
ED_region_tag_redraw(region);
diff --git a/source/blender/editors/interface/interface_regions_intern.h b/source/blender/editors/interface/interface_regions_intern.h
index c299562a357..0cb1fee9a92 100644
--- a/source/blender/editors/interface/interface_regions_intern.h
+++ b/source/blender/editors/interface/interface_regions_intern.h
@@ -20,8 +20,7 @@
* Share between interface_region_*.c files.
*/
-#ifndef __INTERFACE_REGIONS_INTERN_H__
-#define __INTERFACE_REGIONS_INTERN_H__
+#pragma once
/* interface_region_menu_popup.c */
uint ui_popup_menu_hash(const char *str);
@@ -29,5 +28,3 @@ uint ui_popup_menu_hash(const char *str);
/* interface_regions_intern.h */
ARegion *ui_region_temp_add(bScreen *screen);
void ui_region_temp_remove(struct bContext *C, bScreen *screen, ARegion *region);
-
-#endif /* __INTERFACE_REGIONS_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index ad5f897e5fe..0708714c659 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -1009,7 +1009,7 @@ static void menu_search_update_fn(const bContext *UNUSED(C),
}
if (index == words_len) {
- if (!UI_search_item_add(items, item->drawwstr_full, item, item->icon, item->state)) {
+ if (!UI_search_item_add(items, item->drawwstr_full, item, item->icon, item->state, 0)) {
break;
}
}
diff --git a/source/blender/editors/interface/interface_template_search_operator.c b/source/blender/editors/interface/interface_template_search_operator.c
index cdf87103587..b8070ccbb25 100644
--- a/source/blender/editors/interface/interface_template_search_operator.c
+++ b/source/blender/editors/interface/interface_template_search_operator.c
@@ -109,7 +109,7 @@ static void operator_search_update_fn(const bContext *C,
}
}
- if (!UI_search_item_add(items, name, ot, ICON_NONE, 0)) {
+ if (!UI_search_item_add(items, name, ot, ICON_NONE, 0, 0)) {
break;
}
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index d8020c96d30..c7d3d7bf501 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -362,17 +362,24 @@ static bool id_search_add(const bContext *C,
*/
char name_ui[MAX_ID_FULL_NAME_UI];
int iconid = ui_id_icon_get(C, id, template_ui->preview);
- bool has_sep_char = (id->lib != NULL);
+ const bool use_lib_prefix = template_ui->preview || iconid;
+ const bool has_sep_char = (id->lib != NULL);
/* When using previews, the library hint (linked, overridden, missing) is added with a
* character prefix, otherwise we can use a icon. */
- BKE_id_full_name_ui_prefix_get(name_ui, id, template_ui->preview, UI_SEP_CHAR);
- if (!template_ui->preview) {
+ int name_prefix_offset;
+ BKE_id_full_name_ui_prefix_get(
+ name_ui, id, use_lib_prefix, UI_SEP_CHAR, &name_prefix_offset);
+ if (!use_lib_prefix) {
iconid = UI_library_icon_get(id);
}
- if (!UI_search_item_add(
- items, name_ui, id, iconid, has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0)) {
+ if (!UI_search_item_add(items,
+ name_ui,
+ id,
+ iconid,
+ has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0,
+ name_prefix_offset)) {
return false;
}
}
@@ -521,7 +528,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
switch (event) {
case UI_ID_BROWSE:
case UI_ID_PIN:
- RNA_warning("warning, id event %d shouldnt come here", event);
+ RNA_warning("warning, id event %d shouldn't come here", event);
break;
case UI_ID_OPEN:
case UI_ID_ADD_NEW:
@@ -558,7 +565,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
case UI_ID_LOCAL:
if (id) {
Main *bmain = CTX_data_main(C);
- if (BKE_lib_override_library_is_enabled() && CTX_wm_window(C)->eventstate->shift) {
+ if (CTX_wm_window(C)->eventstate->shift) {
if (ID_IS_OVERRIDABLE_LIBRARY(id)) {
/* Only remap that specific ID usage to overriding local data-block. */
ID *override_id = BKE_lib_override_library_create_from_id(bmain, id, false);
@@ -568,6 +575,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
/* Assign new pointer, takes care of updates/notifiers */
RNA_id_pointer_create(override_id, &idptr);
}
+ undo_push_label = "Make Library Override";
}
}
else {
@@ -576,11 +584,13 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
/* reassign to get get proper updates/notifiers */
idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
+ undo_push_label = "Make Local";
}
}
- RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
- RNA_property_update(C, &template_ui->ptr, template_ui->prop);
- undo_push_label = "Make Local";
+ if (undo_push_label != NULL) {
+ RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
+ RNA_property_update(C, &template_ui->ptr, template_ui->prop);
+ }
}
break;
case UI_ID_OVERRIDE:
@@ -930,10 +940,8 @@ static void template_ID(const bContext *C,
0,
0,
0,
- BKE_lib_override_library_is_enabled() ?
- TIP_("Direct linked library data-block, click to make local, "
- "Shift + Click to create a library override") :
- TIP_("Direct linked library data-block, click to make local"));
+ TIP_("Direct linked library data-block, click to make local, "
+ "Shift + Click to create a library override"));
if (disabled) {
UI_but_flag_enable(but, UI_BUT_DISABLED);
}
@@ -1836,18 +1844,6 @@ void uiTemplatePathBuilder(uiLayout *layout,
* Template for building the panel layout for the active object's modifiers.
* \{ */
-/**
- * Get the active object or the property region's pinned object.
- */
-static Object *get_context_object(const bContext *C)
-{
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
- if (sbuts != NULL && (sbuts->pinid != NULL) && GS(sbuts->pinid->name) == ID_OB) {
- return (Object *)sbuts->pinid;
- }
- return CTX_data_active_object(C);
-}
-
static void modifier_panel_id(void *md_link, char *r_name)
{
ModifierData *md = (ModifierData *)md_link;
@@ -1859,7 +1855,7 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
ScrArea *sa = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
ListBase *modifiers = &ob->modifiers;
bool panels_match = UI_panel_list_matches_data(region, modifiers, modifier_panel_id);
@@ -1891,8 +1887,9 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
else {
/* The expansion might have been changed elsewhere, so we still need to set it. */
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
- if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED))
+ if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED)) {
UI_panel_set_expand_from_list_data(C, panel);
+ }
}
/* Assuming there's only one group of instanced panels, update the custom data pointers. */
@@ -1952,7 +1949,7 @@ static ListBase *get_constraints(const bContext *C, bool use_bone_constraints)
}
}
else {
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
if (ob != NULL) {
constraints = &ob->constraints;
}
@@ -2036,6 +2033,7 @@ void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_
ScrArea *sa = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
+ Object *ob = ED_object_active_context(C);
ListBase *constraints = get_constraints(C, use_bone_constraints);
/* Switch between the bone panel ID function and the object panel ID function. */
@@ -2051,11 +2049,15 @@ void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_
char panel_idname[MAX_NAME];
panel_id_func(con, panel_idname);
+ /* Create custom data RNA pointer. */
+ PointerRNA *con_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(&ob->id, &RNA_Constraint, con, con_ptr);
+
Panel *new_panel = UI_panel_add_instanced(
- sa, region, &region->panels, panel_idname, i, NULL);
+ sa, region, &region->panels, panel_idname, i, con_ptr);
+
if (new_panel) {
- /* Set the list panel functionality function pointers since we don't do it with
- * python. */
+ /* Set the list panel functionality function pointers since we don't do it with python. */
new_panel->type->set_list_data_expand_flag = set_constraint_expand_flag;
new_panel->type->get_list_data_expand_flag = get_constraint_expand_flag;
new_panel->type->reorder = constraint_reorder;
@@ -2067,8 +2069,25 @@ void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_
else {
/* The expansion might have been changed elsewhere, so we still need to set it. */
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
- if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED))
+ if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED)) {
UI_panel_set_expand_from_list_data(C, panel);
+ }
+ }
+
+ /* Assuming there's only one group of instanced panels, update the custom data pointers. */
+ Panel *panel = region->panels.first;
+ LISTBASE_FOREACH (bConstraint *, con, constraints) {
+ /* Move to the next instanced panel corresponding to the next constraint. */
+ while ((panel->type == NULL) || !(panel->type->flag & PNL_INSTANCED)) {
+ panel = panel->next;
+ BLI_assert(panel != NULL); /* There shouldn't be fewer panels than constraint panels. */
+ }
+
+ PointerRNA *con_ptr = MEM_mallocN(sizeof(PointerRNA), "constraint panel customdata");
+ RNA_pointer_create(&ob->id, &RNA_Constraint, con, con_ptr);
+ UI_panel_custom_data_set(panel, con_ptr);
+
+ panel = panel->next;
}
}
}
@@ -2095,7 +2114,7 @@ void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
ListBase *modifiers = &ob->greasepencil_modifiers;
bool panels_match = UI_panel_list_matches_data(region, modifiers, gpencil_modifier_panel_id);
@@ -2127,8 +2146,9 @@ void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C)
else {
/* The expansion might have been changed elsewhere, so we still need to set it. */
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
- if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED))
+ if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED)) {
UI_panel_set_expand_from_list_data(C, panel);
+ }
}
/* Assuming there's only one group of instanced panels, update the custom data pointers. */
@@ -2183,7 +2203,7 @@ void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
ListBase *shaderfx = &ob->shader_fx;
bool panels_match = UI_panel_list_matches_data(region, shaderfx, shaderfx_panel_id);
@@ -2195,8 +2215,13 @@ void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C)
char panel_idname[MAX_NAME];
shaderfx_panel_id(fx, panel_idname);
+ /* Create custom data RNA pointer. */
+ PointerRNA *fx_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(&ob->id, &RNA_ShaderFx, fx, fx_ptr);
+
Panel *new_panel = UI_panel_add_instanced(
- sa, region, &region->panels, panel_idname, i, NULL);
+ sa, region, &region->panels, panel_idname, i, fx_ptr);
+
if (new_panel != NULL) {
UI_panel_set_expand_from_list_data(C, new_panel);
}
@@ -2205,8 +2230,30 @@ void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C)
else {
/* The expansion might have been changed elsewhere, so we still need to set it. */
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
- if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED))
+ if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED)) {
UI_panel_set_expand_from_list_data(C, panel);
+ }
+ }
+
+ /* Assuming there's only one group of instanced panels, update the custom data pointers. */
+ Panel *panel = region->panels.first;
+ LISTBASE_FOREACH (ShaderFxData *, fx, shaderfx) {
+ const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx->type);
+ if (fxi->panelRegister == NULL) {
+ continue;
+ }
+
+ /* Move to the next instanced panel corresponding to the next modifier. */
+ while ((panel->type == NULL) || !(panel->type->flag & PNL_INSTANCED)) {
+ panel = panel->next;
+ BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
+ }
+
+ PointerRNA *fx_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(&ob->id, &RNA_ShaderFx, fx, fx_ptr);
+ UI_panel_custom_data_set(panel, fx_ptr);
+
+ panel = panel->next;
}
}
}
@@ -4829,6 +4876,7 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
/* Preset selector */
/* There is probably potential to use simpler "uiItemR" functions here, but automatic updating
* after a preset is selected would be more complicated. */
+ row = uiLayoutRow(layout, true);
bt = uiDefBlockBut(
block, CurveProfile_buttons_presets, profile, "Preset", 0, 0, UI_UNIT_X, UI_UNIT_X, "");
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
@@ -7304,6 +7352,9 @@ void uiTemplateCacheFile(uiLayout *layout,
uiItemR(row, &fileptr, "scale", 0, IFACE_("Manual Scale"), ICON_NONE);
}
+ uiItemR(layout, &fileptr, "velocity_name", 0, NULL, ICON_NONE);
+ uiItemR(layout, &fileptr, "velocity_unit", 0, NULL, ICON_NONE);
+
/* TODO: unused for now, so no need to expose. */
#if 0
row = uiLayoutRow(layout, false);
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 2879da39ff1..4a1c7be918e 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -382,6 +382,7 @@ typedef struct CollItemSearch {
int index;
int iconid;
bool is_id;
+ int name_prefix_offset;
uint has_sep_char : 1;
} CollItemSearch;
@@ -432,6 +433,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
}
}
+ int name_prefix_offset = 0;
int iconid = ICON_NONE;
bool has_sep_char = false;
bool is_id = itemptr.type && RNA_struct_is_ID(itemptr.type);
@@ -447,7 +449,8 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
}
else {
const ID *id = itemptr.data;
- BKE_id_full_name_ui_prefix_get(name_buf, itemptr.data, true, UI_SEP_CHAR);
+ BKE_id_full_name_ui_prefix_get(
+ name_buf, itemptr.data, true, UI_SEP_CHAR, &name_prefix_offset);
BLI_STATIC_ASSERT(sizeof(name_buf) >= MAX_ID_FULL_NAME_UI,
"Name string buffer should be big enough to hold full UI ID name");
name = name_buf;
@@ -459,13 +462,14 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
}
if (name) {
- if (skip_filter || BLI_strcasestr(name, str)) {
+ if (skip_filter || BLI_strcasestr(name + name_prefix_offset, str)) {
cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
cis->data = itemptr.data;
cis->name = BLI_strdup(name);
cis->index = i;
cis->iconid = iconid;
cis->is_id = is_id;
+ cis->name_prefix_offset = name_prefix_offset;
cis->has_sep_char = has_sep_char;
BLI_addtail(items_list, cis);
}
@@ -484,11 +488,12 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
for (cis = items_list->first; cis; cis = cis->next) {
/* If no item has an own icon to display, libraries can use the library icons rather than the
* name prefix for showing the library status. */
+ int name_prefix_offset = cis->name_prefix_offset;
if (!has_id_icon && cis->is_id) {
cis->iconid = UI_library_icon_get(cis->data);
/* No need to re-allocate, string should be shorter than before (lib status prefix is
* removed). */
- BKE_id_full_name_ui_prefix_get(name_buf, cis->data, false, UI_SEP_CHAR);
+ BKE_id_full_name_ui_prefix_get(name_buf, cis->data, false, UI_SEP_CHAR, &name_prefix_offset);
BLI_assert(strlen(name_buf) <= MEM_allocN_len(cis->name));
strcpy(cis->name, name_buf);
}
@@ -497,7 +502,8 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
cis->name,
cis->data,
cis->iconid,
- cis->has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0)) {
+ cis->has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0,
+ name_prefix_offset)) {
break;
}
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 74c3bd9eeb5..d38decd28d1 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -53,6 +53,7 @@
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
+#include "GPU_platform.h"
#include "GPU_state.h"
#ifdef WITH_INPUT_IME
@@ -1208,6 +1209,26 @@ void UI_widgetbase_draw_cache_end(void)
GPU_blend(false);
}
+/* Disable cached/instanced drawing and enforce single widget drawing pipeline.
+ * Works around interface artifacts happening on certain driver and hardware
+ * configurations. */
+static bool draw_widgetbase_batch_skip_draw_cache(void)
+{
+ /* MacOS is known to have issues on Mac Mini and MacBook Pro with Intel Iris GPU.
+ * For example, T78307. */
+ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_ANY)) {
+ return true;
+ }
+
+ /* There are also reports that some AMD and Mesa driver configuration suffer from the
+ * same issue, T78803. */
+ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) {
+ return true;
+ }
+
+ return false;
+}
+
static void draw_widgetbase_batch(uiWidgetBase *wtb)
{
wtb->uniform_params.tria_type = wtb->tria1.type;
@@ -1216,7 +1237,7 @@ static void draw_widgetbase_batch(uiWidgetBase *wtb)
copy_v2_v2(wtb->uniform_params.tria1_center, wtb->tria1.center);
copy_v2_v2(wtb->uniform_params.tria2_center, wtb->tria2.center);
- if (g_widget_base_batch.enabled) {
+ if (g_widget_base_batch.enabled && !draw_widgetbase_batch_skip_draw_cache()) {
g_widget_base_batch.params[g_widget_base_batch.count] = wtb->uniform_params;
g_widget_base_batch.count++;
@@ -1335,7 +1356,7 @@ static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect)
static int ui_but_draw_menu_icon(const uiBut *but)
{
- return (but->flag & UI_BUT_ICON_SUBMENU) && (but->dt == UI_EMBOSS_PULLDOWN);
+ return (but->flag & UI_BUT_ICON_SUBMENU) && (but->emboss == UI_EMBOSS_PULLDOWN);
}
/* icons have been standardized... and this call draws in untransformed coordinates */
@@ -1380,7 +1401,7 @@ static void widget_draw_icon(
}
}
else if (ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_DECORATOR)) {
- if (but->flag & UI_BUT_DISABLED) {
+ if (but->flag & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
alpha *= 0.5f;
}
}
@@ -1396,7 +1417,7 @@ static void widget_draw_icon(
but->str && but->str[0] == '\0') {
xs = rect->xmin + 2.0f * ofs;
}
- else if (but->dt == UI_EMBOSS_NONE || but->type == UI_BTYPE_LABEL) {
+ else if (but->emboss == UI_EMBOSS_NONE || but->type == UI_BTYPE_LABEL) {
xs = rect->xmin + 2.0f * ofs;
}
else {
@@ -1515,7 +1536,7 @@ static void ui_text_clip_right_ex(const uiFontStyle *fstyle,
l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, &tmp);
memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
if (r_final_len) {
- *r_final_len = (size_t)(l_end + sep_len);
+ *r_final_len = (size_t)(l_end) + sep_len;
}
}
}
@@ -2354,7 +2375,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
/* pass (even if its a menu toolbar) */
}
else if (ui_block_is_pie_menu(but->block)) {
- if (but->dt == UI_EMBOSS_RADIAL) {
+ if (but->emboss == UI_EMBOSS_RADIAL) {
rect->xmin += 0.3f * U.widget_unit;
}
}
@@ -2382,7 +2403,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
}
else if (but->flag & UI_BUT_DRAG_MULTI) {
bool text_is_edited = ui_but_drag_multi_edit_get(but) != NULL;
- if (text_is_edited) {
+ if (text_is_edited || (but->drawflag & UI_BUT_TEXT_LEFT)) {
rect->xmin += text_padding;
}
}
@@ -2601,18 +2622,19 @@ static void widget_state_numslider(uiWidgetType *wt, int state, int drawflag)
/* labels use theme colors for text */
static void widget_state_option_menu(uiWidgetType *wt, int state, int drawflag)
{
- bTheme *btheme = UI_GetTheme(); /* XXX */
+ const bTheme *btheme = UI_GetTheme();
+
+ const uiWidgetColors *old_wcol = wt->wcol_theme;
+ uiWidgetColors wcol_menu_option = *wt->wcol_theme;
+
+ /* Override the checkbox theme colors to use the menu-back text colors. */
+ copy_v3_v3_uchar(wcol_menu_option.text, btheme->tui.wcol_menu_back.text);
+ copy_v3_v3_uchar(wcol_menu_option.text_sel, btheme->tui.wcol_menu_back.text_sel);
+ wt->wcol_theme = &wcol_menu_option;
- /* call this for option button */
widget_state(wt, state, drawflag);
- /* if not selected we get theme from menu back */
- if (state & UI_SELECT) {
- copy_v3_v3_uchar(wt->wcol.text, btheme->tui.wcol_menu_back.text_sel);
- }
- else {
- copy_v3_v3_uchar(wt->wcol.text, btheme->tui.wcol_menu_back.text);
- }
+ wt->wcol_theme = old_wcol;
}
static void widget_state_nothing(uiWidgetType *wt, int UNUSED(state), int UNUSED(drawflag))
@@ -4483,7 +4505,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
uiWidgetType *wt = NULL;
/* handle menus separately */
- if (but->dt == UI_EMBOSS_PULLDOWN) {
+ if (but->emboss == UI_EMBOSS_PULLDOWN) {
switch (but->type) {
case UI_BTYPE_LABEL:
widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect);
@@ -4496,7 +4518,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
break;
}
}
- else if (but->dt == UI_EMBOSS_NONE) {
+ else if (but->emboss == UI_EMBOSS_NONE) {
/* "nothing" */
switch (but->type) {
case UI_BTYPE_LABEL:
@@ -4507,11 +4529,11 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
break;
}
}
- else if (but->dt == UI_EMBOSS_RADIAL) {
+ else if (but->emboss == UI_EMBOSS_RADIAL) {
wt = widget_type(UI_WTYPE_MENU_ITEM_RADIAL);
}
else {
- BLI_assert(but->dt == UI_EMBOSS);
+ BLI_assert(but->emboss == UI_EMBOSS);
switch (but->type) {
case UI_BTYPE_LABEL:
@@ -4588,7 +4610,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
if ((but->drawflag & (UI_BUT_TEXT_LEFT | UI_BUT_TEXT_RIGHT)) == 0) {
but->drawflag |= UI_BUT_TEXT_LEFT;
}
- /* widget_optionbut() carefully sets the text rectangle for fine tuned paddings. If the
+ /* #widget_optionbut() carefully sets the text rectangle for fine tuned paddings. If the
* text drawing were to add its own padding, DPI and zoom factor would be applied twice
* in the final padding, so it's difficult to control it. */
but->drawflag |= UI_BUT_NO_TEXT_PADDING;
@@ -4761,7 +4783,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
}
if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- if (but->dt != UI_EMBOSS_PULLDOWN) {
+ if (but->emboss != UI_EMBOSS_PULLDOWN) {
disabled = true;
}
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 087bb2cae16..84fe3e13426 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -1471,7 +1471,7 @@ void UI_ThemeClearColor(int colorid)
float col[3];
UI_GetThemeColor3fv(colorid, col);
- GPU_clear_color(col[0], col[1], col[2], 0.0f);
+ GPU_clear_color(col[0], col[1], col[2], 1.0f);
}
void UI_ThemeClearColorAlpha(int colorid, float alpha)
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 0cbf73280a3..3efed43e08c 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -242,7 +242,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
bool tot_changed = false, do_init;
const uiStyle *style = UI_style_get();
- do_init = (v2d->flag & V2D_IS_INITIALISED) == 0;
+ do_init = (v2d->flag & V2D_IS_INIT) == 0;
/* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */
switch (type) {
@@ -374,8 +374,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
break;
}
- /* set initialized flag so that View2D doesn't get reinitialised next time again */
- v2d->flag |= V2D_IS_INITIALISED;
+ /* set initialized flag so that View2D doesn't get reinitialized next time again */
+ v2d->flag |= V2D_IS_INIT;
/* store view size */
v2d->winx = winx;
diff --git a/source/blender/editors/interface/view2d_draw.c b/source/blender/editors/interface/view2d_draw.c
index 0108dafc531..54b25939baf 100644
--- a/source/blender/editors/interface/view2d_draw.c
+++ b/source/blender/editors/interface/view2d_draw.c
@@ -174,26 +174,38 @@ static void get_parallel_lines_draw_steps(const ParallelLinesSet *lines,
}
}
+/**
+ * \param rect_mask: Region size in pixels.
+ */
static void draw_parallel_lines(const ParallelLinesSet *lines,
const rctf *rect,
- const uchar *color,
+ const rcti *rect_mask,
+ const uchar color[3],
char direction)
{
float first;
- uint steps;
+ uint steps, steps_max;
if (direction == 'v') {
get_parallel_lines_draw_steps(lines, rect->xmin, rect->xmax, &first, &steps);
+ steps_max = BLI_rcti_size_x(rect_mask);
}
else {
BLI_assert(direction == 'h');
get_parallel_lines_draw_steps(lines, rect->ymin, rect->ymax, &first, &steps);
+ steps_max = BLI_rcti_size_y(rect_mask);
}
if (steps == 0) {
return;
}
+ if (UNLIKELY(steps >= steps_max)) {
+ /* Note that we could draw a solid color,
+ * however this flickers because of numeric instability when zoomed out. */
+ return;
+ }
+
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -234,12 +246,12 @@ static void draw_parallel_lines(const ParallelLinesSet *lines,
static void view2d_draw_lines_internal(const View2D *v2d,
const ParallelLinesSet *lines,
- const uchar *color,
+ const uchar color[3],
char direction)
{
GPU_matrix_push_projection();
UI_view2d_view_ortho(v2d);
- draw_parallel_lines(lines, &v2d->cur, color, direction);
+ draw_parallel_lines(lines, &v2d->cur, &v2d->mask, color, direction);
GPU_matrix_pop_projection();
}
@@ -248,17 +260,18 @@ static void view2d_draw_lines(const View2D *v2d,
bool display_minor_lines,
char direction)
{
- uchar major_color[3];
- uchar minor_color[3];
- UI_GetThemeColor3ubv(TH_GRID, major_color);
- UI_GetThemeColorShade3ubv(TH_GRID, 16, minor_color);
-
- ParallelLinesSet major_lines;
- major_lines.distance = major_distance;
- major_lines.offset = 0;
- view2d_draw_lines_internal(v2d, &major_lines, major_color, direction);
+ {
+ uchar major_color[3];
+ UI_GetThemeColor3ubv(TH_GRID, major_color);
+ ParallelLinesSet major_lines;
+ major_lines.distance = major_distance;
+ major_lines.offset = 0;
+ view2d_draw_lines_internal(v2d, &major_lines, major_color, direction);
+ }
if (display_minor_lines) {
+ uchar minor_color[3];
+ UI_GetThemeColorShade3ubv(TH_GRID, 16, minor_color);
ParallelLinesSet minor_lines;
minor_lines.distance = major_distance;
minor_lines.offset = major_distance / 2.0f;
@@ -284,9 +297,6 @@ static void draw_horizontal_scale_indicators(const ARegion *region,
return;
}
- GPU_matrix_push_projection();
- wmOrtho2_region_pixelspace(region);
-
float start;
uint steps;
{
@@ -298,8 +308,15 @@ static void draw_horizontal_scale_indicators(const ARegion *region,
UI_view2d_region_to_view_x(v2d, rect->xmax),
&start,
&steps);
+ const uint steps_max = BLI_rcti_size_x(&v2d->mask);
+ if (UNLIKELY(steps >= steps_max)) {
+ return;
+ }
}
+ GPU_matrix_push_projection();
+ wmOrtho2_region_pixelspace(region);
+
const int font_id = BLF_default();
UI_FontThemeColor(font_id, colorid);
@@ -339,9 +356,6 @@ static void draw_vertical_scale_indicators(const ARegion *region,
return;
}
- GPU_matrix_push_projection();
- wmOrtho2_region_pixelspace(region);
-
float start;
uint steps;
{
@@ -353,8 +367,15 @@ static void draw_vertical_scale_indicators(const ARegion *region,
UI_view2d_region_to_view_y(v2d, rect->ymax),
&start,
&steps);
+ const uint steps_max = BLI_rcti_size_y(&v2d->mask);
+ if (UNLIKELY(steps >= steps_max)) {
+ return;
+ }
}
+ GPU_matrix_push_projection();
+ wmOrtho2_region_pixelspace(region);
+
const int font_id = BLF_default();
UI_FontThemeColor(font_id, colorid);
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index a2c83c24e96..d62058699d9 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -56,7 +56,7 @@ static bool view2d_poll(bContext *C)
{
ARegion *region = CTX_wm_region(C);
- return (region != NULL) && (region->v2d.flag & V2D_IS_INITIALISED);
+ return (region != NULL) && (region->v2d.flag & V2D_IS_INIT);
}
/** \} */
@@ -68,7 +68,7 @@ static bool view2d_poll(bContext *C)
/**
* This group of operators come in several forms:
* -# Modal 'dragging' with MMB - where movement of mouse dictates amount to pan view by
- * -# Scrollwheel 'steps' - rolling mousewheel by one step moves view by predefined amount
+ * -# Scroll-wheel 'steps' - rolling mouse-wheel by one step moves view by predefined amount
*
* In order to make sure this works, each operator must define the following RNA-Operator Props:
* - `deltax, deltay` - define how much to move view by (relative to zoom-correction factor)
@@ -475,20 +475,29 @@ static int view_edge_pan_modal(bContext *C, wmOperator *op, const wmEvent *event
* On successful handling, always pass events on to other handlers. */
const int success_retval = OPERATOR_PASS_THROUGH;
- /* Find whether the mouse is beyond X and Y edges. */
+ int outside_padding = RNA_int_get(op->ptr, "outside_padding") * UI_UNIT_X;
+ rcti padding_rect;
+ if (outside_padding != 0) {
+ padding_rect = region->winrct;
+ BLI_rcti_pad(&padding_rect, outside_padding, outside_padding);
+ }
+
int pan_dir_x = 0;
int pan_dir_y = 0;
- if (event->x > region->winrct.xmax - EDGE_PAN_REGION_PAD) {
- pan_dir_x = 1;
- }
- else if (event->x < region->winrct.xmin + EDGE_PAN_REGION_PAD) {
- pan_dir_x = -1;
- }
- if (event->y > region->winrct.ymax - EDGE_PAN_REGION_PAD) {
- pan_dir_y = 1;
- }
- else if (event->y < region->winrct.ymin + EDGE_PAN_REGION_PAD) {
- pan_dir_y = -1;
+ if ((outside_padding == 0) || BLI_rcti_isect_pt(&padding_rect, event->x, event->y)) {
+ /* Find whether the mouse is beyond X and Y edges. */
+ if (event->x > region->winrct.xmax - EDGE_PAN_REGION_PAD) {
+ pan_dir_x = 1;
+ }
+ else if (event->x < region->winrct.xmin + EDGE_PAN_REGION_PAD) {
+ pan_dir_x = -1;
+ }
+ if (event->y > region->winrct.ymax - EDGE_PAN_REGION_PAD) {
+ pan_dir_y = 1;
+ }
+ else if (event->y < region->winrct.ymin + EDGE_PAN_REGION_PAD) {
+ pan_dir_y = -1;
+ }
}
const double current_time = PIL_check_seconds_timer();
@@ -532,6 +541,16 @@ static void VIEW2D_OT_edge_pan(wmOperatorType *ot)
/* operator is modal */
ot->flag = OPTYPE_INTERNAL;
+ RNA_def_int(ot->srna,
+ "outside_padding",
+ 0,
+ 0,
+ 100,
+ "Outside Padding",
+ "Padding around the region in UI units within which panning is activated (0 to "
+ "disable boundary)",
+ 0,
+ 100);
}
#undef EDGE_PAN_REGION_PAD
@@ -738,8 +757,8 @@ static void VIEW2D_OT_scroll_up(wmOperatorType *ot)
/**
* This group of operators come in several forms:
- * -# Scrollwheel 'steps' - rolling mousewheel by one step zooms view by predefined amount.
- * -# Scrollwheel 'steps' + alt + ctrl/shift - zooms view on one axis only (ctrl=x, shift=y).
+ * -# Scroll-wheel 'steps' - rolling mouse-wheel by one step zooms view by predefined amount.
+ * -# Scroll-wheel 'steps' + alt + ctrl/shift - zooms view on one axis only (ctrl=x, shift=y).
* XXX this could be implemented...
* -# Pad +/- Keys - pressing each key moves the zooms the view by a predefined amount.
*
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index 9db1fe31494..238ebffe153 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -158,99 +158,78 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
{
- uiLayout *box;
- uiLayout *row;
- uiLayout *col;
+ uiLayout *box, *row, *col, *sub;
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Manual Transform:"), ICON_NONE);
+ uiItemL(box, IFACE_("Manual Transform"), ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "global_scale", 0, NULL, ICON_NONE);
+ uiItemR(box, imfptr, "global_scale", 0, NULL, ICON_NONE);
/* Scene Options */
box = uiLayoutBox(layout);
row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Scene Options:"), ICON_SCENE_DATA);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "start", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "end", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "xsamples", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "gsamples", 0, NULL, ICON_NONE);
+ uiItemL(row, IFACE_("Scene Options"), ICON_SCENE_DATA);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "sh_open", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(box, false);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "sh_close", 0, NULL, ICON_NONE);
+ sub = uiLayoutColumn(col, true);
+ uiItemR(sub, imfptr, "start", 0, IFACE_("Frame Start"), ICON_NONE);
+ uiItemR(sub, imfptr, "end", 0, IFACE_("End"), ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "xsamples", 0, IFACE_("Samples Transform"), ICON_NONE);
+ uiItemR(col, imfptr, "gsamples", 0, IFACE_("Geometry"), ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "renderable_only", 0, NULL, ICON_NONE);
+ sub = uiLayoutColumn(col, true);
+ uiItemR(sub, imfptr, "sh_open", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(sub, imfptr, "sh_close", UI_ITEM_R_SLIDER, IFACE_("Close"), ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "visible_objects_only", 0, NULL, ICON_NONE);
+ uiItemS(col);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "flatten", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "flatten", 0, NULL, ICON_NONE);
+ sub = uiLayoutColumnWithHeading(col, true, IFACE_("Only"));
+ uiItemR(sub, imfptr, "selected", 0, IFACE_("Selected Objects"), ICON_NONE);
+ uiItemR(sub, imfptr, "renderable_only", 0, IFACE_("Renderable Objects"), ICON_NONE);
+ uiItemR(sub, imfptr, "visible_objects_only", 0, IFACE_("Visible Objects"), ICON_NONE);
/* Object Data */
box = uiLayoutBox(layout);
row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Object Options:"), ICON_OBJECT_DATA);
+ uiItemL(row, IFACE_("Object Options"), ICON_OBJECT_DATA);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "uvs", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(box, false);
- row = uiLayoutRow(box, false);
+ uiItemR(col, imfptr, "uvs", 0, NULL, ICON_NONE);
+ row = uiLayoutRow(col, false);
+ uiLayoutSetActive(row, RNA_boolean_get(imfptr, "uvs"));
uiItemR(row, imfptr, "packuv", 0, NULL, ICON_NONE);
- uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "uvs"));
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "normals", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "vcolors", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "face_sets", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "normals", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "vcolors", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "face_sets", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "curves_as_mesh", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "subdiv_schema", 0, NULL, ICON_NONE);
+ uiItemS(col);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "apply_subdiv", 0, NULL, ICON_NONE);
+ sub = uiLayoutColumnWithHeading(col, true, IFACE_("Subdivisions"));
+ uiItemR(sub, imfptr, "apply_subdiv", 0, IFACE_("Apply"), ICON_NONE);
+ uiItemR(sub, imfptr, "subdiv_schema", 0, IFACE_("Use Schema"), ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "curves_as_mesh", 0, NULL, ICON_NONE);
+ uiItemS(col);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "triangulate", 0, NULL, ICON_NONE);
-
- const bool triangulate = RNA_boolean_get(imfptr, "triangulate");
-
- row = uiLayoutRow(box, false);
- uiLayoutSetEnabled(row, triangulate);
- uiItemR(row, imfptr, "quad_method", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiLayoutSetEnabled(row, triangulate);
- uiItemR(row, imfptr, "ngon_method", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "triangulate", 0, NULL, ICON_NONE);
+ sub = uiLayoutColumn(col, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(imfptr, "triangulate"));
+ uiItemR(sub, imfptr, "quad_method", 0, IFACE_("Method Quads"), ICON_NONE);
+ uiItemR(sub, imfptr, "ngon_method", 0, IFACE_("Polygons"), ICON_NONE);
- /* Object Data */
+ /* Particle Data */
box = uiLayoutBox(layout);
row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Particle Systems:"), ICON_PARTICLE_DATA);
+ uiItemL(row, IFACE_("Particle Systems"), ICON_PARTICLE_DATA);
col = uiLayoutColumn(box, true);
uiItemR(col, imfptr, "export_hair", 0, NULL, ICON_NONE);
@@ -578,28 +557,25 @@ static int get_sequence_len(char *filename, int *ofs)
static void ui_alembic_import_settings(uiLayout *layout, PointerRNA *imfptr)
{
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
uiLayout *box = uiLayoutBox(layout);
uiLayout *row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Manual Transform:"), ICON_NONE);
+ uiItemL(row, IFACE_("Manual Transform"), ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "scale", 0, NULL, ICON_NONE);
+ uiItemR(box, imfptr, "scale", 0, NULL, ICON_NONE);
box = uiLayoutBox(layout);
row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Options:"), ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "relative_path", 0, NULL, ICON_NONE);
+ uiItemL(row, IFACE_("Options"), ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "set_frame_range", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "is_sequence", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "validate_meshes", 0, NULL, ICON_NONE);
+ uiLayout *col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "relative_path", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "set_frame_range", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "is_sequence", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "validate_meshes", 0, NULL, ICON_NONE);
}
static void wm_alembic_import_draw(bContext *UNUSED(C), wmOperator *op)
diff --git a/source/blender/editors/io/io_alembic.h b/source/blender/editors/io/io_alembic.h
index ecd8c1818f8..512f4e4636b 100644
--- a/source/blender/editors/io/io_alembic.h
+++ b/source/blender/editors/io/io_alembic.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __IO_ALEMBIC_H__
-#define __IO_ALEMBIC_H__
+#pragma once
/** \file
* \ingroup editor/io
@@ -28,5 +27,3 @@ struct wmOperatorType;
void WM_OT_alembic_export(struct wmOperatorType *ot);
void WM_OT_alembic_import(struct wmOperatorType *ot);
-
-#endif /* __IO_ALEMBIC_H__ */
diff --git a/source/blender/editors/io/io_cache.h b/source/blender/editors/io/io_cache.h
index c6fc50a236e..be6e31842af 100644
--- a/source/blender/editors/io/io_cache.h
+++ b/source/blender/editors/io/io_cache.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __IO_CACHE_H__
-#define __IO_CACHE_H__
+#pragma once
/** \file
* \ingroup editor/io
@@ -28,5 +27,3 @@ struct wmOperatorType;
void CACHEFILE_OT_open(struct wmOperatorType *ot);
void CACHEFILE_OT_reload(struct wmOperatorType *ot);
-
-#endif /* __IO_CACHE_H__ */
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index c1a4492994a..b91b3b92947 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -253,21 +253,20 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "No objects selected -- Created empty export file");
return OPERATOR_CANCELLED;
}
- else if (export_count < 0) {
+ if (export_count < 0) {
BKE_report(op->reports, RPT_WARNING, "Error during export (see Console)");
return OPERATOR_CANCELLED;
}
- else {
- char buff[100];
- sprintf(buff, "Exported %d Objects", export_count);
- BKE_report(op->reports, RPT_INFO, buff);
- return OPERATOR_FINISHED;
- }
+
+ char buff[100];
+ sprintf(buff, "Exported %d Objects", export_count);
+ BKE_report(op->reports, RPT_INFO, buff);
+ return OPERATOR_FINISHED;
}
static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
{
- uiLayout *bbox, *box, *row, *col, *split;
+ uiLayout *box, *row, *col, *sub;
bool include_animations = RNA_boolean_get(imfptr, "include_animations");
int ui_section = RNA_enum_get(imfptr, "prop_bc_export_ui_section");
@@ -280,161 +279,126 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
bool sampling = animation_type == BC_ANIMATION_EXPORT_SAMPLES;
/* Export Options: */
- box = uiLayoutBox(layout);
-
- row = uiLayoutRow(box, false);
+ row = uiLayoutRow(layout, false);
uiItemR(row, imfptr, "prop_bc_export_ui_section", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- if (ui_section == BC_UI_SECTION_MAIN) {
- /* =================== */
- /* Export Data options */
- /* =================== */
-
- bbox = uiLayoutBox(layout);
- row = uiLayoutRow(bbox, false);
- uiItemL(row, IFACE_("Global Orientation:"), ICON_ORIENTATION_GLOBAL);
- row = uiLayoutRow(bbox, false);
- uiItemR(row, imfptr, "export_global_forward_selection", 0, "", ICON_NONE);
-
- row = uiLayoutRow(bbox, false);
- uiItemR(row, imfptr, "export_global_up_selection", 0, "", ICON_NONE);
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
- row = uiLayoutRow(bbox, false);
- uiItemR(row, imfptr, "apply_global_orientation", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE);
+ if (ui_section == BC_UI_SECTION_MAIN) {
+ /* Export data options. */
+ box = uiLayoutBox(layout);
+ col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "selected", 0, NULL, ICON_NONE);
+ sub = uiLayoutColumn(col, false);
+ uiLayoutSetEnabled(sub, RNA_boolean_get(imfptr, "selected"));
+ uiItemR(sub, imfptr, "include_children", 0, NULL, ICON_NONE);
+ uiItemR(sub, imfptr, "include_armatures", 0, NULL, ICON_NONE);
+ uiItemR(sub, imfptr, "include_shapekeys", 0, NULL, ICON_NONE);
+ box = uiLayoutBox(layout);
row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE);
- uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
+ uiItemL(row, IFACE_("Global Orientation"), ICON_ORIENTATION_GLOBAL);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE);
- uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
+ uiItemR(box, imfptr, "apply_global_orientation", 0, IFACE_("Apply"), ICON_NONE);
row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_shapekeys", 0, NULL, ICON_NONE);
- uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
-
+ uiItemR(row,
+ imfptr,
+ "export_global_forward_selection",
+ UI_ITEM_R_EXPAND,
+ IFACE_("Forward Axis"),
+ ICON_NONE);
row = uiLayoutRow(box, false);
+ uiItemR(
+ row, imfptr, "export_global_up_selection", UI_ITEM_R_EXPAND, IFACE_("Up Axis"), ICON_NONE);
/* Texture options */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Texture Options:"), ICON_TEXTURE_DATA);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE);
+ uiItemL(box, IFACE_("Texture Options"), ICON_TEXTURE_DATA);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "use_texture_copies", 1, NULL, ICON_NONE);
+ col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "use_texture_copies", 0, NULL, ICON_NONE);
+ row = uiLayoutRowWithHeading(col, true, IFACE_("UV"));
+ uiItemR(row, imfptr, "active_uv_only", 0, IFACE_("Only Selected Map"), ICON_NONE);
}
else if (ui_section == BC_UI_SECTION_GEOMETRY) {
- row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Export Data Options:"), ICON_MESH_DATA);
-
- row = uiLayoutRow(box, false);
- split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
+ box = uiLayoutBox(layout);
+ uiItemL(box, IFACE_("Export Data Options"), ICON_MESH_DATA);
- col = uiLayoutColumn(split, false);
- uiItemR(col, imfptr, "apply_modifiers", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(box, false);
- col = uiLayoutColumn(split, false);
- uiItemR(col, imfptr, "export_mesh_type_selection", 0, "", ICON_NONE);
- uiLayoutSetEnabled(col, RNA_boolean_get(imfptr, "apply_modifiers"));
+ uiItemR(col, imfptr, "triangulate", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(box, false);
- uiItemR(col, imfptr, "triangulate", 1, NULL, ICON_NONE);
+ row = uiLayoutRowWithHeading(col, true, IFACE_("Apply Modifiers"));
+ uiItemR(row, imfptr, "apply_modifiers", 0, "", ICON_NONE);
+ sub = uiLayoutColumn(row, false);
+ uiLayoutSetActive(sub, RNA_boolean_get(imfptr, "apply_modifiers"));
+ uiItemR(sub, imfptr, "export_mesh_type_selection", 0, "", ICON_NONE);
- row = uiLayoutRow(box, false);
- split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
- uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
if (RNA_boolean_get(imfptr, "include_animations")) {
- uiItemR(split, imfptr, "export_animation_transformation_type_selection", 0, "", ICON_NONE);
+ uiItemR(col, imfptr, "export_animation_transformation_type_selection", 0, NULL, ICON_NONE);
}
else {
- uiItemR(split, imfptr, "export_object_transformation_type_selection", 0, "", ICON_NONE);
+ uiItemR(col, imfptr, "export_object_transformation_type_selection", 0, NULL, ICON_NONE);
}
}
else if (ui_section == BC_UI_SECTION_ARMATURE) {
/* Armature options */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Armature Options:"), ICON_ARMATURE_DATA);
+ uiItemL(box, IFACE_("Armature Options"), ICON_ARMATURE_DATA);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "deform_bones_only", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "open_sim", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "deform_bones_only", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "open_sim", 0, NULL, ICON_NONE);
}
else if (ui_section == BC_UI_SECTION_ANIMATION) {
+ /* Animation options. */
+ box = uiLayoutBox(layout);
+ uiItemR(box, imfptr, "include_animations", 0, NULL, ICON_NONE);
- /* ====================== */
- /* Animation Data options */
- /* ====================== */
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_animations", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
+ col = uiLayoutColumn(box, false);
+ row = uiLayoutRow(col, false);
+ uiLayoutSetActive(row, include_animations);
uiItemR(row, imfptr, "export_animation_type_selection", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiLayoutSetEnabled(row, include_animations);
- row = uiLayoutRow(box, false);
- split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
- uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
+ uiLayoutSetActive(row, include_animations && animation_type == BC_ANIMATION_EXPORT_SAMPLES);
if (RNA_boolean_get(imfptr, "include_animations")) {
- uiItemR(split, imfptr, "export_animation_transformation_type_selection", 0, "", ICON_NONE);
+ uiItemR(box, imfptr, "export_animation_transformation_type_selection", 0, NULL, ICON_NONE);
}
else {
- uiItemR(split, imfptr, "export_object_transformation_type_selection", 0, "", ICON_NONE);
+ uiItemR(box, imfptr, "export_object_transformation_type_selection", 0, NULL, ICON_NONE);
}
- uiLayoutSetEnabled(row, include_animations && animation_type == BC_ANIMATION_EXPORT_SAMPLES);
- row = uiLayoutColumn(box, false);
+ row = uiLayoutColumn(col, false);
+ uiLayoutSetActive(row,
+ include_animations &&
+ (animation_transformation_type == BC_TRANSFORMATION_TYPE_DECOMPOSED ||
+ animation_type == BC_ANIMATION_EXPORT_KEYS));
uiItemR(row, imfptr, "keep_smooth_curves", 0, NULL, ICON_NONE);
- uiLayoutSetEnabled(row,
- include_animations &&
- (animation_transformation_type == BC_TRANSFORMATION_TYPE_DECOMPOSED ||
- animation_type == BC_ANIMATION_EXPORT_KEYS));
-
- row = uiLayoutColumn(box, false);
- uiItemR(row, imfptr, "sampling_rate", 0, NULL, ICON_NONE);
- uiLayoutSetEnabled(row, sampling && include_animations);
-
- row = uiLayoutColumn(box, false);
- uiItemR(row, imfptr, "keep_keyframes", 0, NULL, ICON_NONE);
- uiLayoutSetEnabled(row, sampling && include_animations);
- row = uiLayoutColumn(box, false);
- uiItemR(row, imfptr, "keep_flat_curves", 0, NULL, ICON_NONE);
- uiLayoutSetEnabled(row, include_animations);
+ sub = uiLayoutColumn(col, false);
+ uiLayoutSetActive(sub, sampling && include_animations);
+ uiItemR(sub, imfptr, "sampling_rate", 0, NULL, ICON_NONE);
+ uiItemR(sub, imfptr, "keep_keyframes", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_all_actions", 0, NULL, ICON_NONE);
- uiLayoutSetEnabled(row, include_animations);
+ sub = uiLayoutColumn(col, false);
+ uiLayoutSetActive(sub, include_animations);
+ uiItemR(sub, imfptr, "keep_flat_curves", 0, NULL, ICON_NONE);
+ uiItemR(sub, imfptr, "include_all_actions", 0, NULL, ICON_NONE);
}
else if (ui_section == BC_UI_SECTION_COLLADA) {
/* Collada options: */
box = uiLayoutBox(layout);
row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Collada Options:"), ICON_MODIFIER);
+ uiItemL(row, IFACE_("Collada Options"), ICON_MODIFIER);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "use_object_instantiation", 1, NULL, ICON_NONE);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "use_blender_profile", 1, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "sort_by_name", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "keep_bind_info", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "limit_precision", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "use_object_instantiation", 1, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "use_blender_profile", 1, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "sort_by_name", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "keep_bind_info", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "limit_precision", 0, NULL, ICON_NONE);
}
}
@@ -465,28 +429,28 @@ void WM_OT_collada_export(wmOperatorType *ot)
struct StructRNA *func = ot->srna;
static const EnumPropertyItem prop_bc_export_mesh_type[] = {
- {BC_MESH_TYPE_VIEW, "view", 0, "View", "Apply modifier's view settings"},
+ {BC_MESH_TYPE_VIEW, "view", 0, "Viewport", "Apply modifier's viewport settings"},
{BC_MESH_TYPE_RENDER, "render", 0, "Render", "Apply modifier's render settings"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem prop_bc_export_global_forward[] = {
- {BC_GLOBAL_FORWARD_X, "X", 0, "X Forward", "Global Forward is positive X Axis"},
- {BC_GLOBAL_FORWARD_Y, "Y", 0, "Y Forward", "Global Forward is positive Y Axis"},
- {BC_GLOBAL_FORWARD_Z, "Z", 0, "Z Forward", "Global Forward is positive Z Axis"},
- {BC_GLOBAL_FORWARD_MINUS_X, "-X", 0, "-X Forward", "Global Forward is negative X Axis"},
- {BC_GLOBAL_FORWARD_MINUS_Y, "-Y", 0, "-Y Forward", "Global Forward is negative Y Axis"},
- {BC_GLOBAL_FORWARD_MINUS_Z, "-Z", 0, "-Z Forward", "Global Forward is negative Z Axis"},
+ {BC_GLOBAL_FORWARD_X, "X", 0, "X", "Global Forward is positive X Axis"},
+ {BC_GLOBAL_FORWARD_Y, "Y", 0, "Y", "Global Forward is positive Y Axis"},
+ {BC_GLOBAL_FORWARD_Z, "Z", 0, "Z", "Global Forward is positive Z Axis"},
+ {BC_GLOBAL_FORWARD_MINUS_X, "-X", 0, "-X", "Global Forward is negative X Axis"},
+ {BC_GLOBAL_FORWARD_MINUS_Y, "-Y", 0, "-Y", "Global Forward is negative Y Axis"},
+ {BC_GLOBAL_FORWARD_MINUS_Z, "-Z", 0, "-Z", "Global Forward is negative Z Axis"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem prop_bc_export_global_up[] = {
- {BC_GLOBAL_UP_X, "X", 0, "X Up", "Global UP is positive X Axis"},
- {BC_GLOBAL_UP_Y, "Y", 0, "Y Up", "Global UP is positive Y Axis"},
- {BC_GLOBAL_UP_Z, "Z", 0, "Z Up", "Global UP is positive Z Axis"},
- {BC_GLOBAL_UP_MINUS_X, "-X", 0, "-X Up", "Global UP is negative X Axis"},
- {BC_GLOBAL_UP_MINUS_Y, "-Y", 0, "-Y Up", "Global UP is negative Y Axis"},
- {BC_GLOBAL_UP_MINUS_Z, "-Z", 0, "-Z Up", "Global UP is negative Z Axis"},
+ {BC_GLOBAL_UP_X, "X", 0, "X", "Global UP is positive X Axis"},
+ {BC_GLOBAL_UP_Y, "Y", 0, "Y", "Global UP is positive Y Axis"},
+ {BC_GLOBAL_UP_Z, "Z", 0, "Z", "Global UP is positive Z Axis"},
+ {BC_GLOBAL_UP_MINUS_X, "-X", 0, "-X", "Global UP is negative X Axis"},
+ {BC_GLOBAL_UP_MINUS_Y, "-Y", 0, "-Y", "Global UP is negative Y Axis"},
+ {BC_GLOBAL_UP_MINUS_Z, "-Z", 0, "-Z", "Global UP is negative Z Axis"},
{0, NULL, 0, NULL, NULL},
};
@@ -619,7 +583,7 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(func,
"deform_bones_only",
false,
- "Deform Bones only",
+ "Deform Bones Only",
"Only export deforming bones with armatures");
RNA_def_boolean(
@@ -672,7 +636,7 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(func,
"keep_flat_curves",
0,
- "All keyed curves",
+ "All Keyed Curves",
"Export also curves which have only one key or are totally flat");
RNA_def_boolean(
@@ -803,45 +767,36 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS);
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports, RPT_ERROR, "Parsing errors in Document (see Blender Console)");
- return OPERATOR_CANCELLED;
- }
+
+ BKE_report(op->reports, RPT_ERROR, "Parsing errors in Document (see Blender Console)");
+ return OPERATOR_CANCELLED;
}
static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
{
- uiLayout *box, *row;
+ uiLayout *box, *col;
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
/* Import Options: */
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Import Data Options:"), ICON_MESH_DATA);
+ uiItemL(box, IFACE_("Import Data Options"), ICON_MESH_DATA);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "import_units", 0, NULL, ICON_NONE);
+ uiItemR(box, imfptr, "import_units", 0, NULL, ICON_NONE);
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, false);
- uiItemL(row, IFACE_("Armature Options:"), ICON_MESH_DATA);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "fix_orientation", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "find_chains", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "auto_connect", 0, NULL, ICON_NONE);
+ uiItemL(box, IFACE_("Armature Options"), ICON_ARMATURE_DATA);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "min_chain_length", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "fix_orientation", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "find_chains", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "auto_connect", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "min_chain_length", 0, NULL, ICON_NONE);
box = uiLayoutBox(layout);
- row = uiLayoutRow(box, false);
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "keep_bind_info", 0, NULL, ICON_NONE);
+ uiItemR(box, imfptr, "keep_bind_info", 0, NULL, ICON_NONE);
}
static void wm_collada_import_draw(bContext *UNUSED(C), wmOperator *op)
diff --git a/source/blender/editors/io/io_collada.h b/source/blender/editors/io/io_collada.h
index 6330fc9639a..5c0a1a8b927 100644
--- a/source/blender/editors/io/io_collada.h
+++ b/source/blender/editors/io/io_collada.h
@@ -21,12 +21,9 @@
* \ingroup editor/io
*/
-#ifndef __IO_COLLADA_H__
-#define __IO_COLLADA_H__
+#pragma once
struct wmOperatorType;
void WM_OT_collada_export(struct wmOperatorType *ot);
void WM_OT_collada_import(struct wmOperatorType *ot);
-
-#endif
diff --git a/source/blender/editors/io/io_ops.h b/source/blender/editors/io/io_ops.h
index 2923e052752..2e6cccbf438 100644
--- a/source/blender/editors/io/io_ops.h
+++ b/source/blender/editors/io/io_ops.h
@@ -21,9 +21,6 @@
* \ingroup editor/io
*/
-#ifndef __IO_OPS_H__
-#define __IO_OPS_H__
+#pragma once
void ED_operatortypes_io(void);
-
-#endif
diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index 262b15c63e5..096dc44c758 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -145,21 +145,23 @@ static void wm_usd_export_draw(bContext *UNUSED(C), wmOperator *op)
uiLayoutSetPropSep(layout, true);
- col = uiLayoutColumn(layout, true);
+ uiLayout *box = uiLayoutBox(layout);
+
+ col = uiLayoutColumn(box, true);
uiItemR(col, ptr, "selected_objects_only", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, true);
+ col = uiLayoutColumn(box, true);
uiItemR(col, ptr, "export_animation", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "export_hair", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "export_uvmaps", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "export_normals", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "export_materials", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(layout, true);
+ col = uiLayoutColumn(box, true);
uiItemR(col, ptr, "evaluation_mode", 0, NULL, ICON_NONE);
- uiLayout *box = uiLayoutBox(layout);
- uiItemL(box, IFACE_("Experimental:"), ICON_NONE);
+ box = uiLayoutBox(layout);
+ uiItemL(box, IFACE_("Experimental"), ICON_NONE);
uiItemR(box, ptr, "use_instancing", 0, NULL, ICON_NONE);
}
diff --git a/source/blender/editors/io/io_usd.h b/source/blender/editors/io/io_usd.h
index c794dc744df..671984b6f34 100644
--- a/source/blender/editors/io/io_usd.h
+++ b/source/blender/editors/io/io_usd.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __IO_USD_H__
-#define __IO_USD_H__
+#pragma once
/** \file
* \ingroup editor/io
@@ -27,5 +26,3 @@
struct wmOperatorType;
void WM_OT_usd_export(struct wmOperatorType *ot);
-
-#endif /* __IO_USD_H__ */
diff --git a/source/blender/editors/lattice/editlattice_select.c b/source/blender/editors/lattice/editlattice_select.c
index 8751a289b9c..49cf4779496 100644
--- a/source/blender/editors/lattice/editlattice_select.c
+++ b/source/blender/editors/lattice/editlattice_select.c
@@ -268,18 +268,17 @@ void LATTICE_OT_select_mirror(wmOperatorType *ot)
* \{ */
static bool lattice_test_bitmap_uvw(
- Lattice *lt, BLI_bitmap *selpoints, int u, int v, int w, const bool selected)
+ Lattice *lt, const BLI_bitmap *selpoints, int u, int v, int w, const bool selected)
{
if ((u < 0 || u >= lt->pntsu) || (v < 0 || v >= lt->pntsv) || (w < 0 || w >= lt->pntsw)) {
return false;
}
- else {
- int i = BKE_lattice_index_from_uvw(lt, u, v, w);
- if (lt->def[i].hide == 0) {
- return (BLI_BITMAP_TEST(selpoints, i) != 0) == selected;
- }
- return false;
+
+ int i = BKE_lattice_index_from_uvw(lt, u, v, w);
+ if (lt->def[i].hide == 0) {
+ return (BLI_BITMAP_TEST(selpoints, i) != 0) == selected;
}
+ return false;
}
static int lattice_select_more_less(bContext *C, const bool select)
diff --git a/source/blender/editors/lattice/lattice_intern.h b/source/blender/editors/lattice/lattice_intern.h
index fe3f35b9223..ee324a3b31e 100644
--- a/source/blender/editors/lattice/lattice_intern.h
+++ b/source/blender/editors/lattice/lattice_intern.h
@@ -21,8 +21,7 @@
* \ingroup edlattice
*/
-#ifndef __LATTICE_INTERN_H__
-#define __LATTICE_INTERN_H__
+#pragma once
/* editlattice_select.c */
void LATTICE_OT_select_all(struct wmOperatorType *ot);
@@ -35,5 +34,3 @@ void LATTICE_OT_select_mirror(struct wmOperatorType *ot);
/* editlattice_tools.c */
void LATTICE_OT_make_regular(struct wmOperatorType *ot);
void LATTICE_OT_flip(struct wmOperatorType *ot);
-
-#endif /* __LATTICE_INTERN_H__ */
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index 767976b5ae6..c19a5b8ef68 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -210,7 +210,7 @@ static void finSelectedSplinePoint(MaskLayer *mask_layer,
*point = NULL;
return;
}
- else if (*point) {
+ if (*point) {
*point = NULL;
}
else {
@@ -319,9 +319,7 @@ static bool add_vertex_extrude(const bContext *C,
if (!mask_layer) {
return false;
}
- else {
- finSelectedSplinePoint(mask_layer, &spline, &point, true);
- }
+ finSelectedSplinePoint(mask_layer, &spline, &point, true);
ED_mask_select_toggle_all(mask, SEL_DESELECT);
@@ -441,7 +439,7 @@ static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *mask_layer,
/* Convert coordinate from normalized space to pixel one.
* TODO(sergey): Make the function more generally available. */
static void mask_point_make_pixel_space(bContext *C,
- float point_normalized[2],
+ const float point_normalized[2],
float point_pixel[2])
{
ScrArea *area = CTX_wm_area(C);
@@ -502,7 +500,7 @@ static int add_vertex_handle_cyclic(
if (is_last_point_active) {
return add_vertex_handle_cyclic_at_point(C, mask, spline, active_point, first_point, co);
}
- else if (is_first_point_active) {
+ if (is_first_point_active) {
return add_vertex_handle_cyclic_at_point(C, mask, spline, active_point, last_point, co);
}
return OPERATOR_PASS_THROUGH;
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 3786ed2789c..12ce358a501 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -753,8 +753,7 @@ void ED_mask_draw_region(
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(
- &state, 0.0f, 0.0f, width, height, GL_RED, GL_FLOAT, GL_NEAREST, buffer, 1.0f, 1.0f, NULL);
+ immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GL_R16F, false, buffer, 1.0f, 1.0f, NULL);
GPU_matrix_pop();
diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h
index 6a45af4d2a6..f6990583383 100644
--- a/source/blender/editors/mask/mask_intern.h
+++ b/source/blender/editors/mask/mask_intern.h
@@ -21,8 +21,7 @@
* \ingroup spclip
*/
-#ifndef __MASK_INTERN_H__
-#define __MASK_INTERN_H__
+#pragma once
struct Mask;
struct bContext;
@@ -130,5 +129,3 @@ void MASK_OT_shape_key_insert(struct wmOperatorType *ot);
void MASK_OT_shape_key_clear(struct wmOperatorType *ot);
void MASK_OT_shape_key_feather_reset(struct wmOperatorType *ot);
void MASK_OT_shape_key_rekey(struct wmOperatorType *ot);
-
-#endif /* __MASK_INTERN_H__ */
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 68dfe0d151f..51f3a94efde 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -1589,12 +1589,12 @@ static int mask_normals_make_consistent_exec(bContext *C, wmOperator *UNUSED(op)
return OPERATOR_CANCELLED;
}
-/* named to match mesh recalc normals */
+/* Named to match mesh recalculate normals. */
void MASK_OT_normals_make_consistent(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Recalc Normals";
- ot->description = "Re-calculate the direction of selected handles";
+ ot->name = "Recalculate Handles";
+ ot->description = "Recalculate the direction of selected handles";
ot->idname = "MASK_OT_normals_make_consistent";
/* api callbacks */
@@ -1710,9 +1710,7 @@ static int mask_hide_view_clear_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MASK_OT_hide_view_clear(wmOperatorType *ot)
@@ -1773,9 +1771,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MASK_OT_hide_view_set(wmOperatorType *ot)
@@ -1827,9 +1823,7 @@ static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MASK_OT_feather_weight_clear(wmOperatorType *ot)
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index c8cddced99c..82d8a1dc85f 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -331,53 +331,52 @@ static int select_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- MaskSplinePointUW *uw;
- if (ED_mask_feather_find_nearest(
- C, mask, co, threshold, &mask_layer, &spline, &point, &uw, NULL)) {
+ MaskSplinePointUW *uw;
- if (extend) {
- mask_layer->act_spline = spline;
- mask_layer->act_point = point;
+ if (ED_mask_feather_find_nearest(
+ C, mask, co, threshold, &mask_layer, &spline, &point, &uw, NULL)) {
- if (uw) {
- uw->flag |= SELECT;
- }
+ if (extend) {
+ mask_layer->act_spline = spline;
+ mask_layer->act_point = point;
+
+ if (uw) {
+ uw->flag |= SELECT;
}
- else if (deselect) {
- if (uw) {
- uw->flag &= ~SELECT;
- }
+ }
+ else if (deselect) {
+ if (uw) {
+ uw->flag &= ~SELECT;
}
- else {
- mask_layer->act_spline = spline;
- mask_layer->act_point = point;
+ }
+ else {
+ mask_layer->act_spline = spline;
+ mask_layer->act_point = point;
- if (uw) {
- if (!(uw->flag & SELECT)) {
- uw->flag |= SELECT;
- }
- else if (toggle) {
- uw->flag &= ~SELECT;
- }
+ if (uw) {
+ if (!(uw->flag & SELECT)) {
+ uw->flag |= SELECT;
+ }
+ else if (toggle) {
+ uw->flag &= ~SELECT;
}
}
+ }
- ED_mask_select_flush_all(mask);
+ ED_mask_select_flush_all(mask);
- DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
+ return OPERATOR_FINISHED;
+ }
+ if (deselect_all) {
+ /* For clip editor tracks, leave deselect all to clip editor. */
+ if (!ED_clip_can_select(C)) {
+ ED_mask_deselect_all(C);
return OPERATOR_FINISHED;
}
- else if (deselect_all) {
- /* For clip editor tracks, leave deselect all to clip editor. */
- if (!ED_clip_can_select(C)) {
- ED_mask_deselect_all(C);
- return OPERATOR_FINISHED;
- }
- }
}
return OPERATOR_PASS_THROUGH;
diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c
index f264e67d35c..74348f2c8cf 100644
--- a/source/blender/editors/mask/mask_shapekey.c
+++ b/source/blender/editors/mask/mask_shapekey.c
@@ -71,9 +71,7 @@ static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MASK_OT_shape_key_insert(wmOperatorType *ot)
@@ -119,9 +117,7 @@ static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MASK_OT_shape_key_clear(wmOperatorType *ot)
@@ -205,9 +201,7 @@ static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MASK_OT_shape_key_feather_reset(wmOperatorType *ot)
@@ -365,9 +359,7 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MASK_OT_shape_key_rekey(wmOperatorType *ot)
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index d18f5de357f..dd4b8146154 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -115,7 +115,7 @@ enum {
BEV_MODAL_SEGMENTS_DOWN,
BEV_MODAL_OFFSET_MODE_CHANGE,
BEV_MODAL_CLAMP_OVERLAP_TOGGLE,
- BEV_MODAL_VERTEX_ONLY_TOGGLE,
+ BEV_MODAL_AFFECT_CHANGE,
BEV_MODAL_HARDEN_NORMALS_TOGGLE,
BEV_MODAL_MARK_SEAM_TOGGLE,
BEV_MODAL_MARK_SHARP_TOGGLE,
@@ -146,7 +146,7 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
int available_len = sizeof(buf);
Scene *sce = CTX_data_scene(C);
char offset_str[NUM_STR_REP_LEN];
- const char *mode_str, *omiter_str, *imiter_str, *vmesh_str, *profile_type_str;
+ const char *mode_str, *omiter_str, *imiter_str, *vmesh_str, *profile_type_str, *affect_str;
PropertyRNA *prop;
#define WM_MODALKEY(_id) \
@@ -182,6 +182,9 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
prop = RNA_struct_find_property(op->ptr, "vmesh_method");
RNA_property_enum_name_gettexted(
C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &vmesh_str);
+ prop = RNA_struct_find_property(op->ptr, "affect");
+ RNA_property_enum_name_gettexted(
+ C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &affect_str);
BLI_snprintf(status_text,
sizeof(status_text),
@@ -192,7 +195,7 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
"%s: Segments (%d), "
"%s: Profile (%.3f), "
"%s: Clamp Overlap (%s), "
- "%s: Vertex Only (%s), "
+ "%s: Affect (%s), "
"%s: Outer Miter (%s), "
"%s: Inner Miter (%s), "
"%s: Harden Normals (%s), "
@@ -212,8 +215,8 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
RNA_float_get(op->ptr, "profile"),
WM_MODALKEY(BEV_MODAL_CLAMP_OVERLAP_TOGGLE),
WM_bool_as_string(RNA_boolean_get(op->ptr, "clamp_overlap")),
- WM_MODALKEY(BEV_MODAL_VERTEX_ONLY_TOGGLE),
- WM_bool_as_string(RNA_boolean_get(op->ptr, "vertex_only")),
+ WM_MODALKEY(BEV_MODAL_AFFECT_CHANGE),
+ affect_str,
WM_MODALKEY(BEV_MODAL_OUTER_MITER_CHANGE),
omiter_str,
WM_MODALKEY(BEV_MODAL_INNER_MITER_CHANGE),
@@ -333,7 +336,7 @@ static bool edbm_bevel_calc(wmOperator *op)
const int profile_type = RNA_enum_get(op->ptr, "profile_type");
const int segments = RNA_int_get(op->ptr, "segments");
const float profile = RNA_float_get(op->ptr, "profile");
- const bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
+ const bool affect = RNA_enum_get(op->ptr, "affect");
const bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
const int material_init = RNA_int_get(op->ptr, "material");
const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide");
@@ -367,7 +370,7 @@ static bool edbm_bevel_calc(wmOperator *op)
EDBM_op_init(em,
&bmop,
op,
- "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i "
+ "bevel geom=%hev offset=%f segments=%i affect=%i offset_type=%i "
"profile_type=%i profile=%f clamp_overlap=%b material=%i loop_slide=%b "
"mark_seam=%b mark_sharp=%b harden_normals=%b face_strength_mode=%i "
"miter_outer=%i miter_inner=%i spread=%f smoothresh=%f custom_profile=%p "
@@ -375,7 +378,7 @@ static bool edbm_bevel_calc(wmOperator *op)
BM_ELEM_SELECT,
offset,
segments,
- vertex_only,
+ affect,
offset_type,
profile_type,
profile,
@@ -626,7 +629,7 @@ static bool edbm_bevel_poll_property(const bContext *UNUSED(C),
if (STREQ(prop_id, "offset") && offset_type == BEVEL_AMT_PERCENT) {
return false;
}
- else if (STREQ(prop_id, "offset_pct") && offset_type != BEVEL_AMT_PERCENT) {
+ if (STREQ(prop_id, "offset_pct") && offset_type != BEVEL_AMT_PERCENT) {
return false;
}
}
@@ -654,11 +657,11 @@ wmKeyMap *bevel_modal_keymap(wmKeyConfig *keyconf)
0,
"Toggle clamp overlap",
"Toggle clamp overlap flag"},
- {BEV_MODAL_VERTEX_ONLY_TOGGLE,
- "VERTEX_ONLY_TOGGLE",
+ {BEV_MODAL_AFFECT_CHANGE,
+ "AFFECT_CHANGE",
0,
- "Toggle vertex only",
- "Toggle vertex only flag"},
+ "Change affect type",
+ "Change which geometry type the operation affects, edges or vertices"},
{BEV_MODAL_HARDEN_NORMALS_TOGGLE,
"HARDEN_NORMALS_TOGGLE",
0,
@@ -729,7 +732,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
edbm_bevel_update_status_text(C, op);
return OPERATOR_RUNNING_MODAL;
}
- else if (etype == MOUSEMOVE) {
+ if (etype == MOUSEMOVE) {
if (!has_numinput) {
edbm_bevel_mouse_set_value(op, event);
edbm_bevel_calc(op);
@@ -830,9 +833,13 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
edbm_bevel_calc_initial_length(op, event, true);
break;
- case BEV_MODAL_VERTEX_ONLY_TOGGLE: {
- bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
- RNA_boolean_set(op->ptr, "vertex_only", !vertex_only);
+ case BEV_MODAL_AFFECT_CHANGE: {
+ int affect_type = RNA_enum_get(op->ptr, "affect");
+ affect_type++;
+ if (affect_type > BEVEL_AFFECT_EDGES) {
+ affect_type = BEVEL_AFFECT_VERTICES;
+ }
+ RNA_enum_set(op->ptr, "affect", affect_type);
edbm_bevel_calc(op);
edbm_bevel_update_status_text(C, op);
handled = true;
@@ -938,36 +945,31 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void edbm_bevel_ui(bContext *C, wmOperator *op)
{
uiLayout *layout = op->layout;
- uiLayout *row, *col, *split;
+ uiLayout *col, *row;
PointerRNA ptr, toolsettings_ptr;
- PropertyRNA *prop;
- const char *offset_name;
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
int profile_type = RNA_enum_get(&ptr, "profile_type");
+ int offset_type = RNA_enum_get(&ptr, "offset_type");
+ bool affect_type = RNA_enum_get(&ptr, "affect");
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, &ptr, "affect", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
+ uiItemS(layout);
- if (RNA_enum_get(&ptr, "offset_type") == BEVEL_AMT_PERCENT) {
+ uiItemR(layout, &ptr, "offset_type", 0, NULL, ICON_NONE);
+
+ if (offset_type == BEVEL_AMT_PERCENT) {
uiItemR(layout, &ptr, "offset_pct", 0, NULL, ICON_NONE);
}
else {
- prop = RNA_struct_find_property(op->ptr, "offset_type");
- RNA_property_enum_name_gettexted(
- C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &offset_name);
- uiItemR(layout, &ptr, "offset", 0, offset_name, ICON_NONE);
+ uiItemR(layout, &ptr, "offset", 0, NULL, ICON_NONE);
}
- row = uiLayoutRow(layout, true);
- uiItemR(row, &ptr, "offset_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-
- split = uiLayoutSplit(layout, 0.5f, true);
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "vertex_only", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "clamp_overlap", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "loop_slide", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "mark_seam", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "mark_sharp", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "harden_normals", 0, NULL, ICON_NONE);
uiItemR(layout, &ptr, "segments", 0, NULL, ICON_NONE);
if (ELEM(profile_type, BEVEL_PROFILE_SUPERELLIPSE, BEVEL_PROFILE_CUSTOM)) {
@@ -980,23 +982,37 @@ static void edbm_bevel_ui(bContext *C, wmOperator *op)
}
uiItemR(layout, &ptr, "material", 0, NULL, ICON_NONE);
- uiItemL(layout, "Miter Type:", ICON_NONE);
- uiItemR(layout, &ptr, "miter_outer", 0, "Outer", ICON_NONE);
- uiItemR(layout, &ptr, "miter_inner", 0, "Inner", ICON_NONE);
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, &ptr, "harden_normals", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "clamp_overlap", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "loop_slide", 0, NULL, ICON_NONE);
+
+ col = uiLayoutColumnWithHeading(layout, true, IFACE_("Mark"));
+ uiLayoutSetActive(col, affect_type == BEVEL_AFFECT_EDGES);
+ uiItemR(col, &ptr, "mark_seam", 0, IFACE_("Seams"), ICON_NONE);
+ uiItemR(col, &ptr, "mark_sharp", 0, IFACE_("Sharp"), ICON_NONE);
+
+ uiItemS(layout);
+
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, affect_type == BEVEL_AFFECT_EDGES);
+ uiItemR(col, &ptr, "miter_outer", 0, IFACE_("Miter Outer"), ICON_NONE);
+ uiItemR(col, &ptr, "miter_inner", 0, IFACE_("Inner"), ICON_NONE);
if (RNA_enum_get(&ptr, "miter_inner") == BEVEL_MITER_ARC) {
- uiItemR(layout, &ptr, "spread", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "spread", 0, NULL, ICON_NONE);
}
- uiItemL(layout, "Face Strength Mode:", ICON_NONE);
- row = uiLayoutRow(layout, true);
- uiItemR(row, &ptr, "face_strength_mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemS(layout);
+
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, affect_type == BEVEL_AFFECT_EDGES);
+ uiItemR(col, &ptr, "vmesh_method", 0, IFACE_("Intersection Type"), ICON_NONE);
- uiItemL(layout, "Intersection Type:", ICON_NONE);
- row = uiLayoutRow(layout, true);
- uiItemR(row, &ptr, "vmesh_method", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "face_strength_mode", 0, IFACE_("Face Strength"), ICON_NONE);
- uiItemL(layout, "Profile Type:", ICON_NONE);
- row = uiLayoutRow(layout, true);
+ uiItemS(layout);
+
+ row = uiLayoutRow(layout, false);
uiItemR(row, &ptr, "profile_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
if (profile_type == BEVEL_PROFILE_CUSTOM) {
/* Get an RNA pointer to ToolSettings to give to the curve profile template code. */
@@ -1076,6 +1092,12 @@ void MESH_OT_bevel(wmOperatorType *ot)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem prop_affect_items[] = {
+ {BEVEL_AFFECT_VERTICES, "VERTICES", 0, "Vertices", "Affect only vertices"},
+ {BEVEL_AFFECT_EDGES, "EDGES", 0, "Edges", "Affect only edges"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
/* identifiers */
ot->name = "Bevel";
ot->description = "Cut into selected items at an angle to create bevel or chamfer";
@@ -1136,7 +1158,12 @@ void MESH_OT_bevel(wmOperatorType *ot)
PROFILE_HARD_MIN,
1.0f);
- RNA_def_boolean(ot->srna, "vertex_only", false, "Vertex Only", "Bevel only vertices");
+ RNA_def_enum(ot->srna,
+ "affect",
+ prop_affect_items,
+ BEVEL_AFFECT_EDGES,
+ "Affect",
+ "Affect Edges or Vertices");
RNA_def_boolean(ot->srna,
"clamp_overlap",
@@ -1156,7 +1183,7 @@ void MESH_OT_bevel(wmOperatorType *ot)
-1,
-1,
INT_MAX,
- "Material",
+ "Material Index",
"Material for bevel faces (-1 means use adjacent faces)",
-1,
100);
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index bf6c5a2f829..5ad1b5d67da 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -424,10 +424,9 @@ static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
if (changed) {
return true;
}
- else {
- BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude");
- return false;
- }
+
+ BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude");
+ return false;
}
/* extrude without transform */
diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c
index 2eeada95eda..8d9837f123a 100644
--- a/source/blender/editors/mesh/editmesh_inset.c
+++ b/source/blender/editors/mesh/editmesh_inset.c
@@ -313,10 +313,9 @@ static bool edbm_inset_calc(wmOperator *op)
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
}
- else {
- EDBM_update_generic(obedit->data, true, true);
- changed = true;
- }
+
+ EDBM_update_generic(obedit->data, true, true);
+ changed = true;
}
return changed;
}
@@ -387,186 +386,181 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event)
edbm_inset_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
- else {
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
}
- else if ((event->type == opdata->launch_event) && (event->val == KM_RELEASE) &&
- RNA_boolean_get(op->ptr, "release_confirm")) {
+ if ((event->type == opdata->launch_event) && (event->val == KM_RELEASE) &&
+ RNA_boolean_get(op->ptr, "release_confirm")) {
edbm_inset_calc(op);
edbm_inset_exit(C, op);
return OPERATOR_FINISHED;
}
- else {
- bool handled = false;
- switch (event->type) {
- case EVT_ESCKEY:
- case RIGHTMOUSE:
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
-
- case MOUSEMOVE:
- if (!has_numinput) {
- float mdiff[2];
- float amount;
-
- mdiff[0] = opdata->mcenter[0] - event->mval[0];
- mdiff[1] = opdata->mcenter[1] - event->mval[1];
-
- if (opdata->modify_depth) {
- amount = opdata->old_depth +
- ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size) /
- opdata->max_obj_scale;
- }
- else {
- amount = opdata->old_thickness -
- ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size) /
- opdata->max_obj_scale;
- }
-
- /* Fake shift-transform... */
- if (opdata->shift) {
- amount = (amount - opdata->shift_amount) * 0.1f + opdata->shift_amount;
- }
-
- if (opdata->modify_depth) {
- RNA_float_set(op->ptr, "depth", amount);
- }
- else {
- amount = max_ff(amount, 0.0f);
- RNA_float_set(op->ptr, "thickness", amount);
- }
-
- if (edbm_inset_calc(op)) {
- edbm_inset_update_header(op, C);
- }
- else {
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
- handled = true;
- }
- break;
-
- case LEFTMOUSE:
- case EVT_PADENTER:
- case EVT_RETKEY:
- if ((event->val == KM_PRESS) ||
- ((event->val == KM_RELEASE) && RNA_boolean_get(op->ptr, "release_confirm"))) {
- edbm_inset_calc(op);
- edbm_inset_exit(C, op);
- return OPERATOR_FINISHED;
- }
- break;
- case EVT_LEFTSHIFTKEY:
- case EVT_RIGHTSHIFTKEY:
- if (event->val == KM_PRESS) {
- if (opdata->modify_depth) {
- opdata->shift_amount = RNA_float_get(op->ptr, "depth");
- }
- else {
- opdata->shift_amount = RNA_float_get(op->ptr, "thickness");
- }
- opdata->shift = true;
- handled = true;
+
+ bool handled = false;
+ switch (event->type) {
+ case EVT_ESCKEY:
+ case RIGHTMOUSE:
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+
+ case MOUSEMOVE:
+ if (!has_numinput) {
+ float mdiff[2];
+ float amount;
+
+ mdiff[0] = opdata->mcenter[0] - event->mval[0];
+ mdiff[1] = opdata->mcenter[1] - event->mval[1];
+
+ if (opdata->modify_depth) {
+ amount = opdata->old_depth +
+ ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size) /
+ opdata->max_obj_scale;
}
else {
- opdata->shift_amount = 0.0f;
- opdata->shift = false;
- handled = true;
+ amount = opdata->old_thickness -
+ ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size) /
+ opdata->max_obj_scale;
}
- break;
- case EVT_LEFTCTRLKEY:
- case EVT_RIGHTCTRLKEY: {
- float mlen[2];
-
- mlen[0] = opdata->mcenter[0] - event->mval[0];
- mlen[1] = opdata->mcenter[1] - event->mval[1];
+ /* Fake shift-transform... */
+ if (opdata->shift) {
+ amount = (amount - opdata->shift_amount) * 0.1f + opdata->shift_amount;
+ }
- if (event->val == KM_PRESS) {
- opdata->old_thickness = RNA_float_get(op->ptr, "thickness");
- if (opdata->shift) {
- opdata->shift_amount = opdata->old_thickness;
- }
- opdata->modify_depth = true;
+ if (opdata->modify_depth) {
+ RNA_float_set(op->ptr, "depth", amount);
}
else {
- opdata->old_depth = RNA_float_get(op->ptr, "depth");
- if (opdata->shift) {
- opdata->shift_amount = opdata->old_depth;
- }
- opdata->modify_depth = false;
+ amount = max_ff(amount, 0.0f);
+ RNA_float_set(op->ptr, "thickness", amount);
}
- opdata->initial_length = len_v2(mlen);
- edbm_inset_update_header(op, C);
+ if (edbm_inset_calc(op)) {
+ edbm_inset_update_header(op, C);
+ }
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
handled = true;
- break;
}
-
- case EVT_OKEY:
- if (event->val == KM_PRESS) {
- const bool use_outset = RNA_boolean_get(op->ptr, "use_outset");
- RNA_boolean_set(op->ptr, "use_outset", !use_outset);
- if (edbm_inset_calc(op)) {
- edbm_inset_update_header(op, C);
- }
- else {
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
- handled = true;
+ break;
+
+ case LEFTMOUSE:
+ case EVT_PADENTER:
+ case EVT_RETKEY:
+ if ((event->val == KM_PRESS) ||
+ ((event->val == KM_RELEASE) && RNA_boolean_get(op->ptr, "release_confirm"))) {
+ edbm_inset_calc(op);
+ edbm_inset_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+ break;
+ case EVT_LEFTSHIFTKEY:
+ case EVT_RIGHTSHIFTKEY:
+ if (event->val == KM_PRESS) {
+ if (opdata->modify_depth) {
+ opdata->shift_amount = RNA_float_get(op->ptr, "depth");
+ }
+ else {
+ opdata->shift_amount = RNA_float_get(op->ptr, "thickness");
}
- break;
- case EVT_BKEY:
- if (event->val == KM_PRESS) {
- const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
- RNA_boolean_set(op->ptr, "use_boundary", !use_boundary);
- if (edbm_inset_calc(op)) {
- edbm_inset_update_header(op, C);
- }
- else {
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
- handled = true;
+ opdata->shift = true;
+ handled = true;
+ }
+ else {
+ opdata->shift_amount = 0.0f;
+ opdata->shift = false;
+ handled = true;
+ }
+ break;
+
+ case EVT_LEFTCTRLKEY:
+ case EVT_RIGHTCTRLKEY: {
+ float mlen[2];
+
+ mlen[0] = opdata->mcenter[0] - event->mval[0];
+ mlen[1] = opdata->mcenter[1] - event->mval[1];
+
+ if (event->val == KM_PRESS) {
+ opdata->old_thickness = RNA_float_get(op->ptr, "thickness");
+ if (opdata->shift) {
+ opdata->shift_amount = opdata->old_thickness;
}
- break;
- case EVT_IKEY:
- if (event->val == KM_PRESS) {
- const bool use_individual = RNA_boolean_get(op->ptr, "use_individual");
- RNA_boolean_set(op->ptr, "use_individual", !use_individual);
- if (edbm_inset_calc(op)) {
- edbm_inset_update_header(op, C);
- }
- else {
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
- handled = true;
+ opdata->modify_depth = true;
+ }
+ else {
+ opdata->old_depth = RNA_float_get(op->ptr, "depth");
+ if (opdata->shift) {
+ opdata->shift_amount = opdata->old_depth;
}
- break;
+ opdata->modify_depth = false;
+ }
+ opdata->initial_length = len_v2(mlen);
+
+ edbm_inset_update_header(op, C);
+ handled = true;
+ break;
}
- /* Modal numinput inactive, try to handle numeric inputs last... */
- if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input, event)) {
- float amounts[2] = {RNA_float_get(op->ptr, "thickness"), RNA_float_get(op->ptr, "depth")};
- applyNumInput(&opdata->num_input, amounts);
- amounts[0] = max_ff(amounts[0], 0.0f);
- RNA_float_set(op->ptr, "thickness", amounts[0]);
- RNA_float_set(op->ptr, "depth", amounts[1]);
-
- if (edbm_inset_calc(op)) {
- edbm_inset_update_header(op, C);
- return OPERATOR_RUNNING_MODAL;
+ case EVT_OKEY:
+ if (event->val == KM_PRESS) {
+ const bool use_outset = RNA_boolean_get(op->ptr, "use_outset");
+ RNA_boolean_set(op->ptr, "use_outset", !use_outset);
+ if (edbm_inset_calc(op)) {
+ edbm_inset_update_header(op, C);
+ }
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ handled = true;
}
- else {
- edbm_inset_cancel(C, op);
- return OPERATOR_CANCELLED;
+ break;
+ case EVT_BKEY:
+ if (event->val == KM_PRESS) {
+ const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
+ RNA_boolean_set(op->ptr, "use_boundary", !use_boundary);
+ if (edbm_inset_calc(op)) {
+ edbm_inset_update_header(op, C);
+ }
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ handled = true;
+ }
+ break;
+ case EVT_IKEY:
+ if (event->val == KM_PRESS) {
+ const bool use_individual = RNA_boolean_get(op->ptr, "use_individual");
+ RNA_boolean_set(op->ptr, "use_individual", !use_individual);
+ if (edbm_inset_calc(op)) {
+ edbm_inset_update_header(op, C);
+ }
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ handled = true;
}
+ break;
+ }
+
+ /* Modal numinput inactive, try to handle numeric inputs last... */
+ if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input, event)) {
+ float amounts[2] = {RNA_float_get(op->ptr, "thickness"), RNA_float_get(op->ptr, "depth")};
+ applyNumInput(&opdata->num_input, amounts);
+ amounts[0] = max_ff(amounts[0], 0.0f);
+ RNA_float_set(op->ptr, "thickness", amounts[0]);
+ RNA_float_set(op->ptr, "depth", amounts[1]);
+
+ if (edbm_inset_calc(op)) {
+ edbm_inset_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
}
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
}
return OPERATOR_RUNNING_MODAL;
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index fd7cc2733ec..97bd6ee0039 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -60,9 +60,7 @@ static int bm_face_isect_self(BMFace *f, void *UNUSED(user_data))
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
return 0;
}
- else {
- return -1;
- }
+ return -1;
}
/**
@@ -73,12 +71,10 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
return -1;
}
- else if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
/**
@@ -90,12 +86,10 @@ static int bm_face_isect_pair_swap(BMFace *f, void *UNUSED(user_data))
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
return -1;
}
- else if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
return 0;
}
- else {
- return 1;
- }
+ return 1;
}
/**
@@ -515,12 +509,10 @@ static int bm_edge_sort_length_cb(const void *e_a_v, const void *e_b_v)
if (val_a > val_b) {
return 1;
}
- else if (val_a < val_b) {
+ if (val_a < val_b) {
return -1;
}
- else {
- return 0;
- }
+ return 0;
}
static void bm_face_split_by_edges_island_connect(
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 369c7735d20..1f411617c68 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -102,7 +102,7 @@ typedef struct KnifeVert {
ListBase edges;
ListBase faces;
- float co[3], cageco[3], sco[2]; /* sco is screen coordinates for cageco */
+ float co[3], cageco[3];
bool is_face, in_space;
bool is_cut; /* along a cut created by user input (will draw too) */
} KnifeVert;
@@ -429,8 +429,6 @@ static KnifeVert *new_knife_vert(KnifeTool_OpData *kcd, const float co[3], const
copy_v3_v3(kfv->co, co);
copy_v3_v3(kfv->cageco, cageco);
- knife_project_v2(kcd, kfv->cageco, kfv->sco);
-
return kfv;
}
@@ -649,28 +647,22 @@ static int linehit_compare(const void *vlh1, const void *vlh2)
if (lh1->l < lh2->l) {
return -1;
}
- else if (lh1->l > lh2->l) {
+ if (lh1->l > lh2->l) {
return 1;
}
- else {
- if (lh1->m < lh2->m) {
- return -1;
- }
- else if (lh1->m > lh2->m) {
- return 1;
- }
- else {
- if (lh1->v < lh2->v) {
- return -1;
- }
- else if (lh1->v > lh2->v) {
- return 1;
- }
- else {
- return 0;
- }
- }
+ if (lh1->m < lh2->m) {
+ return -1;
}
+ if (lh1->m > lh2->m) {
+ return 1;
+ }
+ if (lh1->v < lh2->v) {
+ return -1;
+ }
+ if (lh1->v > lh2->v) {
+ return 1;
+ }
+ return 0;
}
/*
@@ -816,11 +808,9 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd,
kfe->e = e_base;
return;
}
- else {
- if (knife_add_single_cut__is_linehit_outside_face(f, lh1, lh2->hit) ||
- knife_add_single_cut__is_linehit_outside_face(f, lh2, lh1->hit)) {
- return;
- }
+ if (knife_add_single_cut__is_linehit_outside_face(f, lh1, lh2->hit) ||
+ knife_add_single_cut__is_linehit_outside_face(f, lh2, lh1->hit)) {
+ return;
}
/* Check if edge actually lies within face (might not, if this face is concave) */
@@ -1063,7 +1053,8 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
const KnifeTool_OpData *kcd = arg;
GPU_depth_test(false);
- glPolygonOffset(1.0f, 1.0f);
+ GPU_matrix_push_projection();
+ GPU_polygon_offset(1.0f, 1.0f);
GPU_matrix_push();
GPU_matrix_mul(kcd->ob->obmat);
@@ -1234,6 +1225,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
immUnbindProgram();
GPU_matrix_pop();
+ GPU_matrix_pop_projection();
/* Reset default */
GPU_depth_test(true);
@@ -1405,9 +1397,7 @@ static bool coinciding_edges(BMEdge *e1, BMEdge *e2)
(equals_v3v3(co11, co22) && equals_v3v3(co12, co21))) {
return true;
}
- else {
- return false;
- }
+ return false;
}
/* Callback used in point_is_visible to exclude hits on the faces that are the same
@@ -1558,8 +1548,8 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
{
SmallHash faces, kfes, kfvs;
float v1[3], v2[3], v3[3], v4[3], s1[2], s2[2];
- BVHTree *planetree, *tree;
- BVHTreeOverlap *results, *result;
+ BVHTree *tree;
+ int *results, *result;
BMLoop **ls;
BMFace *f;
KnifeEdge *kfe;
@@ -1572,18 +1562,14 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
KnifeLineHit hit;
void *val;
void **val_p;
- float plane_cos[12];
float s[2], se1[2], se2[2], sint[2];
float r1[3], r2[3];
- float d, d1, d2, lambda;
+ float d1, d2, lambda;
float vert_tol, vert_tol_sq;
float line_tol, line_tol_sq;
float face_tol, face_tol_sq;
- int isect_kind;
uint tot;
int i;
- const bool use_hit_prev = true;
- const bool use_hit_curr = (kcd->is_drag_hold == false);
if (kcd->linehits) {
MEM_freeN(kcd->linehits);
@@ -1633,22 +1619,22 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
clip_to_ortho_planes(v2, v4, kcd->ortho_extent_center, kcd->ortho_extent + 10.0f);
}
- /* First use bvh tree to find faces, knife edges, and knife verts that might
+ float plane[4];
+ {
+ float v1_v2[3], v1_v3[3];
+ sub_v3_v3v3(v1_v2, v2, v1);
+ sub_v3_v3v3(v1_v3, v3, v1);
+ cross_v3_v3v3(plane, v1_v2, v1_v3);
+ plane_from_point_normal_v3(plane, v1, plane);
+ }
+
+ /* First use BVH tree to find faces, knife edges, and knife verts that might
* intersect the cut plane with rays v1-v3 and v2-v4.
- * This deduplicates the candidates before doing more expensive intersection tests. */
+ * This de-duplicates the candidates before doing more expensive intersection tests. */
tree = BKE_bmbvh_tree_get(kcd->bmbvh);
- planetree = BLI_bvhtree_new(4, FLT_EPSILON * 4, 8, 8);
- copy_v3_v3(plane_cos + 0, v1);
- copy_v3_v3(plane_cos + 3, v2);
- copy_v3_v3(plane_cos + 6, v3);
- copy_v3_v3(plane_cos + 9, v4);
- BLI_bvhtree_insert(planetree, 0, plane_cos, 4);
- BLI_bvhtree_balance(planetree);
-
- results = BLI_bvhtree_overlap(tree, planetree, &tot, NULL, NULL);
+ results = BLI_bvhtree_intersect_plane(tree, plane, &tot);
if (!results) {
- BLI_bvhtree_free(planetree);
return;
}
@@ -1657,9 +1643,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
BLI_smallhash_init(&kfvs);
for (i = 0, result = results; i < tot; i++, result++) {
- ls = (BMLoop **)kcd->em->looptris[result->indexA];
+ ls = (BMLoop **)kcd->em->looptris[*result];
f = ls[0]->f;
- set_lowest_face_tri(kcd, f, result->indexA);
+ set_lowest_face_tri(kcd, f, *result);
/* occlude but never cut unselected faces (when only_select is used) */
if (kcd->only_select && !BM_elem_flag_test(f, BM_ELEM_SELECT)) {
@@ -1714,10 +1700,25 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
val_p = BLI_smallhash_iternext_p(&hiter, (uintptr_t *)&v)) {
KnifeEdge *kfe_hit = NULL;
- knife_project_v2(kcd, v->cageco, s);
- d = dist_squared_to_line_segment_v2(s, s1, s2);
- if ((d <= vert_tol_sq) &&
- (point_is_visible(kcd, v->cageco, s, bm_elem_from_knife_vert(v, &kfe_hit)))) {
+ bool kfv_is_in_cut = false;
+ if (ELEM(v, kcd->prev.vert, kcd->curr.vert)) {
+ /* This KnifeVert was captured by the snap system.
+ * Since the tolerance distance can be different, add this vertex directly.
+ * Otherwise, the cut may fail or a close cut on a connected edge can be performed. */
+ bm_elem_from_knife_vert(v, &kfe_hit);
+ copy_v2_v2(s, (v == kcd->prev.vert) ? kcd->prev.mval : kcd->curr.mval);
+ kfv_is_in_cut = true;
+ }
+ else {
+ knife_project_v2(kcd, v->cageco, s);
+ float d = dist_squared_to_line_segment_v2(s, s1, s2);
+ if ((d <= vert_tol_sq) &&
+ (point_is_visible(kcd, v->cageco, s, bm_elem_from_knife_vert(v, &kfe_hit)))) {
+ kfv_is_in_cut = true;
+ }
+ }
+
+ if (kfv_is_in_cut) {
memset(&hit, 0, sizeof(hit));
hit.v = v;
@@ -1735,7 +1736,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
BLI_array_append(linehits, hit);
}
else {
- /* note that these vertes aren't used */
+ /* This vertex isn't used so remove from `kfvs`.
+ * This is useful to detect KnifeEdges that can be skipped.
+ * And it optimizes smallhash_iternext a little bit. */
*val_p = NULL;
}
}
@@ -1743,30 +1746,38 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
/* now edge hits; don't add if a vertex at end of edge should have hit */
for (val = BLI_smallhash_iternew(&kfes, &hiter, (uintptr_t *)&kfe); val;
val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&kfe)) {
- int kfe_verts_in_cut;
- /* if we intersect both verts, don't attempt to intersect the edge */
- kfe_verts_in_cut = (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v1) != NULL) +
- (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v2) != NULL);
-
- if (kfe_verts_in_cut == 2) {
+ /* If we intersect any of the vertices, don't attempt to intersect the edge. */
+ if (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v1) ||
+ BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v2)) {
continue;
}
knife_project_v2(kcd, kfe->v1->cageco, se1);
knife_project_v2(kcd, kfe->v2->cageco, se2);
- isect_kind = (kfe_verts_in_cut) ? -1 : isect_seg_seg_v2_point(s1, s2, se1, se2, sint);
- if (isect_kind == -1) {
- /* isect_seg_seg_v2_simple doesn't do tolerance test around ends of s1-s2 */
- closest_to_line_segment_v2(sint, s1, se1, se2);
- if (len_squared_v2v2(sint, s1) <= line_tol_sq) {
- isect_kind = 1;
- }
- else {
- closest_to_line_segment_v2(sint, s2, se1, se2);
- if (len_squared_v2v2(sint, s2) <= line_tol_sq) {
+ int isect_kind = 1;
+ if (kfe == kcd->prev.edge) {
+ /* This KnifeEdge was captured by the snap system. */
+ copy_v2_v2(sint, kcd->prev.mval);
+ }
+ else if (kfe == kcd->curr.edge) {
+ /* This KnifeEdge was captured by the snap system. */
+ copy_v2_v2(sint, kcd->curr.mval);
+ }
+ else {
+ isect_kind = isect_seg_seg_v2_point_ex(s1, s2, se1, se2, 0.0f, sint);
+ if (isect_kind == -1) {
+ /* isect_seg_seg_v2_point doesn't do tolerance test around ends of s1-s2 */
+ closest_to_line_segment_v2(sint, s1, se1, se2);
+ if (len_squared_v2v2(sint, s1) <= line_tol_sq) {
isect_kind = 1;
}
+ else {
+ closest_to_line_segment_v2(sint, s2, se1, se2);
+ if (len_squared_v2v2(sint, s2) <= line_tol_sq) {
+ isect_kind = 1;
+ }
+ }
}
}
if (isect_kind == 1) {
@@ -1801,32 +1812,38 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
}
}
}
+
/* now face hits; don't add if a vertex or edge in face should have hit */
- for (val = BLI_smallhash_iternew(&faces, &hiter, (uintptr_t *)&f); val;
- val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&f)) {
- float p[3], p_cage[3];
-
- if (use_hit_prev && knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) {
- if (point_is_visible(kcd, p_cage, s1, (BMElem *)f)) {
- memset(&hit, 0, sizeof(hit));
- hit.f = f;
- copy_v3_v3(hit.hit, p);
- copy_v3_v3(hit.cagehit, p_cage);
- copy_v2_v2(hit.schit, s1);
- set_linehit_depth(kcd, &hit);
- BLI_array_append(linehits, hit);
+ const bool use_hit_prev = (kcd->prev.vert == NULL) && (kcd->prev.edge == NULL);
+ const bool use_hit_curr = (kcd->curr.vert == NULL) && (kcd->curr.edge == NULL) &&
+ !kcd->is_drag_hold;
+ if (use_hit_prev || use_hit_curr) {
+ for (val = BLI_smallhash_iternew(&faces, &hiter, (uintptr_t *)&f); val;
+ val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&f)) {
+ float p[3], p_cage[3];
+
+ if (use_hit_prev && knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) {
+ if (point_is_visible(kcd, p_cage, s1, (BMElem *)f)) {
+ memset(&hit, 0, sizeof(hit));
+ hit.f = f;
+ copy_v3_v3(hit.hit, p);
+ copy_v3_v3(hit.cagehit, p_cage);
+ copy_v2_v2(hit.schit, s1);
+ set_linehit_depth(kcd, &hit);
+ BLI_array_append(linehits, hit);
+ }
}
- }
- if (use_hit_curr && knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) {
- if (point_is_visible(kcd, p_cage, s2, (BMElem *)f)) {
- memset(&hit, 0, sizeof(hit));
- hit.f = f;
- copy_v3_v3(hit.hit, p);
- copy_v3_v3(hit.cagehit, p_cage);
- copy_v2_v2(hit.schit, s2);
- set_linehit_depth(kcd, &hit);
- BLI_array_append(linehits, hit);
+ if (use_hit_curr && knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) {
+ if (point_is_visible(kcd, p_cage, s2, (BMElem *)f)) {
+ memset(&hit, 0, sizeof(hit));
+ hit.f = f;
+ copy_v3_v3(hit.hit, p);
+ copy_v3_v3(hit.cagehit, p_cage);
+ copy_v2_v2(hit.schit, s2);
+ set_linehit_depth(kcd, &hit);
+ BLI_array_append(linehits, hit);
+ }
}
}
}
@@ -1844,7 +1861,6 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
BLI_smallhash_release(&faces);
BLI_smallhash_release(&kfes);
BLI_smallhash_release(&kfvs);
- BLI_bvhtree_free(planetree);
if (results) {
MEM_freeN(results);
}
@@ -1938,10 +1954,11 @@ static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius
for (i = 0; i < 2; i++) {
KnifeVert *kfv = i ? kfe->v2 : kfe->v1;
+ float kfv_sco[2];
- knife_project_v2(kcd, kfv->cageco, kfv->sco);
+ knife_project_v2(kcd, kfv->cageco, kfv_sco);
- dis_sq = len_squared_v2v2(kfv->sco, sco);
+ dis_sq = len_squared_v2v2(kfv_sco, sco);
if (dis_sq < radius_sq) {
if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true) == 0) {
@@ -1971,11 +1988,12 @@ static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
}
/* p is closest point on edge to the mouse cursor */
-static KnifeEdge *knife_find_closest_edge(
- KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, bool *is_space)
+static KnifeEdge *knife_find_closest_edge_of_face(KnifeTool_OpData *kcd,
+ BMFace *f,
+ float p[3],
+ float cagep[3])
{
- BMFace *f;
- float co[3], cageco[3], sco[2];
+ float sco[2];
float maxdist;
if (kcd->is_interactive) {
@@ -1989,127 +2007,105 @@ static KnifeEdge *knife_find_closest_edge(
maxdist = KNIFE_FLT_EPS;
}
- f = knife_find_closest_face(kcd, co, cageco, NULL);
- *is_space = !f;
-
- kcd->curr.bmface = f;
-
- if (f) {
- const float maxdist_sq = maxdist * maxdist;
- KnifeEdge *cure = NULL;
- float cur_cagep[3];
- ListBase *lst;
- Ref *ref;
- float dis_sq, curdis_sq = FLT_MAX;
-
- /* set p to co, in case we don't find anything, means a face cut */
- copy_v3_v3(p, co);
- copy_v3_v3(cagep, cageco);
-
- knife_project_v2(kcd, cageco, sco);
-
- /* look through all edges associated with this face */
- lst = knife_get_face_kedges(kcd, f);
- for (ref = lst->first; ref; ref = ref->next) {
- KnifeEdge *kfe = ref->ref;
- float test_cagep[3];
- float lambda;
-
- /* project edge vertices into screen space */
- knife_project_v2(kcd, kfe->v1->cageco, kfe->v1->sco);
- knife_project_v2(kcd, kfe->v2->cageco, kfe->v2->sco);
-
- /* check if we're close enough and calculate 'lambda' */
- if (kcd->is_angle_snapping) {
- /* if snapping, check we're in bounds */
- float sco_snap[2];
- isect_line_line_v2_point(
- kfe->v1->sco, kfe->v2->sco, kcd->prev.mval, kcd->curr.mval, sco_snap);
- lambda = line_point_factor_v2(sco_snap, kfe->v1->sco, kfe->v2->sco);
-
- /* be strict about angle-snapping within edge */
- if ((lambda < 0.0f - KNIFE_FLT_EPSBIG) || (lambda > 1.0f + KNIFE_FLT_EPSBIG)) {
- continue;
- }
+ const float maxdist_sq = maxdist * maxdist;
+ KnifeEdge *cure = NULL;
+ float cur_cagep[3];
+ ListBase *lst;
+ Ref *ref;
+ float dis_sq, curdis_sq = FLT_MAX;
+
+ knife_project_v2(kcd, cagep, sco);
+
+ /* look through all edges associated with this face */
+ lst = knife_get_face_kedges(kcd, f);
+ for (ref = lst->first; ref; ref = ref->next) {
+ KnifeEdge *kfe = ref->ref;
+ float kfv1_sco[2], kfv2_sco[2], test_cagep[3];
+ float lambda;
+
+ /* project edge vertices into screen space */
+ knife_project_v2(kcd, kfe->v1->cageco, kfv1_sco);
+ knife_project_v2(kcd, kfe->v2->cageco, kfv2_sco);
+
+ /* check if we're close enough and calculate 'lambda' */
+ if (kcd->is_angle_snapping) {
+ /* if snapping, check we're in bounds */
+ float sco_snap[2];
+ isect_line_line_v2_point(kfv1_sco, kfv2_sco, kcd->prev.mval, kcd->curr.mval, sco_snap);
+ lambda = line_point_factor_v2(sco_snap, kfv1_sco, kfv2_sco);
+
+ /* be strict about angle-snapping within edge */
+ if ((lambda < 0.0f - KNIFE_FLT_EPSBIG) || (lambda > 1.0f + KNIFE_FLT_EPSBIG)) {
+ continue;
+ }
- dis_sq = len_squared_v2v2(sco, sco_snap);
- if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
- /* we already have 'lambda' */
- }
- else {
- continue;
- }
+ dis_sq = len_squared_v2v2(sco, sco_snap);
+ if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
+ /* we already have 'lambda' */
}
else {
- dis_sq = dist_squared_to_line_segment_v2(sco, kfe->v1->sco, kfe->v2->sco);
- if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
- lambda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco);
- }
- else {
- continue;
- }
+ continue;
}
+ }
+ else {
+ dis_sq = dist_squared_to_line_segment_v2(sco, kfv1_sco, kfv2_sco);
+ if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
+ lambda = line_point_factor_v2(sco, kfv1_sco, kfv2_sco);
+ }
+ else {
+ continue;
+ }
+ }
- /* now we have 'lambda' calculated (in screen-space) */
- knife_interp_v3_v3v3(kcd, test_cagep, kfe->v1->cageco, kfe->v2->cageco, lambda);
+ /* now we have 'lambda' calculated (in screen-space) */
+ knife_interp_v3_v3v3(kcd, test_cagep, kfe->v1->cageco, kfe->v2->cageco, lambda);
- if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
- /* check we're in the view */
- if (ED_view3d_clipping_test(kcd->vc.rv3d, test_cagep, true)) {
- continue;
- }
+ if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
+ /* check we're in the view */
+ if (ED_view3d_clipping_test(kcd->vc.rv3d, test_cagep, true)) {
+ continue;
}
-
- cure = kfe;
- curdis_sq = dis_sq;
- copy_v3_v3(cur_cagep, test_cagep);
}
- if (fptr) {
- *fptr = f;
- }
+ cure = kfe;
+ curdis_sq = dis_sq;
+ copy_v3_v3(cur_cagep, test_cagep);
+ }
- if (cure) {
- if (!kcd->ignore_edge_snapping || !(cure->e)) {
- KnifeVert *edgesnap = NULL;
+ if (cure) {
+ if (!kcd->ignore_edge_snapping || !(cure->e)) {
+ KnifeVert *edgesnap = NULL;
- if (kcd->snap_midpoints) {
- mid_v3_v3v3(p, cure->v1->co, cure->v2->co);
- mid_v3_v3v3(cagep, cure->v1->cageco, cure->v2->cageco);
- }
- else {
- float lambda = line_point_factor_v3(cur_cagep, cure->v1->cageco, cure->v2->cageco);
- copy_v3_v3(cagep, cur_cagep);
- interp_v3_v3v3(p, cure->v1->co, cure->v2->co, lambda);
- }
-
- /* update mouse coordinates to the snapped-to edge's screen coordinates
- * this is important for angle snap, which uses the previous mouse position */
- edgesnap = new_knife_vert(kcd, p, cagep);
- kcd->curr.mval[0] = edgesnap->sco[0];
- kcd->curr.mval[1] = edgesnap->sco[1];
+ if (kcd->snap_midpoints) {
+ mid_v3_v3v3(p, cure->v1->co, cure->v2->co);
+ mid_v3_v3v3(cagep, cure->v1->cageco, cure->v2->cageco);
}
else {
- return NULL;
+ float lambda = line_point_factor_v3(cur_cagep, cure->v1->cageco, cure->v2->cageco);
+ copy_v3_v3(cagep, cur_cagep);
+ interp_v3_v3v3(p, cure->v1->co, cure->v2->co, lambda);
}
- }
- return cure;
- }
-
- if (fptr) {
- *fptr = NULL;
+ /* update mouse coordinates to the snapped-to edge's screen coordinates
+ * this is important for angle snap, which uses the previous mouse position */
+ edgesnap = new_knife_vert(kcd, p, cagep);
+ knife_project_v2(kcd, edgesnap->cageco, kcd->curr.mval);
+ }
+ else {
+ return NULL;
+ }
}
- return NULL;
+ return cure;
}
/* find a vertex near the mouse cursor, if it exists */
-static KnifeVert *knife_find_closest_vert(
- KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, bool *is_space)
+static KnifeVert *knife_find_closest_vert_of_face(KnifeTool_OpData *kcd,
+ BMFace *f,
+ float p[3],
+ float cagep[3])
{
- BMFace *f;
- float co[3], cageco[3], sco[2];
+ float sco[2];
float maxdist;
if (kcd->is_interactive) {
@@ -2122,86 +2118,58 @@ static KnifeVert *knife_find_closest_vert(
maxdist = KNIFE_FLT_EPS;
}
- f = knife_find_closest_face(kcd, co, cageco, is_space);
-
- kcd->curr.bmface = f;
-
- if (f) {
- const float maxdist_sq = maxdist * maxdist;
- ListBase *lst;
- Ref *ref;
- KnifeVert *curv = NULL;
- float dis_sq, curdis_sq = FLT_MAX;
-
- /* set p to co, in case we don't find anything, means a face cut */
- copy_v3_v3(p, co);
- copy_v3_v3(cagep, cageco);
+ const float maxdist_sq = maxdist * maxdist;
+ ListBase *lst;
+ Ref *ref;
+ KnifeVert *curv = NULL;
+ float cur_kfv_sco[2];
+ float dis_sq, curdis_sq = FLT_MAX;
- knife_project_v2(kcd, cageco, sco);
+ knife_project_v2(kcd, cagep, sco);
- lst = knife_get_face_kedges(kcd, f);
- for (ref = lst->first; ref; ref = ref->next) {
- KnifeEdge *kfe = ref->ref;
- int i;
+ lst = knife_get_face_kedges(kcd, f);
+ for (ref = lst->first; ref; ref = ref->next) {
+ KnifeEdge *kfe = ref->ref;
+ int i;
- for (i = 0; i < 2; i++) {
- KnifeVert *kfv = i ? kfe->v2 : kfe->v1;
+ for (i = 0; i < 2; i++) {
+ KnifeVert *kfv = i ? kfe->v2 : kfe->v1;
+ float kfv_sco[2];
- knife_project_v2(kcd, kfv->cageco, kfv->sco);
+ knife_project_v2(kcd, kfv->cageco, kfv_sco);
- /* be strict about angle snapping, the vertex needs to be very close to the angle,
- * or we ignore */
- if (kcd->is_angle_snapping) {
- if (dist_squared_to_line_segment_v2(kfv->sco, kcd->prev.mval, kcd->curr.mval) >
- KNIFE_FLT_EPSBIG) {
- continue;
- }
+ /* be strict about angle snapping, the vertex needs to be very close to the angle,
+ * or we ignore */
+ if (kcd->is_angle_snapping) {
+ if (dist_squared_to_line_segment_v2(kfv_sco, kcd->prev.mval, kcd->curr.mval) >
+ KNIFE_FLT_EPSBIG) {
+ continue;
}
+ }
- dis_sq = len_squared_v2v2(kfv->sco, sco);
- if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
- if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
- if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true) == 0) {
- curv = kfv;
- curdis_sq = dis_sq;
- }
- }
- else {
- curv = kfv;
- curdis_sq = dis_sq;
- }
+ dis_sq = len_squared_v2v2(kfv_sco, sco);
+ if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
+ if (!RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d) ||
+ !ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true)) {
+ curv = kfv;
+ curdis_sq = dis_sq;
+ copy_v2_v2(cur_kfv_sco, kfv_sco);
}
}
}
+ }
- if (!kcd->ignore_vert_snapping || !(curv && curv->v)) {
- if (fptr) {
- *fptr = f;
- }
-
- if (curv) {
- copy_v3_v3(p, curv->co);
- copy_v3_v3(cagep, curv->cageco);
-
- /* update mouse coordinates to the snapped-to vertex's screen coordinates
- * this is important for angle snap, which uses the previous mouse position */
- kcd->curr.mval[0] = curv->sco[0];
- kcd->curr.mval[1] = curv->sco[1];
- }
-
- return curv;
- }
- else {
- if (fptr) {
- *fptr = f;
- }
+ if (!kcd->ignore_vert_snapping || !(curv && curv->v)) {
+ if (curv) {
+ copy_v3_v3(p, curv->co);
+ copy_v3_v3(cagep, curv->cageco);
- return NULL;
+ /* update mouse coordinates to the snapped-to vertex's screen coordinates
+ * this is important for angle snap, which uses the previous mouse position */
+ copy_v2_v2(kcd->curr.mval, cur_kfv_sco);
}
- }
- if (fptr) {
- *fptr = NULL;
+ return curv;
}
return NULL;
@@ -2248,11 +2216,10 @@ static bool knife_snap_angle(KnifeTool_OpData *kcd)
return true;
}
-/* update active knife edge/vert pointers */
-static int knife_update_active(KnifeTool_OpData *kcd)
+static void knife_snap_update_from_mval(KnifeTool_OpData *kcd, const float mval[2])
{
knife_pos_data_clear(&kcd->curr);
- copy_v2_v2(kcd->curr.mval, kcd->mval);
+ copy_v2_v2(kcd->curr.mval, mval);
/* view matrix may have changed, reproject */
knife_project_v2(kcd, kcd->prev.cage, kcd->prev.mval);
@@ -2264,15 +2231,26 @@ static int knife_update_active(KnifeTool_OpData *kcd)
kcd->is_angle_snapping = false;
}
- kcd->curr.vert = knife_find_closest_vert(
- kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space);
+ kcd->curr.bmface = knife_find_closest_face(
+ kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.is_space);
+
+ if (kcd->curr.bmface) {
+ kcd->curr.vert = knife_find_closest_vert_of_face(
+ kcd, kcd->curr.bmface, kcd->curr.co, kcd->curr.cage);
- if (!kcd->curr.vert &&
- /* no edge snapping while dragging (edges are too sticky when cuts are immediate) */
- !kcd->is_drag_hold) {
- kcd->curr.edge = knife_find_closest_edge(
- kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space);
+ if (!kcd->curr.vert &&
+ /* no edge snapping while dragging (edges are too sticky when cuts are immediate) */
+ !kcd->is_drag_hold) {
+ kcd->curr.edge = knife_find_closest_edge_of_face(
+ kcd, kcd->curr.bmface, kcd->curr.co, kcd->curr.cage);
+ }
}
+}
+
+/* update active knife edge/vert pointers */
+static int knife_update_active(KnifeTool_OpData *kcd)
+{
+ knife_snap_update_from_mval(kcd, kcd->mval);
/* if no hits are found this would normally default to (0, 0, 0) so instead
* get a point at the mouse ray closest to the previous point.
@@ -2310,12 +2288,10 @@ static int sort_verts_by_dist_cb(void *co_p, const void *cur_a_p, const void *cu
if (a_sq < b_sq) {
return -1;
}
- else if (a_sq > b_sq) {
+ if (a_sq > b_sq) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
static bool knife_verts_edge_in_face(KnifeVert *v1, KnifeVert *v2, BMFace *f)
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index 10e8bfa529f..ef78d31a6bb 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -152,12 +152,11 @@ static int knifeproject_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports,
- RPT_ERROR,
- "No other selected objects have wire or boundary edges to use for projection");
- return OPERATOR_CANCELLED;
- }
+
+ BKE_report(op->reports,
+ RPT_ERROR,
+ "No other selected objects have wire or boundary edges to use for projection");
+ return OPERATOR_CANCELLED;
}
void MESH_OT_knife_project(wmOperatorType *ot)
@@ -165,7 +164,7 @@ void MESH_OT_knife_project(wmOperatorType *ot)
/* description */
ot->name = "Knife Project";
ot->idname = "MESH_OT_knife_project";
- ot->description = "Use other objects outlines & boundaries to project knife cuts";
+ ot->description = "Use other objects outlines and boundaries to project knife cuts";
/* callbacks */
ot->exec = knifeproject_exec;
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 0f52911c603..2f453369d92 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -451,11 +451,10 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
"hold Alt for smooth"));
return OPERATOR_RUNNING_MODAL;
}
- else {
- ringsel_finish(C, op);
- ringsel_exit(C, op);
- return OPERATOR_FINISHED;
- }
+
+ ringsel_finish(C, op);
+ ringsel_exit(C, op);
+ return OPERATOR_FINISHED;
}
static int ringcut_invoke(bContext *C, wmOperator *op, const wmEvent *event)
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index 739bc5bdf7c..8eeba5007e1 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -66,9 +66,7 @@ static bool paint_mask_extract_poll(bContext *C)
CTX_wm_operator_poll_msg_set(C, "The mask can not be extracted with dyntopo activated");
return false;
}
- else {
- return ED_operator_object_active_editable_mesh(C);
- }
+ return ED_operator_object_active_editable_mesh(C);
}
return false;
}
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index 7cde233c6b6..e7e27c2189f 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -642,10 +642,10 @@ static BMElem *edbm_elem_find_nearest(ViewContext *vc, const char htype)
if ((em->selectmode & SCE_SELECT_VERTEX) && (htype == BM_VERT)) {
return (BMElem *)EDBM_vert_find_nearest(vc, &dist);
}
- else if ((em->selectmode & SCE_SELECT_EDGE) && (htype == BM_EDGE)) {
+ if ((em->selectmode & SCE_SELECT_EDGE) && (htype == BM_EDGE)) {
return (BMElem *)EDBM_edge_find_nearest(vc, &dist);
}
- else if ((em->selectmode & SCE_SELECT_FACE) && (htype == BM_FACE)) {
+ if ((em->selectmode & SCE_SELECT_FACE) && (htype == BM_FACE)) {
return (BMElem *)EDBM_face_find_nearest(vc, &dist);
}
diff --git a/source/blender/editors/mesh/editmesh_polybuild.c b/source/blender/editors/mesh/editmesh_polybuild.c
index c7bb45ccfe3..da3d16ba04f 100644
--- a/source/blender/editors/mesh/editmesh_polybuild.c
+++ b/source/blender/editors/mesh/editmesh_polybuild.c
@@ -247,9 +247,7 @@ static int edbm_polybuild_delete_at_cursor_invoke(bContext *C,
WM_event_add_mousemove(vc.win);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MESH_OT_polybuild_delete_at_cursor(wmOperatorType *ot)
@@ -415,9 +413,7 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MESH_OT_polybuild_face_at_cursor(wmOperatorType *ot)
@@ -470,7 +466,7 @@ static int edbm_polybuild_split_at_cursor_invoke(bContext *C,
if (ele_act == NULL || ele_act->head.hflag == BM_FACE) {
return OPERATOR_PASS_THROUGH;
}
- else if (ele_act->head.htype == BM_EDGE) {
+ if (ele_act->head.htype == BM_EDGE) {
BMEdge *e_act = (BMEdge *)ele_act;
mid_v3_v3v3(center, e_act->v1->co, e_act->v2->co);
mul_m4_v3(vc.obedit->obmat, center);
@@ -503,9 +499,7 @@ static int edbm_polybuild_split_at_cursor_invoke(bContext *C,
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MESH_OT_polybuild_split_at_cursor(wmOperatorType *ot)
@@ -596,9 +590,7 @@ static int edbm_polybuild_dissolve_at_cursor_invoke(bContext *C,
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MESH_OT_polybuild_dissolve_at_cursor(wmOperatorType *ot)
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index e805507351c..89a90dcf12d 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -155,9 +155,7 @@ static float edbm_rip_edge_side_measure(
dist_squared_to_line_segment_v2(fmval, e_v1_co, e_v2_co)) {
return score;
}
- else {
- return -score;
- }
+ return -score;
}
/* - Advanced selection handling 'ripsel' functions ----- */
@@ -433,9 +431,7 @@ static UnorderedLoopPair *edbm_tagged_loop_pairs_to_fill(BMesh *bm)
return uloop_pairs;
}
- else {
- return NULL;
- }
+ return NULL;
}
static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *uloop_pairs)
@@ -658,89 +654,88 @@ static int edbm_rip_invoke__vert(bContext *C, const wmEvent *event, Object *obed
/* should never happen */
return OPERATOR_CANCELLED;
}
- else {
- int vi_best = 0;
- if (ese.ele) {
- BM_select_history_remove(bm, ese.ele);
- }
+ int vi_best = 0;
- dist_sq = FLT_MAX;
+ if (ese.ele) {
+ BM_select_history_remove(bm, ese.ele);
+ }
+
+ dist_sq = FLT_MAX;
- /* in the loop below we find the best vertex to drag based on its connected geometry,
- * either by its face corner, or connected edge (when no faces are attached) */
- for (i = 0; i < vout_len; i++) {
+ /* in the loop below we find the best vertex to drag based on its connected geometry,
+ * either by its face corner, or connected edge (when no faces are attached) */
+ for (i = 0; i < vout_len; i++) {
- if (BM_vert_is_wire(vout[i]) == false) {
- /* find the best face corner */
- BM_ITER_ELEM (l, &iter, vout[i], BM_LOOPS_OF_VERT) {
- if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) {
- float l_mid_co[3];
+ if (BM_vert_is_wire(vout[i]) == false) {
+ /* find the best face corner */
+ BM_ITER_ELEM (l, &iter, vout[i], BM_LOOPS_OF_VERT) {
+ if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) {
+ float l_mid_co[3];
- edbm_calc_loop_co(l, l_mid_co);
- d = edbm_rip_edgedist_squared(
- region, projectMat, v->co, l_mid_co, fmval, INSET_DEFAULT);
+ edbm_calc_loop_co(l, l_mid_co);
+ d = edbm_rip_edgedist_squared(
+ region, projectMat, v->co, l_mid_co, fmval, INSET_DEFAULT);
- if (d < dist_sq) {
- dist_sq = d;
- vi_best = i;
- }
+ if (d < dist_sq) {
+ dist_sq = d;
+ vi_best = i;
}
}
}
- else {
- BMEdge *e;
- /* a wire vert, find the best edge */
- BM_ITER_ELEM (e, &iter, vout[i], BM_EDGES_OF_VERT) {
- if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- float e_mid_co[3];
-
- mid_v3_v3v3(e_mid_co, e->v1->co, e->v2->co);
- d = edbm_rip_edgedist_squared(
- region, projectMat, v->co, e_mid_co, fmval, INSET_DEFAULT);
-
- if (d < dist_sq) {
- dist_sq = d;
- vi_best = i;
- }
+ }
+ else {
+ BMEdge *e;
+ /* a wire vert, find the best edge */
+ BM_ITER_ELEM (e, &iter, vout[i], BM_EDGES_OF_VERT) {
+ if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ float e_mid_co[3];
+
+ mid_v3_v3v3(e_mid_co, e->v1->co, e->v2->co);
+ d = edbm_rip_edgedist_squared(
+ region, projectMat, v->co, e_mid_co, fmval, INSET_DEFAULT);
+
+ if (d < dist_sq) {
+ dist_sq = d;
+ vi_best = i;
}
}
}
}
+ }
- /* vout[0] == best
- * vout[1] == glue
- * vout[2+] == splice with glue (when vout_len > 2)
- */
- if (vi_best != 0) {
- SWAP(BMVert *, vout[0], vout[vi_best]);
- vi_best = 0;
- }
+ /* vout[0] == best
+ * vout[1] == glue
+ * vout[2+] == splice with glue (when vout_len > 2)
+ */
+ if (vi_best != 0) {
+ SWAP(BMVert *, vout[0], vout[vi_best]);
+ vi_best = 0;
+ }
- /* select the vert from the best region */
- v = vout[vi_best];
- BM_vert_select_set(bm, v, true);
+ /* select the vert from the best region */
+ v = vout[vi_best];
+ BM_vert_select_set(bm, v, true);
- if (ese.ele) {
- BM_select_history_store(bm, v);
- }
+ if (ese.ele) {
+ BM_select_history_store(bm, v);
+ }
- /* splice all others back together */
- if (vout_len > 2) {
- for (i = 2; i < vout_len; i++) {
- BM_vert_splice(bm, vout[1], vout[i]);
- }
+ /* splice all others back together */
+ if (vout_len > 2) {
+ for (i = 2; i < vout_len; i++) {
+ BM_vert_splice(bm, vout[1], vout[i]);
}
+ }
- if (do_fill) {
- /* match extrude vert-order */
- BM_edge_create(bm, vout[1], vout[0], NULL, BM_CREATE_NOP);
- }
+ if (do_fill) {
+ /* match extrude vert-order */
+ BM_edge_create(bm, vout[1], vout[0], NULL, BM_CREATE_NOP);
+ }
- MEM_freeN(vout);
+ MEM_freeN(vout);
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
if (!e_best) {
@@ -1090,15 +1085,15 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* Ignore it. */
return OPERATOR_CANCELLED;
}
- else if (error_face_selected) {
+ if (error_face_selected) {
BKE_report(op->reports, RPT_ERROR, "Cannot rip selected faces");
return OPERATOR_CANCELLED;
}
- else if (error_disconnected_vertices) {
+ if (error_disconnected_vertices) {
BKE_report(op->reports, RPT_ERROR, "Cannot rip multiple disconnected vertices");
return OPERATOR_CANCELLED;
}
- else if (error_rip_failed) {
+ if (error_rip_failed) {
BKE_report(op->reports, RPT_ERROR, "Rip failed");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index fe83d9f00ea..d2e9b57e950 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -205,7 +205,7 @@ static BMElem *edbm_select_id_bm_elem_get(Base **bases, const uint sel_id, uint
/* -------------------------------------------------------------------- */
/** \name Find Nearest Vert/Edge/Face
*
- * \note Screen-space manhatten distances are used here,
+ * \note Screen-space manhattan distances are used here,
* since its faster and good enough for the purpose of selection.
*
* \note \a dist_bias is used so we can bias against selected items.
@@ -316,65 +316,63 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
}
return NULL;
}
- else {
- struct NearestVertUserData data = {{0}};
- const struct NearestVertUserData_Hit *hit = NULL;
- const eV3DProjTest clip_flag = RV3D_CLIPPING_ENABLED(vc->v3d, vc->rv3d) ?
- V3D_PROJ_TEST_CLIP_DEFAULT :
- V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB;
- BMesh *prev_select_bm = NULL;
-
- static struct {
- int index;
- const BMVert *elem;
- const BMesh *bm;
- } prev_select = {0};
-
- data.mval_fl[0] = vc->mval[0];
- data.mval_fl[1] = vc->mval[1];
- data.use_select_bias = use_select_bias;
- data.use_cycle = use_cycle;
-
- for (; base_index < bases_len; base_index++) {
- Base *base_iter = bases[base_index];
- ED_view3d_viewcontext_init_object(vc, base_iter->object);
- if (use_cycle && prev_select.bm == vc->em->bm &&
- prev_select.elem == BM_vert_at_index_find_or_table(vc->em->bm, prev_select.index)) {
- data.cycle_index_prev = prev_select.index;
- /* No need to compare in the rest of the loop. */
- use_cycle = false;
- }
- else {
- data.cycle_index_prev = 0;
- }
- data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
- *r_dist;
+ struct NearestVertUserData data = {{0}};
+ const struct NearestVertUserData_Hit *hit = NULL;
+ const eV3DProjTest clip_flag = RV3D_CLIPPING_ENABLED(vc->v3d, vc->rv3d) ?
+ V3D_PROJ_TEST_CLIP_DEFAULT :
+ V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB;
+ BMesh *prev_select_bm = NULL;
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, clip_flag);
+ static struct {
+ int index;
+ const BMVert *elem;
+ const BMesh *bm;
+ } prev_select = {0};
- hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit;
+ data.mval_fl[0] = vc->mval[0];
+ data.mval_fl[1] = vc->mval[1];
+ data.use_select_bias = use_select_bias;
+ data.use_cycle = use_cycle;
- if (hit->dist < *r_dist) {
- if (r_base_index) {
- *r_base_index = base_index;
- }
- *r_dist = hit->dist;
- prev_select_bm = vc->em->bm;
- }
+ for (; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ ED_view3d_viewcontext_init_object(vc, base_iter->object);
+ if (use_cycle && prev_select.bm == vc->em->bm &&
+ prev_select.elem == BM_vert_at_index_find_or_table(vc->em->bm, prev_select.index)) {
+ data.cycle_index_prev = prev_select.index;
+ /* No need to compare in the rest of the loop. */
+ use_cycle = false;
}
-
- if (hit == NULL) {
- return NULL;
+ else {
+ data.cycle_index_prev = 0;
}
- prev_select.index = hit->index;
- prev_select.elem = hit->vert;
- prev_select.bm = prev_select_bm;
+ data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist;
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, clip_flag);
+
+ hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit;
+
+ if (hit->dist < *r_dist) {
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
+ *r_dist = hit->dist;
+ prev_select_bm = vc->em->bm;
+ }
+ }
- return hit->vert;
+ if (hit == NULL) {
+ return NULL;
}
+
+ prev_select.index = hit->index;
+ prev_select.elem = hit->vert;
+ prev_select.bm = prev_select_bm;
+
+ return hit->vert;
}
BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist)
@@ -417,7 +415,7 @@ struct NearestEdgeUserData_Hit {
int index;
BMEdge *edge;
- /* edges only, un-biased manhatten distance to which ever edge we pick
+ /* edges only, un-biased manhattan distance to which ever edge we pick
* (not used for choosing) */
float dist_center;
};
@@ -563,69 +561,67 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
}
return NULL;
}
- else {
- struct NearestEdgeUserData data = {{0}};
- const struct NearestEdgeUserData_Hit *hit = NULL;
- /* interpolate along the edge before doing a clipping plane test */
- const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB;
- BMesh *prev_select_bm = NULL;
-
- static struct {
- int index;
- const BMEdge *elem;
- const BMesh *bm;
- } prev_select = {0};
-
- data.vc = *vc;
- data.mval_fl[0] = vc->mval[0];
- data.mval_fl[1] = vc->mval[1];
- data.use_select_bias = use_select_bias;
- data.use_cycle = use_cycle;
-
- for (; base_index < bases_len; base_index++) {
- Base *base_iter = bases[base_index];
- ED_view3d_viewcontext_init_object(vc, base_iter->object);
- if (use_cycle && prev_select.bm == vc->em->bm &&
- prev_select.elem == BM_edge_at_index_find_or_table(vc->em->bm, prev_select.index)) {
- data.cycle_index_prev = prev_select.index;
- /* No need to compare in the rest of the loop. */
- use_cycle = false;
- }
- else {
- data.cycle_index_prev = 0;
- }
- data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
- *r_dist;
+ struct NearestEdgeUserData data = {{0}};
+ const struct NearestEdgeUserData_Hit *hit = NULL;
+ /* interpolate along the edge before doing a clipping plane test */
+ const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB;
+ BMesh *prev_select_bm = NULL;
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenEdge(vc, find_nearest_edge__doClosest, &data, clip_flag);
+ static struct {
+ int index;
+ const BMEdge *elem;
+ const BMesh *bm;
+ } prev_select = {0};
- hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit;
+ data.vc = *vc;
+ data.mval_fl[0] = vc->mval[0];
+ data.mval_fl[1] = vc->mval[1];
+ data.use_select_bias = use_select_bias;
+ data.use_cycle = use_cycle;
- if (hit->dist < *r_dist) {
- if (r_base_index) {
- *r_base_index = base_index;
- }
- *r_dist = hit->dist;
- prev_select_bm = vc->em->bm;
- }
+ for (; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ ED_view3d_viewcontext_init_object(vc, base_iter->object);
+ if (use_cycle && prev_select.bm == vc->em->bm &&
+ prev_select.elem == BM_edge_at_index_find_or_table(vc->em->bm, prev_select.index)) {
+ data.cycle_index_prev = prev_select.index;
+ /* No need to compare in the rest of the loop. */
+ use_cycle = false;
}
-
- if (hit == NULL) {
- return NULL;
+ else {
+ data.cycle_index_prev = 0;
}
- if (r_dist_center) {
- *r_dist_center = hit->dist_center;
+ data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist;
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ mesh_foreachScreenEdge(vc, find_nearest_edge__doClosest, &data, clip_flag);
+
+ hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit;
+
+ if (hit->dist < *r_dist) {
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
+ *r_dist = hit->dist;
+ prev_select_bm = vc->em->bm;
}
+ }
- prev_select.index = hit->index;
- prev_select.elem = hit->edge;
- prev_select.bm = prev_select_bm;
+ if (hit == NULL) {
+ return NULL;
+ }
- return hit->edge;
+ if (r_dist_center) {
+ *r_dist_center = hit->dist_center;
}
+
+ prev_select.index = hit->index;
+ prev_select.elem = hit->edge;
+ prev_select.bm = prev_select_bm;
+
+ return hit->edge;
}
BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist)
@@ -769,67 +765,65 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
}
return NULL;
}
- else {
- struct NearestFaceUserData data = {{0}};
- const struct NearestFaceUserData_Hit *hit = NULL;
- const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT;
- BMesh *prev_select_bm = NULL;
-
- static struct {
- int index;
- const BMFace *elem;
- const BMesh *bm;
- } prev_select = {0};
-
- data.mval_fl[0] = vc->mval[0];
- data.mval_fl[1] = vc->mval[1];
- data.use_select_bias = use_select_bias;
- data.use_cycle = use_cycle;
-
- for (; base_index < bases_len; base_index++) {
- Base *base_iter = bases[base_index];
- ED_view3d_viewcontext_init_object(vc, base_iter->object);
- if (use_cycle && prev_select.bm == vc->em->bm &&
- prev_select.elem == BM_face_at_index_find_or_table(vc->em->bm, prev_select.index)) {
- data.cycle_index_prev = prev_select.index;
- /* No need to compare in the rest of the loop. */
- use_cycle = false;
- }
- else {
- data.cycle_index_prev = 0;
- }
- data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
- *r_dist;
+ struct NearestFaceUserData data = {{0}};
+ const struct NearestFaceUserData_Hit *hit = NULL;
+ const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT;
+ BMesh *prev_select_bm = NULL;
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, clip_flag);
+ static struct {
+ int index;
+ const BMFace *elem;
+ const BMesh *bm;
+ } prev_select = {0};
- hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit;
+ data.mval_fl[0] = vc->mval[0];
+ data.mval_fl[1] = vc->mval[1];
+ data.use_select_bias = use_select_bias;
+ data.use_cycle = use_cycle;
- if (hit->dist < *r_dist) {
- if (r_base_index) {
- *r_base_index = base_index;
- }
- *r_dist = hit->dist;
- prev_select_bm = vc->em->bm;
- }
+ for (; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ ED_view3d_viewcontext_init_object(vc, base_iter->object);
+ if (use_cycle && prev_select.bm == vc->em->bm &&
+ prev_select.elem == BM_face_at_index_find_or_table(vc->em->bm, prev_select.index)) {
+ data.cycle_index_prev = prev_select.index;
+ /* No need to compare in the rest of the loop. */
+ use_cycle = false;
}
-
- if (hit == NULL) {
- return NULL;
+ else {
+ data.cycle_index_prev = 0;
}
- if (r_dist_center) {
- *r_dist_center = hit->dist;
+ data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias = *r_dist;
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+ mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, clip_flag);
+
+ hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit;
+
+ if (hit->dist < *r_dist) {
+ if (r_base_index) {
+ *r_base_index = base_index;
+ }
+ *r_dist = hit->dist;
+ prev_select_bm = vc->em->bm;
}
+ }
- prev_select.index = hit->index;
- prev_select.elem = hit->face;
- prev_select.bm = prev_select_bm;
+ if (hit == NULL) {
+ return NULL;
+ }
- return hit->face;
+ if (r_dist_center) {
+ *r_dist_center = hit->dist;
}
+
+ prev_select.index = hit->index;
+ prev_select.elem = hit->face;
+ prev_select.bm = prev_select_bm;
+
+ return hit->face;
}
BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
@@ -1353,9 +1347,7 @@ static int edbm_select_mode_exec(bContext *C, wmOperator *op)
if (EDBM_selectmode_toggle_multi(C, type, action, use_extend, use_expand)) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -1809,9 +1801,7 @@ static int edbm_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *e
RNA_boolean_get(op->ptr, "ring"))) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MESH_OT_loop_select(wmOperatorType *ot)
@@ -2556,9 +2546,7 @@ bool EDBM_selectmode_disable(Scene *scene,
return true;
}
- else {
- return false;
- }
+ return false;
}
/** \} */
@@ -4202,11 +4190,11 @@ static bool edbm_deselect_nth(BMEditMesh *em, const struct CheckerIntervalParams
walker_deselect_nth(em, op_params, &v->head);
return true;
}
- else if (e) {
+ if (e) {
walker_deselect_nth(em, op_params, &e->head);
return true;
}
- else if (f) {
+ if (f) {
walker_deselect_nth(em, op_params, &f->head);
return true;
}
@@ -4241,10 +4229,7 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op)
MEM_freeN(objects);
if (!found_active_elt) {
- BKE_report(op->reports,
- RPT_ERROR,
- (objects_len == 1 ? "Mesh has no active vert/edge/face" :
- "Meshes have no active vert/edge/face"));
+ BKE_report(op->reports, RPT_ERROR, "Mesh object(s) have no active vertex/edge/face");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c
index 635fc6279ea..b3fb9747070 100644
--- a/source/blender/editors/mesh/editmesh_select_similar.c
+++ b/source/blender/editors/mesh/editmesh_select_similar.c
@@ -245,9 +245,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
if (custom_data_offset == -1) {
continue;
}
- else {
- gset_array[ob_index] = BLI_gset_ptr_new("Select similar face: facemap gset");
- }
+ gset_array[ob_index] = BLI_gset_ptr_new("Select similar face: facemap gset");
}
}
@@ -1249,12 +1247,10 @@ static int edbm_select_similar_exec(bContext *C, wmOperator *op)
if (type < 100) {
return similar_vert_select_exec(C, op);
}
- else if (type < 200) {
+ if (type < 200) {
return similar_edge_select_exec(C, op);
}
- else {
- return similar_face_select_exec(C, op);
- }
+ return similar_face_select_exec(C, op);
}
static const EnumPropertyItem *select_similar_type_itemf(bContext *C,
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 2cffb3ecdec..29860de88f1 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -1557,7 +1557,7 @@ static int edbm_vert_connect_path_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Invalid selection order");
return OPERATOR_CANCELLED;
}
- else if (failed_connect_len == objects_len) {
+ if (failed_connect_len == objects_len) {
BKE_report(op->reports, RPT_ERROR, "Could not connect vertices");
return OPERATOR_CANCELLED;
}
@@ -2035,19 +2035,26 @@ static bool flip_custom_normals(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr)
}
BMFace *f;
- BMLoop *l;
- BMIter iter_f, iter_l;
+ BMLoop *l, *l_start;
+ BMIter iter_f;
BM_ITER_MESH (f, &iter_f, bm, BM_FACES_OF_MESH) {
+ /* Flip all the custom loop normals on the selected faces. */
if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
continue;
}
- /* Flip all the custom loop normals on the selected faces. */
- BM_ITER_ELEM (l, &iter_l, f, BM_LOOPS_OF_FACE) {
+ /* Because the winding has changed, we need to go the reverse way around the face to get the
+ * correct placement of the normals. However we need to derive the old loop index to get the
+ * correct data. Note that the first loop index is the same though. So the loop starts and ends
+ * in the same place as before the flip.
+ */
+ l_start = l = BM_FACE_FIRST_LOOP(f);
+ int old_index = BM_elem_index_get(l);
+ do {
int loop_index = BM_elem_index_get(l);
- BMLoopNorEditData *lnor_ed = lnors_ed_arr->lidx_to_lnor_editdata[loop_index];
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lidx_to_lnor_editdata[old_index];
BMLoopNorEditData *lnor_ed_new = lnors_ed_arr_new_full->lidx_to_lnor_editdata[loop_index];
BLI_assert(lnor_ed != NULL && lnor_ed_new != NULL);
@@ -2055,7 +2062,10 @@ static bool flip_custom_normals(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr)
BKE_lnor_space_custom_normal_to_data(
bm->lnor_spacearr->lspacearr[loop_index], lnor_ed->nloc, lnor_ed_new->clnors_data);
- }
+
+ old_index++;
+ l = l->prev;
+ } while (l != l_start);
}
BM_loop_normal_editdata_array_free(lnors_ed_arr_new_full);
return true;
@@ -2686,7 +2696,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "No selected vertex");
return OPERATOR_CANCELLED;
}
- else if (tot_invalid == objects_len) {
+ if (tot_invalid == objects_len) {
BKE_report(op->reports, RPT_WARNING, "Selected faces must be triangles or quads");
return OPERATOR_CANCELLED;
}
@@ -3505,7 +3515,7 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No selected vertex");
return OPERATOR_CANCELLED;
}
- else if (tot_shapekeys == 0) {
+ if (tot_shapekeys == 0) {
BKE_report(op->reports,
RPT_ERROR,
objects_len > 1 ? "Meshes do not have shape keys" :
@@ -3562,7 +3572,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Active mesh does not have shape keys");
return OPERATOR_CANCELLED;
}
- else if (shape_ref >= totshape_ref) {
+ if (shape_ref >= totshape_ref) {
/* This case occurs if operator was used before on object with more keys than current one. */
shape_ref = 0; /* default to basis */
}
@@ -3592,10 +3602,8 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
if (!key) {
continue;
}
- else {
- kb = BKE_keyblock_find_name(key, kb_ref->name);
- shape = BLI_findindex(&key->block, kb);
- }
+ kb = BKE_keyblock_find_name(key, kb_ref->name);
+ shape = BLI_findindex(&key->block, kb);
if (kb) {
/* Perform blending on selected vertices. */
@@ -3679,7 +3687,10 @@ static void edbm_blend_from_shape_ui(bContext *C, wmOperator *op)
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
RNA_id_pointer_create((ID *)me->key, &ptr_key);
- uiItemPointerR(layout, &ptr, "shape", &ptr_key, "key_blocks", "", ICON_SHAPEKEY_DATA);
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ uiItemPointerR(layout, &ptr, "shape", &ptr_key, "key_blocks", NULL, ICON_SHAPEKEY_DATA);
uiItemR(layout, &ptr, "blend", 0, NULL, ICON_NONE);
uiItemR(layout, &ptr, "add", 0, NULL, ICON_NONE);
}
@@ -3861,7 +3872,7 @@ static float bm_edge_seg_isect(const float sco_a[2],
return perc;
}
/* test e->v2 */
- else if ((x11 == x22 && y11 == y22) || (x12 == x22 && y12 == y22)) {
+ if ((x11 == x22 && y11 == y22) || (x12 == x22 && y12 == y22)) {
perc = 0;
*isected = 2;
return perc;
@@ -4171,7 +4182,8 @@ static Base *mesh_separate_tagged(
BKE_object_material_array_assign(bmain,
base_new->object,
BKE_object_material_array_p(obedit),
- *BKE_object_material_len_p(obedit));
+ *BKE_object_material_len_p(obedit),
+ false);
ED_object_base_select(base_new, BA_SELECT);
@@ -4243,7 +4255,8 @@ static Base *mesh_separate_arrays(Main *bmain,
BKE_object_material_array_assign(bmain,
base_new->object,
BKE_object_material_array_p(obedit),
- *BKE_object_material_len_p(obedit));
+ *BKE_object_material_len_p(obedit),
+ false);
ED_object_base_select(base_new, BA_SELECT);
@@ -5589,25 +5602,26 @@ static bool edbm_decimate_check(bContext *UNUSED(C), wmOperator *UNUSED(op))
static void edbm_decimate_ui(bContext *UNUSED(C), wmOperator *op)
{
- uiLayout *layout = op->layout, *box, *row, *col;
+ uiLayout *layout = op->layout, *row, *col, *sub;
PointerRNA ptr;
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
+ uiLayoutSetPropSep(layout, true);
+
uiItemR(layout, &ptr, "ratio", 0, NULL, ICON_NONE);
- box = uiLayoutBox(layout);
- uiItemR(box, &ptr, "use_vertex_group", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(box, false);
+ uiItemR(layout, &ptr, "use_vertex_group", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col, RNA_boolean_get(&ptr, "use_vertex_group"));
uiItemR(col, &ptr, "vertex_group_factor", 0, NULL, ICON_NONE);
uiItemR(col, &ptr, "invert_vertex_group", 0, NULL, ICON_NONE);
- box = uiLayoutBox(layout);
- uiItemR(box, &ptr, "use_symmetry", 0, NULL, ICON_NONE);
- row = uiLayoutRow(box, true);
- uiLayoutSetActive(row, RNA_boolean_get(&ptr, "use_symmetry"));
- uiItemR(row, &ptr, "symmetry_axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ row = uiLayoutRowWithHeading(layout, true, IFACE_("Symmetry"));
+ uiItemR(row, &ptr, "use_symmetry", 0, "", ICON_NONE);
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_symmetry"));
+ uiItemR(sub, &ptr, "symmetry_axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
void MESH_OT_decimate(wmOperatorType *ot)
@@ -5662,7 +5676,7 @@ static void edbm_dissolve_prop__use_verts(wmOperatorType *ot, bool value, int fl
PropertyRNA *prop;
prop = RNA_def_boolean(
- ot->srna, "use_verts", value, "Dissolve Verts", "Dissolve remaining vertices");
+ ot->srna, "use_verts", value, "Dissolve Vertices", "Dissolve remaining vertices");
if (flag) {
RNA_def_property_flag(prop, flag);
@@ -5727,7 +5741,7 @@ void MESH_OT_dissolve_verts(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Dissolve Vertices";
- ot->description = "Dissolve verts, merge edges and faces";
+ ot->description = "Dissolve vertices, merge edges and faces";
ot->idname = "MESH_OT_dissolve_verts";
/* api callbacks */
@@ -5885,12 +5899,10 @@ static int edbm_dissolve_mode_exec(bContext *C, wmOperator *op)
if (em->selectmode & SCE_SELECT_VERTEX) {
return edbm_dissolve_verts_exec(C, op);
}
- else if (em->selectmode & SCE_SELECT_EDGE) {
+ if (em->selectmode & SCE_SELECT_EDGE) {
return edbm_dissolve_edges_exec(C, op);
}
- else {
- return edbm_dissolve_faces_exec(C, op);
- }
+ return edbm_dissolve_faces_exec(C, op);
}
void MESH_OT_dissolve_mode(wmOperatorType *ot)
@@ -5996,7 +6008,7 @@ void MESH_OT_dissolve_limited(wmOperatorType *ot)
ot->name = "Limited Dissolve";
ot->idname = "MESH_OT_dissolve_limited";
ot->description =
- "Dissolve selected edges and verts, limited by the angle of surrounding geometry";
+ "Dissolve selected edges and vertices, limited by the angle of surrounding geometry";
/* api callbacks */
ot->exec = edbm_dissolve_limited_exec;
@@ -6814,9 +6826,7 @@ static bool edbm_sort_elements_poll_property(const bContext *UNUSED(C),
if (action == SRT_RANDOMIZE) {
return true;
}
- else {
- return false;
- }
+ return false;
}
/* Hide seed for reverse and randomize actions! */
@@ -6824,9 +6834,7 @@ static bool edbm_sort_elements_poll_property(const bContext *UNUSED(C),
if (ELEM(action, SRT_RANDOMIZE, SRT_REVERSE)) {
return false;
}
- else {
- return true;
- }
+ return true;
}
return true;
@@ -7211,7 +7219,7 @@ void MESH_OT_wireframe(wmOperatorType *ot)
PropertyRNA *prop;
/* identifiers */
- ot->name = "Wire Frame";
+ ot->name = "Wireframe";
ot->idname = "MESH_OT_wireframe";
ot->description = "Create a solid wire-frame from faces";
@@ -7507,10 +7515,8 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
if (!EDBM_op_finish(em, &bmop, op, true)) {
continue;
}
- else {
- EDBM_update_generic(obedit->data, true, true);
- EDBM_selectmode_flush(em);
- }
+ EDBM_update_generic(obedit->data, true, true);
+ EDBM_selectmode_flush(em);
}
MEM_freeN(objects);
@@ -7889,7 +7895,7 @@ void MESH_OT_mark_freestyle_face(wmOperatorType *ot)
/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
/* NOTE: We could add more here, like e.g. a switch between local or global coordinates of target,
- * use numinput to type in explicit vector values... */
+ * use number-input to type in explicit vector values. */
enum {
/* Generic commands. */
EDBM_CLNOR_MODAL_CANCEL = 1,
@@ -8413,6 +8419,8 @@ static void edbm_point_normals_ui(bContext *C, wmOperator *op)
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+ uiLayoutSetPropSep(layout, true);
+
/* Main auto-draw call */
uiDefAutoButsRNA(layout, &ptr, point_normals_draw_check_prop, NULL, NULL, '\0', false);
}
@@ -8701,17 +8709,21 @@ enum {
};
static EnumPropertyItem average_method_items[] = {
- {EDBM_CLNOR_AVERAGE_LOOP, "CUSTOM_NORMAL", 0, "Custom Normal", "Take Average of vert Normals"},
+ {EDBM_CLNOR_AVERAGE_LOOP,
+ "CUSTOM_NORMAL",
+ 0,
+ "Custom Normal",
+ "Take average of vertex normals"},
{EDBM_CLNOR_AVERAGE_FACE_AREA,
"FACE_AREA",
0,
"Face Area",
- "Set all vert normals by Face Area"},
+ "Set all vertex normals by face area"},
{EDBM_CLNOR_AVERAGE_ANGLE,
"CORNER_ANGLE",
0,
"Corner Angle",
- "Set all vert normals by Corner Angle"},
+ "Set all vertex normals by corner angle"},
{0, NULL, 0, NULL, NULL},
};
@@ -8869,7 +8881,7 @@ static bool average_normals_draw_check_prop(PointerRNA *ptr,
if (STREQ(prop_id, "weight")) {
return (average_type == EDBM_CLNOR_AVERAGE_LOOP);
}
- else if (STREQ(prop_id, "threshold")) {
+ if (STREQ(prop_id, "threshold")) {
return (average_type == EDBM_CLNOR_AVERAGE_LOOP);
}
@@ -8885,6 +8897,8 @@ static void edbm_average_normals_ui(bContext *C, wmOperator *op)
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+ uiLayoutSetPropSep(layout, true);
+
/* Main auto-draw call */
uiDefAutoButsRNA(layout, &ptr, average_normals_draw_check_prop, NULL, NULL, '\0', false);
}
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index e4ecfa9c680..9f625fd0515 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -619,7 +619,7 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key *
if (kb_act->totelem != um->me.totvert) {
/* The current mesh has some extra/missing verts compared to the undo, adjust. */
MEM_SAFE_FREE(kb_act->data);
- kb_act->data = MEM_mallocN((size_t)(key->elemsize * bm->totvert), __func__);
+ kb_act->data = MEM_mallocN((size_t)(key->elemsize) * bm->totvert, __func__);
kb_act->totelem = um->me.totvert;
}
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 6c9973dc209..46c63d2e057 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -187,20 +187,19 @@ bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool
return false;
}
- else {
- em->emcopyusers--;
- if (em->emcopyusers < 0) {
- printf("warning: em->emcopyusers was less than zero.\n");
- }
- if (em->emcopyusers <= 0) {
- BKE_editmesh_free(em->emcopy);
- MEM_freeN(em->emcopy);
- em->emcopy = NULL;
- }
+ em->emcopyusers--;
+ if (em->emcopyusers < 0) {
+ printf("warning: em->emcopyusers was less than zero.\n");
+ }
- return true;
+ if (em->emcopyusers <= 0) {
+ BKE_editmesh_free(em->emcopy);
+ MEM_freeN(em->emcopy);
+ em->emcopy = NULL;
}
+
+ return true;
}
bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...)
@@ -526,10 +525,7 @@ void EDBM_flag_enable_all(BMEditMesh *em, const char hflag)
/**
* Return a new UVVertMap from the editmesh
*/
-UvVertMap *BM_uv_vert_map_create(BMesh *bm,
- const float limit[2],
- const bool use_select,
- const bool use_winding)
+UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool use_winding)
{
BMVert *ev;
BMFace *efa;
@@ -538,7 +534,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm,
/* vars from original func */
UvVertMap *vmap;
UvMapVert *buf;
- MLoopUV *luv;
+ const MLoopUV *luv;
uint a;
int totverts, i, totuv, totfaces;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
@@ -610,7 +606,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm,
BM_ITER_MESH_INDEX (ev, &iter, bm, BM_VERTS_OF_MESH, a) {
UvMapVert *newvlist = NULL, *vlist = vmap->vert[a];
UvMapVert *iterv, *v, *lastv, *next;
- float *uv, *uv2, uvdiff[2];
+ const float *uv, *uv2;
while (vlist) {
v = vlist;
@@ -634,9 +630,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm,
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv2 = luv->uv;
- sub_v2_v2v2(uvdiff, uv2, uv);
-
- if (fabsf(uvdiff[0]) < limit[0] && fabsf(uvdiff[1]) < limit[1] &&
+ if (compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT) &&
(!use_winding || winding[iterv->poly_index] == winding[v->poly_index])) {
if (lastv) {
lastv->next = next;
@@ -778,7 +772,8 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
BM_ITER_MESH_INDEX (ev, &iter, bm, BM_VERTS_OF_MESH, i) {
UvElement *newvlist = NULL, *vlist = element_map->vert[i];
UvElement *iterv, *v, *lastv, *next;
- float *uv, *uv2, uvdiff[2];
+ const float *uv, *uv2;
+ bool uv_vert_sel, uv2_vert_sel;
while (vlist) {
v = vlist;
@@ -789,6 +784,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
l = v->l;
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv = luv->uv;
+ uv_vert_sel = luv->flag & MLOOPUV_VERTSEL;
lastv = NULL;
iterv = vlist;
@@ -799,12 +795,15 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
l = iterv->l;
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
uv2 = luv->uv;
+ uv2_vert_sel = luv->flag & MLOOPUV_VERTSEL;
- sub_v2_v2v2(uvdiff, uv2, uv);
+ /* Check if the uv loops share the same selection state (if not, they are not connected as
+ * they have been ripped or other edit commands have separated them). */
+ const bool connected = (uv_vert_sel == uv2_vert_sel) &&
+ compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT);
- if (fabsf(uvdiff[0]) < STD_UV_CONNECT_LIMIT && fabsf(uvdiff[1]) < STD_UV_CONNECT_LIMIT &&
- (!use_winding ||
- winding[BM_elem_index_get(iterv->l->f)] == winding[BM_elem_index_get(v->l->f)])) {
+ if (connected && (!use_winding || winding[BM_elem_index_get(iterv->l->f)] ==
+ winding[BM_elem_index_get(v->l->f)])) {
if (lastv) {
lastv->next = next;
}
@@ -1030,7 +1029,7 @@ bool EDBM_vert_color_check(BMEditMesh *em)
/** \name Mirror Cache API
* \{ */
-static BMVert *cache_mirr_intptr_as_bmvert(intptr_t *index_lookup, int index)
+static BMVert *cache_mirr_intptr_as_bmvert(const intptr_t *index_lookup, int index)
{
intptr_t eve_i = index_lookup[index];
return (eve_i == -1) ? NULL : (BMVert *)eve_i;
@@ -1628,10 +1627,10 @@ bool BMBVH_EdgeVisible(struct BMBVHTree *tree,
if (f && !edge_ray_cast(tree, co2, dir2, NULL, e)) {
return true;
}
- else if (f && !edge_ray_cast(tree, co3, dir3, NULL, e)) {
+ if (f && !edge_ray_cast(tree, co3, dir3, NULL, e)) {
return true;
}
- else if (!f) {
+ if (!f) {
return true;
}
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 8fce726eff5..f608e5ce6a5 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -370,9 +370,7 @@ bool ED_mesh_uv_texture_remove_active(Mesh *me)
if (n != -1) {
return ED_mesh_uv_texture_remove_index(me, n);
}
- else {
- return false;
- }
+ return false;
}
bool ED_mesh_uv_texture_remove_named(Mesh *me, const char *name)
{
@@ -382,9 +380,7 @@ bool ED_mesh_uv_texture_remove_named(Mesh *me, const char *name)
if (n != -1) {
return ED_mesh_uv_texture_remove_index(me, n);
}
- else {
- return false;
- }
+ return false;
}
/* note: keep in sync with ED_mesh_uv_texture_add */
@@ -479,9 +475,7 @@ bool ED_mesh_color_remove_active(Mesh *me)
if (n != -1) {
return ED_mesh_color_remove_index(me, n);
}
- else {
- return false;
- }
+ return false;
}
bool ED_mesh_color_remove_named(Mesh *me, const char *name)
{
@@ -490,9 +484,7 @@ bool ED_mesh_color_remove_named(Mesh *me, const char *name)
if (n != -1) {
return ED_mesh_color_remove_index(me, n);
}
- else {
- return false;
- }
+ return false;
}
/*********************** Sculpt Vertex colors operators ************************/
@@ -590,9 +582,7 @@ bool ED_mesh_sculpt_color_remove_active(Mesh *me)
if (n != -1) {
return ED_mesh_sculpt_color_remove_index(me, n);
}
- else {
- return false;
- }
+ return false;
}
bool ED_mesh_sculpt_color_remove_named(Mesh *me, const char *name)
{
@@ -601,9 +591,7 @@ bool ED_mesh_sculpt_color_remove_named(Mesh *me, const char *name)
if (n != -1) {
return ED_mesh_sculpt_color_remove_index(me, n);
}
- else {
- return false;
- }
+ return false;
}
/*********************** UV texture operators ************************/
@@ -817,9 +805,7 @@ static int mesh_customdata_clear_exec__internal(bContext *C, char htype, int typ
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
/* Clear Mask */
@@ -855,9 +841,7 @@ static int mesh_customdata_mask_clear_exec(bContext *C, wmOperator *UNUSED(op))
if (ret_a == OPERATOR_FINISHED || ret_b == OPERATOR_FINISHED) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void MESH_OT_customdata_mask_clear(wmOperatorType *ot)
@@ -1289,7 +1273,7 @@ void ED_mesh_verts_remove(Mesh *mesh, ReportList *reports, int count)
BKE_report(reports, RPT_ERROR, "Cannot remove vertices in edit mode");
return;
}
- else if (count > mesh->totvert) {
+ if (count > mesh->totvert) {
BKE_report(reports, RPT_ERROR, "Cannot remove more vertices than the mesh contains");
return;
}
@@ -1303,7 +1287,7 @@ void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count)
BKE_report(reports, RPT_ERROR, "Cannot remove edges in edit mode");
return;
}
- else if (count > mesh->totedge) {
+ if (count > mesh->totedge) {
BKE_report(reports, RPT_ERROR, "Cannot remove more edges than the mesh contains");
return;
}
@@ -1317,7 +1301,7 @@ void ED_mesh_loops_remove(Mesh *mesh, ReportList *reports, int count)
BKE_report(reports, RPT_ERROR, "Cannot remove loops in edit mode");
return;
}
- else if (count > mesh->totloop) {
+ if (count > mesh->totloop) {
BKE_report(reports, RPT_ERROR, "Cannot remove more loops than the mesh contains");
return;
}
@@ -1331,7 +1315,7 @@ void ED_mesh_polys_remove(Mesh *mesh, ReportList *reports, int count)
BKE_report(reports, RPT_ERROR, "Cannot remove polys in edit mode");
return;
}
- else if (count > mesh->totpoly) {
+ if (count > mesh->totpoly) {
BKE_report(reports, RPT_ERROR, "Cannot remove more polys than the mesh contains");
return;
}
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index bebad312454..bb5da8f3a9c 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -23,8 +23,7 @@
/* Internal for editmesh_xxxx.c functions */
-#ifndef __MESH_INTERN_H__
-#define __MESH_INTERN_H__
+#pragma once
struct BMEditMesh;
struct BMElem;
@@ -76,6 +75,7 @@ struct BMElem *EDBM_elem_from_selectmode(struct BMEditMesh *em,
struct BMVert *eve,
struct BMEdge *eed,
struct BMFace *efa);
+
int EDBM_elem_to_index_any(struct BMEditMesh *em, struct BMElem *ele);
struct BMElem *EDBM_elem_from_index_any(struct BMEditMesh *em, int index);
@@ -275,5 +275,3 @@ void MESH_OT_customdata_skin_add(struct wmOperatorType *ot);
void MESH_OT_customdata_skin_clear(struct wmOperatorType *ot);
void MESH_OT_customdata_custom_splitnormals_add(struct wmOperatorType *ot);
void MESH_OT_customdata_custom_splitnormals_clear(struct wmOperatorType *ot);
-
-#endif /* __MESH_INTERN_H__ */
diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c
index 0bbc8b0df76..0f746dfd3a0 100644
--- a/source/blender/editors/mesh/mesh_mirror.c
+++ b/source/blender/editors/mesh/mesh_mirror.c
@@ -129,7 +129,7 @@ static int mirrtopo_hash_sort(const void *l1, const void *l2)
if ((MirrTopoHash_t)(intptr_t)l1 > (MirrTopoHash_t)(intptr_t)l2) {
return 1;
}
- else if ((MirrTopoHash_t)(intptr_t)l1 < (MirrTopoHash_t)(intptr_t)l2) {
+ if ((MirrTopoHash_t)(intptr_t)l1 < (MirrTopoHash_t)(intptr_t)l2) {
return -1;
}
return 0;
@@ -140,7 +140,7 @@ static int mirrtopo_vert_sort(const void *v1, const void *v2)
if (((MirrTopoVert_t *)v1)->hash > ((MirrTopoVert_t *)v2)->hash) {
return 1;
}
- else if (((MirrTopoVert_t *)v1)->hash < ((MirrTopoVert_t *)v2)->hash) {
+ if (((MirrTopoVert_t *)v1)->hash < ((MirrTopoVert_t *)v2)->hash) {
return -1;
}
return 0;
@@ -166,9 +166,7 @@ bool ED_mesh_mirrtopo_recalc_check(BMEditMesh *em, Mesh *me, MirrTopoStore_t *me
(totvert != mesh_topo_store->prev_vert_tot) || (totedge != mesh_topo_store->prev_edge_tot)) {
return true;
}
- else {
- return false;
- }
+ return false;
}
void ED_mesh_mirrtopo_init(BMEditMesh *em,
@@ -278,10 +276,8 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em,
* higher number of unique values compared to the previous loop. */
break;
}
- else {
- tot_unique_prev = tot_unique;
- tot_unique_edges_prev = tot_unique_edges;
- }
+ tot_unique_prev = tot_unique;
+ tot_unique_edges_prev = tot_unique_edges;
/* Copy the hash calculated this iteration, so we can use them next time */
memcpy(topo_hash_prev, topo_hash, sizeof(MirrTopoHash_t) * totvert);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 1bdf2ede22a..4d84db9b35b 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -297,6 +297,37 @@ static void join_mesh_single(Depsgraph *depsgraph,
*mpoly_pp += me->totpoly;
}
+/* Face Sets IDs are a sparse sequence, so this function offsets all the IDs by face_set_offset and
+ * updates face_set_offset with the maximum ID value. This way, when used in multiple meshes, all
+ * of them will have different IDs for their Face Sets. */
+static void mesh_join_offset_face_sets_ID(const Mesh *mesh, int *face_set_offset)
+{
+ if (!mesh->totpoly) {
+ return;
+ }
+
+ int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ if (!face_sets) {
+ return;
+ }
+
+ int max_face_set = 0;
+ for (int f = 0; f < mesh->totpoly; f++) {
+ /* As face sets encode the visibility in the integer sign, the offset needs to be added or
+ * subtracted depending on the initial sign of the integer to get the new ID. */
+ if (abs(face_sets[f]) <= *face_set_offset) {
+ if (face_sets[f] > 0) {
+ face_sets[f] += *face_set_offset;
+ }
+ else {
+ face_sets[f] -= *face_set_offset;
+ }
+ }
+ max_face_set = max_ii(max_face_set, abs(face_sets[f]));
+ }
+ *face_set_offset = max_face_set;
+}
+
int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -431,7 +462,13 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
key->type = KEY_RELATIVE;
}
- /* First pass over objects: Copying materials, vertex-groups & face-maps across. */
+ /* Update face_set_id_offset with the face set data in the active object first. This way the Face
+ * Sets IDs in the active object are not the ones that are modified. */
+ Mesh *mesh_active = BKE_mesh_from_object(ob);
+ int face_set_id_offset = 0;
+ mesh_join_offset_face_sets_ID(mesh_active, &face_set_id_offset);
+
+ /* Copy materials, vertex-groups, face sets & face-maps across objects. */
CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
/* only act if a mesh, and not the one we're joining to */
if ((ob != ob_iter) && (ob_iter->type == OB_MESH)) {
@@ -463,6 +500,8 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
ob->actfmap = 1;
}
+ mesh_join_offset_face_sets_ID(me, &face_set_id_offset);
+
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) */
@@ -892,9 +931,7 @@ int mesh_get_x_mirror_vert(Object *ob, Mesh *me_eval, int index, const bool use_
if (use_topology) {
return mesh_get_x_mirror_vert_topo(ob, me_eval, index);
}
- else {
- return mesh_get_x_mirror_vert_spatial(ob, me_eval, index);
- }
+ return mesh_get_x_mirror_vert_spatial(ob, me_eval, index);
}
static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, const float co[3])
@@ -963,9 +1000,7 @@ BMVert *editbmesh_get_x_mirror_vert(Object *ob,
if (use_topology) {
return editbmesh_get_x_mirror_vert_topo(ob, em, eve, index);
}
- else {
- return editbmesh_get_x_mirror_vert_spatial(ob, em, co);
- }
+ return editbmesh_get_x_mirror_vert_spatial(ob, em, co);
}
/**
@@ -1072,13 +1107,13 @@ static int mirror_facerotation(MFace *a, MFace *b)
if (a->v1 == b->v1 && a->v2 == b->v2 && a->v3 == b->v3 && a->v4 == b->v4) {
return 0;
}
- else if (a->v4 == b->v1 && a->v1 == b->v2 && a->v2 == b->v3 && a->v3 == b->v4) {
+ if (a->v4 == b->v1 && a->v1 == b->v2 && a->v2 == b->v3 && a->v3 == b->v4) {
return 1;
}
- else if (a->v3 == b->v1 && a->v4 == b->v2 && a->v1 == b->v3 && a->v2 == b->v4) {
+ if (a->v3 == b->v1 && a->v4 == b->v2 && a->v1 == b->v3 && a->v2 == b->v4) {
return 2;
}
- else if (a->v2 == b->v1 && a->v3 == b->v2 && a->v4 == b->v3 && a->v1 == b->v4) {
+ if (a->v2 == b->v1 && a->v3 == b->v2 && a->v4 == b->v3 && a->v1 == b->v4) {
return 3;
}
}
@@ -1086,10 +1121,10 @@ static int mirror_facerotation(MFace *a, MFace *b)
if (a->v1 == b->v1 && a->v2 == b->v2 && a->v3 == b->v3) {
return 0;
}
- else if (a->v3 == b->v1 && a->v1 == b->v2 && a->v2 == b->v3) {
+ if (a->v3 == b->v1 && a->v1 == b->v2 && a->v2 == b->v3) {
return 1;
}
- else if (a->v2 == b->v1 && a->v3 == b->v2 && a->v1 == b->v3) {
+ if (a->v2 == b->v1 && a->v3 == b->v2 && a->v1 == b->v3) {
return 2;
}
}
@@ -1468,9 +1503,7 @@ MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index)
if (index == -1 || me->dvert == NULL) {
return NULL;
}
- else {
- return me->dvert + index;
- }
+ return me->dvert + index;
}
MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
@@ -1479,13 +1512,9 @@ MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
if (ob->mode & OB_MODE_EDIT) {
return ED_mesh_active_dvert_get_em(ob, NULL);
}
- else {
- return ED_mesh_active_dvert_get_ob(ob, NULL);
- }
- }
- else {
- return NULL;
+ return ED_mesh_active_dvert_get_ob(ob, NULL);
}
+ return NULL;
}
void EDBM_mesh_stats_multi(struct Object **objects,
diff --git a/source/blender/editors/metaball/mball_intern.h b/source/blender/editors/metaball/mball_intern.h
index dec94f97b8a..2b90667f612 100644
--- a/source/blender/editors/metaball/mball_intern.h
+++ b/source/blender/editors/metaball/mball_intern.h
@@ -21,8 +21,7 @@
* \ingroup edmeta
*/
-#ifndef __MBALL_INTERN_H__
-#define __MBALL_INTERN_H__
+#pragma once
#include "DNA_object_types.h"
@@ -37,5 +36,3 @@ void MBALL_OT_duplicate_metaelems(struct wmOperatorType *ot);
void MBALL_OT_select_all(struct wmOperatorType *ot);
void MBALL_OT_select_similar(struct wmOperatorType *ot);
void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot);
-
-#endif
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 4850764eecd..bc9bef4dc63 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -255,13 +255,13 @@ void ED_object_base_init_transform_on_add(Object *object, const float loc[3], co
/* Uses context to figure out transform for primitive.
* Returns standard diameter. */
float ED_object_new_primitive_matrix(
- bContext *C, Object *obedit, const float loc[3], const float rot[3], float primmat[4][4])
+ bContext *C, Object *obedit, const float loc[3], const float rot[3], float r_primmat[4][4])
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
float mat[3][3], rmat[3][3], cmat[3][3], imat[3][3];
- unit_m4(primmat);
+ unit_m4(r_primmat);
eul_to_mat3(rmat, rot);
invert_m3(rmat);
@@ -270,13 +270,13 @@ float ED_object_new_primitive_matrix(
copy_m3_m4(mat, obedit->obmat);
mul_m3_m3m3(cmat, rmat, mat);
invert_m3_m3(imat, cmat);
- copy_m4_m3(primmat, imat);
+ copy_m4_m3(r_primmat, imat);
/* center */
- copy_v3_v3(primmat[3], loc);
- sub_v3_v3v3(primmat[3], primmat[3], obedit->obmat[3]);
+ copy_v3_v3(r_primmat[3], loc);
+ sub_v3_v3v3(r_primmat[3], r_primmat[3], obedit->obmat[3]);
invert_m3_m3(imat, mat);
- mul_m3_v3(imat, primmat[3]);
+ mul_m3_v3(imat, r_primmat[3]);
{
const float dia = v3d ? ED_view3d_grid_scale(scene, v3d, NULL) :
@@ -692,6 +692,46 @@ void OBJECT_OT_lightprobe_add(wmOperatorType *ot)
* \{ */
/* for object add operator */
+
+static const char *get_effector_defname(ePFieldType type)
+{
+ switch (type) {
+ case PFIELD_FORCE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Force");
+ case PFIELD_VORTEX:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Vortex");
+ case PFIELD_MAGNET:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Magnet");
+ case PFIELD_WIND:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Wind");
+ case PFIELD_GUIDE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "CurveGuide");
+ case PFIELD_TEXTURE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "TextureField");
+ case PFIELD_HARMONIC:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Harmonic");
+ case PFIELD_CHARGE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Charge");
+ case PFIELD_LENNARDJ:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Lennard-Jones");
+ case PFIELD_BOID:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Boid");
+ case PFIELD_TURBULENCE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Turbulence");
+ case PFIELD_DRAG:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Drag");
+ case PFIELD_FLUIDFLOW:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "FluidField");
+ case PFIELD_NULL:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Field");
+ case NUM_PFIELD_TYPES:
+ break;
+ }
+
+ BLI_assert(false);
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Field");
+}
+
static int effector_add_exec(bContext *C, wmOperator *op)
{
Object *ob;
@@ -712,8 +752,8 @@ static int effector_add_exec(bContext *C, wmOperator *op)
if (type == PFIELD_GUIDE) {
Curve *cu;
- const char *name = CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "CurveGuide");
- ob = ED_object_add_type(C, OB_CURVE, name, loc, rot, false, local_view_bits);
+ ob = ED_object_add_type(
+ C, OB_CURVE, get_effector_defname(type), loc, rot, false, local_view_bits);
cu = ob->data;
cu->flag |= CU_PATH | CU_3D;
@@ -726,8 +766,8 @@ static int effector_add_exec(bContext *C, wmOperator *op)
}
}
else {
- const char *name = CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Field");
- ob = ED_object_add_type(C, OB_EMPTY, name, loc, rot, false, local_view_bits);
+ ob = ED_object_add_type(
+ C, OB_EMPTY, get_effector_defname(type), loc, rot, false, local_view_bits);
BKE_object_obdata_size_init(ob, dia);
if (ELEM(type, PFIELD_WIND, PFIELD_VORTEX)) {
ob->empty_drawtype = OB_SINGLE_ARROW;
@@ -1237,7 +1277,7 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
break;
}
- /* if this is a new object, initialise default stuff (colors, etc.) */
+ /* If this is a new object, initialize default stuff (colors, etc.) */
if (newob) {
/* set default viewport color to black */
copy_v3_fl(ob->color, 0.0f);
@@ -1395,7 +1435,7 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
/* Avoid dependency cycles. */
LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
- while (BKE_collection_find_cycle(active_lc->collection, collection)) {
+ while (BKE_collection_cycle_find(active_lc->collection, collection)) {
active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
}
@@ -1642,7 +1682,7 @@ static int object_delete_exec(bContext *C, wmOperator *op)
ob->id.name + 2);
continue;
}
- else if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) {
+ if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) {
BKE_reportf(op->reports,
RPT_WARNING,
"Cannot delete object '%s' from scene '%s', indirectly used objects need at "
@@ -1866,7 +1906,7 @@ static bool dupliobject_cmp(const void *a_, const void *b_)
if (a->persistent_id[i] != b->persistent_id[i]) {
return true;
}
- else if (a->persistent_id[i] == INT_MAX) {
+ if (a->persistent_id[i] == INT_MAX) {
break;
}
}
@@ -1891,7 +1931,7 @@ static bool dupliobject_instancer_cmp(const void *a_, const void *b_)
if (a->persistent_id[i] != b->persistent_id[i]) {
return true;
}
- else if (a->persistent_id[i] == INT_MAX) {
+ if (a->persistent_id[i] == INT_MAX) {
break;
}
}
@@ -2451,7 +2491,8 @@ static int object_convert_exec(bContext *C, wmOperator *op)
matrix,
0,
use_seams,
- use_faces);
+ use_faces,
+ false);
gpencilConverted = true;
/* Remove unused materials. */
@@ -2751,6 +2792,8 @@ static void object_convert_ui(bContext *UNUSED(C), wmOperator *op)
uiLayout *layout = op->layout;
PointerRNA ptr;
+ uiLayoutSetPropSep(layout, true);
+
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiItemR(layout, &ptr, "target", 0, NULL, ICON_NONE);
uiItemR(layout, &ptr, "keep_original", 0, NULL, ICON_NONE);
@@ -3097,9 +3140,7 @@ static bool object_join_poll(bContext *C)
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE, OB_GPENCIL)) {
return ED_operator_screenactive(C);
}
- else {
- return false;
- }
+ return false;
}
static int object_join_exec(bContext *C, wmOperator *op)
@@ -3110,11 +3151,11 @@ static int object_join_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode");
return OPERATOR_CANCELLED;
}
- else if (BKE_object_obdata_is_libdata(ob)) {
+ if (BKE_object_obdata_is_libdata(ob)) {
BKE_report(op->reports, RPT_ERROR, "Cannot edit external library data");
return OPERATOR_CANCELLED;
}
- else if (ob->type == OB_GPENCIL) {
+ if (ob->type == OB_GPENCIL) {
bGPdata *gpd = (bGPdata *)ob->data;
if ((!gpd) || GPENCIL_ANY_MODE(gpd)) {
BKE_report(op->reports, RPT_ERROR, "This data does not support joining in this mode");
@@ -3125,13 +3166,13 @@ static int object_join_exec(bContext *C, wmOperator *op)
if (ob->type == OB_MESH) {
return ED_mesh_join_objects_exec(C, op);
}
- else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
return ED_curve_join_objects_exec(C, op);
}
- else if (ob->type == OB_ARMATURE) {
+ if (ob->type == OB_ARMATURE) {
return ED_armature_join_objects_exec(C, op);
}
- else if (ob->type == OB_GPENCIL) {
+ if (ob->type == OB_GPENCIL) {
return ED_gpencil_join_objects_exec(C, op);
}
@@ -3172,9 +3213,7 @@ static bool join_shapes_poll(bContext *C)
if (ob->type == OB_MESH) {
return ED_operator_screenactive(C);
}
- else {
- return false;
- }
+ return false;
}
static int join_shapes_exec(bContext *C, wmOperator *op)
@@ -3185,7 +3224,7 @@ static int join_shapes_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode");
return OPERATOR_CANCELLED;
}
- else if (BKE_object_obdata_is_libdata(ob)) {
+ if (BKE_object_obdata_is_libdata(ob)) {
BKE_report(op->reports, RPT_ERROR, "Cannot edit external library data");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index baa24ab2f4e..ae1aae27b7f 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -60,8 +60,6 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "GPU_draw.h" /* GPU_free_image */
-
#include "WM_api.h"
#include "WM_types.h"
@@ -530,7 +528,7 @@ static void multiresbake_freejob(void *bkv)
/* delete here, since this delete will be called from main thread */
for (link = data->images.first; link; link = link->next) {
Image *ima = (Image *)link->data;
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
}
MEM_freeN(data->ob_image.array);
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index e84dbca2469..cb92fab3cb0 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -68,8 +68,6 @@
#include "ED_screen.h"
#include "ED_uvedit.h"
-#include "GPU_draw.h"
-
#include "object_intern.h"
/* prototypes */
@@ -308,7 +306,7 @@ static void refresh_images(BakeImages *bake_images)
Image *ima = bake_images->data[i].image;
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
if (tile->ok == IMA_OK_LOADED) {
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
DEG_id_tag_update(&ima->id, 0);
break;
}
@@ -434,14 +432,12 @@ static bool bake_object_check(ViewLayer *view_layer, Object *ob, ReportList *rep
BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2);
return false;
}
- else {
- Mesh *me = (Mesh *)ob->data;
- if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) {
- BKE_reportf(
- reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2);
- return false;
- }
+ Mesh *me = (Mesh *)ob->data;
+ if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) {
+ BKE_reportf(
+ reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2);
+ return false;
}
for (i = 0; i < ob->totcol; i++) {
@@ -542,14 +538,11 @@ static bool bake_pass_filter_check(eScenePassType pass_type,
return false;
}
- else {
- BKE_report(reports,
- RPT_ERROR,
- "Combined bake pass requires Emit, or a light pass with "
- "Direct or Indirect contributions enabled");
- return false;
- }
- break;
+ BKE_report(reports,
+ RPT_ERROR,
+ "Combined bake pass requires Emit, or a light pass with "
+ "Direct or Indirect contributions enabled");
+ return false;
case SCE_PASS_DIFFUSE_COLOR:
case SCE_PASS_GLOSSY_COLOR:
case SCE_PASS_TRANSM_COLOR:
@@ -680,7 +673,7 @@ static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images)
/*
* returns the total number of pixels
*/
-static size_t initialize_internal_images(BakeImages *bake_images, ReportList *reports)
+static size_t init_internal_images(BakeImages *bake_images, ReportList *reports)
{
int i;
size_t tot_size = 0;
@@ -835,7 +828,7 @@ static int bake(Render *re,
build_image_lookup(bmain, ob_low, &bake_images);
if (is_save_internal) {
- num_pixels = initialize_internal_images(&bake_images, reports);
+ num_pixels = init_internal_images(&bake_images, reports);
if (num_pixels == 0) {
goto cleanup;
@@ -1071,10 +1064,7 @@ static int bake(Render *re,
(normal_swizzle[2] == R_BAKE_POSZ)) {
break;
}
- else {
- RE_bake_normal_world_to_world(
- pixel_array_low, num_pixels, depth, result, normal_swizzle);
- }
+ RE_bake_normal_world_to_world(pixel_array_low, num_pixels, depth, result, normal_swizzle);
break;
}
case R_BAKE_SPACE_OBJECT: {
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 5746480e3f8..bcb1b8afbdd 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -670,12 +670,12 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
if (!ob) {
CTX_wm_operator_poll_msg_set(C, "Context missing active object");
- return 0;
+ return false;
}
if (ID_IS_LINKED(ob) || (ptr.owner_id && ID_IS_LINKED(ptr.owner_id))) {
CTX_wm_operator_poll_msg_set(C, "Cannot edit library data");
- return 0;
+ return false;
}
if (ID_IS_OVERRIDE_LIBRARY(ob) && ptr.data != NULL) {
@@ -683,7 +683,7 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
return (((bConstraint *)ptr.data)->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0;
}
- return 1;
+ return true;
}
static bool edit_constraint_poll(bContext *C)
@@ -702,7 +702,17 @@ static void edit_constraint_properties(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN);
}
-static int edit_constraint_invoke_properties(bContext *C, wmOperator *op)
+static void edit_constraint_report_property(wmOperatorType *ot)
+{
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "report", false, "Report", "Create a notification after the operation");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+
+static bool edit_constraint_invoke_properties(bContext *C,
+ wmOperator *op,
+ const wmEvent *event,
+ int *r_retval)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C);
@@ -711,7 +721,7 @@ static int edit_constraint_invoke_properties(bContext *C, wmOperator *op)
if (RNA_struct_property_is_set(op->ptr, "constraint") &&
RNA_struct_property_is_set(op->ptr, "owner")) {
- return 1;
+ return true;
}
if (ptr.data) {
@@ -727,10 +737,35 @@ static int edit_constraint_invoke_properties(bContext *C, wmOperator *op)
RNA_enum_set(op->ptr, "owner", EDIT_CONSTRAINT_OWNER_BONE);
}
- return 1;
+ return true;
+ }
+
+ /* Check the custom data of panels under the mouse for a modifier. */
+ if (event != NULL) {
+ PointerRNA *panel_ptr = UI_region_panel_custom_data_under_cursor(C, event);
+
+ if (!(panel_ptr == NULL || RNA_pointer_is_null(panel_ptr))) {
+ if (RNA_struct_is_a(panel_ptr->type, &RNA_Constraint)) {
+ con = panel_ptr->data;
+ RNA_string_set(op->ptr, "constraint", con->name);
+ list = ED_object_constraint_list_from_constraint(ob, con, NULL);
+ RNA_enum_set(op->ptr,
+ "owner",
+ (&ob->constraints == list) ? EDIT_CONSTRAINT_OWNER_OBJECT :
+ EDIT_CONSTRAINT_OWNER_BONE);
+
+ return true;
+ }
+
+ BLI_assert(r_retval != NULL); /* We need the return value in this case. */
+ if (r_retval != NULL) {
+ *r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
+ }
+ return false;
+ }
}
- return 0;
+ return false;
}
static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int type)
@@ -813,12 +848,10 @@ static int stretchto_reset_exec(bContext *C, wmOperator *op)
static int stretchto_reset_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_constraint_invoke_properties(C, op)) {
+ if (edit_constraint_invoke_properties(C, op, NULL, NULL)) {
return stretchto_reset_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot)
@@ -870,12 +903,10 @@ static int limitdistance_reset_exec(bContext *C, wmOperator *op)
static int limitdistance_reset_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_constraint_invoke_properties(C, op)) {
+ if (edit_constraint_invoke_properties(C, op, NULL, NULL)) {
return limitdistance_reset_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot)
@@ -950,12 +981,10 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op)
static int childof_set_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_constraint_invoke_properties(C, op)) {
+ if (edit_constraint_invoke_properties(C, op, NULL, NULL)) {
return childof_set_inverse_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot)
@@ -1001,12 +1030,10 @@ static int childof_clear_inverse_exec(bContext *C, wmOperator *op)
static int childof_clear_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_constraint_invoke_properties(C, op)) {
+ if (edit_constraint_invoke_properties(C, op, NULL, NULL)) {
return childof_clear_inverse_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot)
@@ -1128,12 +1155,10 @@ static int followpath_path_animate_invoke(bContext *C,
const wmEvent *UNUSED(event))
{
/* hook up invoke properties for figuring out which constraint we're dealing with */
- if (edit_constraint_invoke_properties(C, op)) {
+ if (edit_constraint_invoke_properties(C, op, NULL, NULL)) {
return followpath_path_animate_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void CONSTRAINT_OT_followpath_path_animate(wmOperatorType *ot)
@@ -1211,12 +1236,10 @@ static int objectsolver_set_inverse_invoke(bContext *C,
wmOperator *op,
const wmEvent *UNUSED(event))
{
- if (edit_constraint_invoke_properties(C, op)) {
+ if (edit_constraint_invoke_properties(C, op, NULL, NULL)) {
return objectsolver_set_inverse_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void CONSTRAINT_OT_objectsolver_set_inverse(wmOperatorType *ot)
@@ -1269,12 +1292,10 @@ static int objectsolver_clear_inverse_invoke(bContext *C,
wmOperator *op,
const wmEvent *UNUSED(event))
{
- if (edit_constraint_invoke_properties(C, op)) {
+ if (edit_constraint_invoke_properties(C, op, NULL, NULL)) {
return objectsolver_clear_inverse_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void CONSTRAINT_OT_objectsolver_clear_inverse(wmOperatorType *ot)
@@ -1388,26 +1409,23 @@ void ED_object_constraint_dependency_tag_update(Main *bmain, Object *ob, bConstr
DEG_relations_tag_update(bmain);
}
-static bool constraint_poll(bContext *C)
-{
- PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
- return (ptr.owner_id && ptr.data);
-}
-
/** \} */
/* ------------------------------------------------------------------- */
/** \name Delete Constraint Operator
* \{ */
-static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op))
+static int constraint_delete_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
- Object *ob = (Object *)ptr.owner_id;
- bConstraint *con = ptr.data;
+ Object *ob = ED_object_active_context(C);
+ bConstraint *con = edit_constraint_property_get(op, ob, 0);
ListBase *lb = ED_object_constraint_list_from_constraint(ob, con, NULL);
+ /* Store name temporarily for report. */
+ char name[MAX_NAME];
+ strcpy(name, con->name);
+
/* free the constraint */
if (BKE_constraint_remove_ex(lb, ob, con, true)) {
/* there's no active constraint now, so make sure this is the case */
@@ -1421,12 +1439,23 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op))
/* notifiers */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob);
+ if (RNA_boolean_get(op->ptr, "report")) {
+ BKE_reportf(op->reports, RPT_INFO, "Removed constraint: %s", name);
+ }
+
return OPERATOR_FINISHED;
}
- else {
- /* couldn't remove due to some invalid data */
- return OPERATOR_CANCELLED;
+ /* couldn't remove due to some invalid data */
+ return OPERATOR_CANCELLED;
+}
+
+static int constraint_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ int retval;
+ if (edit_constraint_invoke_properties(C, op, event, &retval)) {
+ return constraint_delete_exec(C, op);
}
+ return OPERATOR_CANCELLED;
}
void CONSTRAINT_OT_delete(wmOperatorType *ot)
@@ -1437,11 +1466,14 @@ void CONSTRAINT_OT_delete(wmOperatorType *ot)
ot->description = "Remove constraint from constraint stack";
/* callbacks */
+ ot->invoke = constraint_delete_invoke;
ot->exec = constraint_delete_exec;
- ot->poll = constraint_poll;
+ ot->poll = edit_constraint_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ edit_constraint_properties(ot);
+ edit_constraint_report_property(ot);
}
/** \} */
@@ -1471,14 +1503,13 @@ static int constraint_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int constraint_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int constraint_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_constraint_invoke_properties(C, op)) {
+ int retval;
+ if (edit_constraint_invoke_properties(C, op, event, &retval)) {
return constraint_move_down_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return retval;
}
void CONSTRAINT_OT_move_down(wmOperatorType *ot)
@@ -1527,14 +1558,13 @@ static int constraint_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int constraint_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int constraint_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_constraint_invoke_properties(C, op)) {
+ int retval;
+ if (edit_constraint_invoke_properties(C, op, event, &retval)) {
return constraint_move_up_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return retval;
}
void CONSTRAINT_OT_move_up(wmOperatorType *ot)
@@ -1585,16 +1615,13 @@ static int constraint_move_to_index_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int constraint_move_to_index_invoke(bContext *C,
- wmOperator *op,
- const wmEvent *UNUSED(event))
+static int constraint_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_constraint_invoke_properties(C, op)) {
+ int retval;
+ if (edit_constraint_invoke_properties(C, op, event, &retval)) {
return constraint_move_to_index_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return retval;
}
void CONSTRAINT_OT_move_to_index(wmOperatorType *ot)
@@ -1705,7 +1732,7 @@ void OBJECT_OT_constraints_clear(wmOperatorType *ot)
/* callbacks */
ot->exec = object_constraints_clear_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
}
/** \} */
@@ -1908,8 +1935,7 @@ static bool get_new_constraint_target(
break;
}
- else if (((!only_curve) || (ob->type == OB_CURVE)) &&
- ((!only_mesh) || (ob->type == OB_MESH))) {
+ if (((!only_curve) || (ob->type == OB_CURVE)) && ((!only_mesh) || (ob->type == OB_MESH))) {
/* set target */
*tar_ob = ob;
found = true;
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 0df33255c34..5a0656ee916 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -254,16 +254,12 @@ static const EnumPropertyItem *dt_layers_select_itemf(bContext *C,
if (reverse_transfer) {
return dt_layers_select_src_itemf(C, ptr, prop, r_free);
}
- else {
- return dt_layers_select_dst_itemf(C, ptr, prop, r_free);
- }
- }
- else if (reverse_transfer) {
return dt_layers_select_dst_itemf(C, ptr, prop, r_free);
}
- else {
- return dt_layers_select_src_itemf(C, ptr, prop, r_free);
+ if (reverse_transfer) {
+ return dt_layers_select_dst_itemf(C, ptr, prop, r_free);
}
+ return dt_layers_select_src_itemf(C, ptr, prop, r_free);
}
/* Note: rna_enum_dt_mix_mode_items enum is from rna_modifier.c */
@@ -381,7 +377,7 @@ static bool data_transfer_exec_is_object_valid(wmOperator *op,
me->id.tag &= ~LIB_TAG_DOIT;
return true;
}
- else if (!ID_IS_LINKED(me) && !ID_IS_OVERRIDE_LIBRARY(me)) {
+ if (!ID_IS_LINKED(me) && !ID_IS_OVERRIDE_LIBRARY(me)) {
/* Do not apply transfer operation more than once. */
/* XXX This is not nice regarding vgroups, which are half-Object data... :/ */
BKE_reportf(
@@ -424,8 +420,8 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
const float ray_radius = RNA_float_get(op->ptr, "ray_radius");
const float islands_precision = RNA_float_get(op->ptr, "islands_precision");
- const int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
- const int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
+ int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
+ int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
@@ -451,6 +447,10 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ if (reverse_transfer) {
+ SWAP(int, layers_src, layers_dst);
+ }
+
if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
layers_select_src[fromto_idx] = layers_src;
layers_select_dst[fromto_idx] = layers_dst;
@@ -512,13 +512,15 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
BLI_freelistN(&ctx_objects);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
+ if (changed) {
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
+ }
#if 0 /* TODO */
/* Note: issue with that is that if canceled, operator cannot be redone... Nasty in our case. */
return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
#else
- (void)changed;
return OPERATOR_FINISHED;
#endif
}
@@ -857,9 +859,7 @@ static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return datalayout_transfer_exec(C, op);
}
- else {
- return WM_menu_invoke(C, op, event);
- }
+ return WM_menu_invoke(C, op, event);
}
void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_data_transform.c b/source/blender/editors/object/object_data_transform.c
index 54fd1fe6671..8ea35c7a92c 100644
--- a/source/blender/editors/object/object_data_transform.c
+++ b/source/blender/editors/object/object_data_transform.c
@@ -33,6 +33,7 @@
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_collection_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
@@ -46,6 +47,8 @@
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_editmesh.h"
+#include "BKE_gpencil_geom.h"
+#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
@@ -280,16 +283,22 @@ struct XFormObjectData {
struct XFormObjectData_Mesh {
struct XFormObjectData base;
+ /* Optional data for shape keys. */
+ void *key_data;
float elem_array[0][3];
};
struct XFormObjectData_Lattice {
struct XFormObjectData base;
+ /* Optional data for shape keys. */
+ void *key_data;
float elem_array[0][3];
};
struct XFormObjectData_Curve {
struct XFormObjectData base;
+ /* Optional data for shape keys. */
+ void *key_data;
float elem_array[0][3];
};
@@ -303,54 +312,109 @@ struct XFormObjectData_MetaBall {
struct ElemData_MetaBall elem_array[0];
};
+struct XFormObjectData_GPencil {
+ struct XFormObjectData base;
+ struct GPencilPointCoordinates elem_array[0];
+};
+
struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode)
{
struct XFormObjectData *xod_base = NULL;
if (id == NULL) {
return xod_base;
}
+
switch (GS(id->name)) {
case ID_ME: {
Mesh *me = (Mesh *)id;
+ struct Key *key = me->key;
+ const int key_index = -1;
+
if (is_edit_mode) {
BMesh *bm = me->edit_mesh->bm;
+ /* Always operate on all keys for the moment. */
+ // key_index = bm->shapenr - 1;
const int elem_array_len = bm->totvert;
struct XFormObjectData_Mesh *xod = MEM_mallocN(
sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ memset(xod, 0x0, sizeof(*xod));
+
BM_mesh_vert_coords_get(bm, xod->elem_array);
xod_base = &xod->base;
+
+ if (key != NULL) {
+ const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
+ if (key_size) {
+ xod->key_data = MEM_mallocN(key_size, __func__);
+ BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
+ }
+ }
}
else {
const int elem_array_len = me->totvert;
struct XFormObjectData_Mesh *xod = MEM_mallocN(
sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ memset(xod, 0x0, sizeof(*xod));
+
BKE_mesh_vert_coords_get(me, xod->elem_array);
xod_base = &xod->base;
+
+ if (key != NULL) {
+ const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
+ if (key_size) {
+ xod->key_data = MEM_mallocN(key_size, __func__);
+ BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
+ }
+ }
}
break;
}
case ID_LT: {
Lattice *lt_orig = (Lattice *)id;
Lattice *lt = is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
+ struct Key *key = lt->key;
+ const int key_index = -1;
+
+ if (is_edit_mode) {
+ /* Always operate on all keys for the moment. */
+ // key_index = lt_orig->editlatt->shapenr - 1;
+ }
+
const int elem_array_len = lt->pntsu * lt->pntsv * lt->pntsw;
struct XFormObjectData_Lattice *xod = MEM_mallocN(
sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ memset(xod, 0x0, sizeof(*xod));
+
BKE_lattice_vert_coords_get(lt, xod->elem_array);
xod_base = &xod->base;
+
+ if (key != NULL) {
+ const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
+ if (key_size) {
+ xod->key_data = MEM_mallocN(key_size, __func__);
+ BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
+ }
+ }
+
break;
}
case ID_CU: {
Curve *cu = (Curve *)id;
+ struct Key *key = cu->key;
+
const short ob_type = BKE_curve_type_get(cu);
if (ob_type == OB_FONT) {
/* We could support translation. */
break;
}
+ const int key_index = -1;
ListBase *nurbs;
if (is_edit_mode) {
EditNurb *editnurb = cu->editnurb;
nurbs = &editnurb->nurbs;
+ /* Always operate on all keys for the moment. */
+ // key_index = editnurb->shapenr - 1;
}
else {
nurbs = &cu->nurb;
@@ -359,8 +423,19 @@ struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode
const int elem_array_len = BKE_nurbList_verts_count(nurbs);
struct XFormObjectData_Curve *xod = MEM_mallocN(
sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ memset(xod, 0x0, sizeof(*xod));
+
BKE_curve_nurbs_vert_coords_get(nurbs, xod->elem_array, elem_array_len);
xod_base = &xod->base;
+
+ if (key != NULL) {
+ const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
+ if (key_size) {
+ xod->key_data = MEM_mallocN(key_size, __func__);
+ BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
+ }
+ }
+
break;
}
case ID_AR: {
@@ -369,6 +444,8 @@ struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode
const int elem_array_len = BLI_listbase_count(arm->edbo);
struct XFormObjectData_Armature *xod = MEM_mallocN(
sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ memset(xod, 0x0, sizeof(*xod));
+
edit_armature_coords_and_quats_get(arm, xod->elem_array);
xod_base = &xod->base;
}
@@ -376,6 +453,8 @@ struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode
const int elem_array_len = BKE_armature_bonelist_count(&arm->bonebase);
struct XFormObjectData_Armature *xod = MEM_mallocN(
sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ memset(xod, 0x0, sizeof(*xod));
+
armature_coords_and_quats_get(arm, xod->elem_array);
xod_base = &xod->base;
}
@@ -387,10 +466,23 @@ struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode
const int elem_array_len = BLI_listbase_count(&mb->elems);
struct XFormObjectData_MetaBall *xod = MEM_mallocN(
sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ memset(xod, 0x0, sizeof(*xod));
+
metaball_coords_and_quats_get(mb, xod->elem_array);
xod_base = &xod->base;
break;
}
+ case ID_GD: {
+ bGPdata *gpd = (bGPdata *)id;
+ const int elem_array_len = BKE_gpencil_stroke_point_count(gpd);
+ struct XFormObjectData_GPencil *xod = MEM_mallocN(
+ sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ memset(xod, 0x0, sizeof(*xod));
+
+ BKE_gpencil_point_coords_get(gpd, xod->elem_array);
+ xod_base = &xod->base;
+ break;
+ }
default: {
break;
}
@@ -412,9 +504,35 @@ struct XFormObjectData *ED_object_data_xform_create_from_edit_mode(ID *id)
return ED_object_data_xform_create_ex(id, true);
}
-void ED_object_data_xform_destroy(struct XFormObjectData *xod)
+void ED_object_data_xform_destroy(struct XFormObjectData *xod_base)
{
- MEM_freeN(xod);
+ switch (GS(xod_base->id->name)) {
+ case ID_ME: {
+ struct XFormObjectData_Mesh *xod = (struct XFormObjectData_Mesh *)xod_base;
+ if (xod->key_data != NULL) {
+ MEM_freeN(xod->key_data);
+ }
+ break;
+ }
+ case ID_LT: {
+ struct XFormObjectData_Lattice *xod = (struct XFormObjectData_Lattice *)xod_base;
+ if (xod->key_data != NULL) {
+ MEM_freeN(xod->key_data);
+ }
+ break;
+ }
+ case ID_CU: {
+ struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
+ if (xod->key_data != NULL) {
+ MEM_freeN(xod->key_data);
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ MEM_freeN(xod_base);
}
void ED_object_data_xform_by_mat4(struct XFormObjectData *xod_base, const float mat[4][4])
@@ -422,34 +540,72 @@ void ED_object_data_xform_by_mat4(struct XFormObjectData *xod_base, const float
switch (GS(xod_base->id->name)) {
case ID_ME: {
Mesh *me = (Mesh *)xod_base->id;
+
+ struct Key *key = me->key;
+ const int key_index = -1;
+
struct XFormObjectData_Mesh *xod = (struct XFormObjectData_Mesh *)xod_base;
if (xod_base->is_edit_mode) {
BMesh *bm = me->edit_mesh->bm;
BM_mesh_vert_coords_apply_with_mat4(bm, xod->elem_array, mat);
+ /* Always operate on all keys for the moment. */
+ // key_index = bm->shapenr - 1;
}
else {
BKE_mesh_vert_coords_apply_with_mat4(me, xod->elem_array, mat);
}
+
+ if (key != NULL) {
+ BKE_keyblock_data_set_with_mat4(key, key_index, xod->key_data, mat);
+ }
+
break;
}
case ID_LT: {
Lattice *lt_orig = (Lattice *)xod_base->id;
Lattice *lt = xod_base->is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
+
+ struct Key *key = lt->key;
+ const int key_index = -1;
+
struct XFormObjectData_Lattice *xod = (struct XFormObjectData_Lattice *)xod_base;
BKE_lattice_vert_coords_apply_with_mat4(lt, xod->elem_array, mat);
+ if (xod_base->is_edit_mode) {
+ /* Always operate on all keys for the moment. */
+ // key_index = lt_orig->editlatt->shapenr - 1;
+ }
+
+ if ((key != NULL) && (xod->key_data != NULL)) {
+ BKE_keyblock_data_set_with_mat4(key, key_index, xod->key_data, mat);
+ }
+
break;
}
case ID_CU: {
BLI_assert(xod_base->is_edit_mode == false); /* Not used currently. */
Curve *cu = (Curve *)xod_base->id;
+
+ struct Key *key = cu->key;
+ const int key_index = -1;
+ ListBase *nurb = NULL;
+
struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
if (xod_base->is_edit_mode) {
EditNurb *editnurb = cu->editnurb;
+ nurb = &editnurb->nurbs;
BKE_curve_nurbs_vert_coords_apply_with_mat4(&editnurb->nurbs, xod->elem_array, mat, true);
+ /* Always operate on all keys for the moment. */
+ // key_index = editnurb->shapenr - 1;
}
else {
+ nurb = &cu->nurb;
BKE_curve_nurbs_vert_coords_apply_with_mat4(&cu->nurb, xod->elem_array, mat, true);
}
+
+ if ((key != NULL) && (xod->key_data != NULL)) {
+ BKE_keyblock_curve_data_set_with_mat4(key, nurb, key_index, xod->key_data, mat);
+ }
+
break;
}
case ID_AR: {
@@ -471,6 +627,12 @@ void ED_object_data_xform_by_mat4(struct XFormObjectData *xod_base, const float
metaball_coords_and_quats_apply_with_mat4(mb, xod->elem_array, mat);
break;
}
+ case ID_GD: {
+ bGPdata *gpd = (bGPdata *)xod_base->id;
+ struct XFormObjectData_GPencil *xod = (struct XFormObjectData_GPencil *)xod_base;
+ BKE_gpencil_point_coords_apply_with_mat4(gpd, xod->elem_array, mat);
+ break;
+ }
default: {
break;
}
@@ -482,33 +644,68 @@ void ED_object_data_xform_restore(struct XFormObjectData *xod_base)
switch (GS(xod_base->id->name)) {
case ID_ME: {
Mesh *me = (Mesh *)xod_base->id;
+
+ struct Key *key = me->key;
+ const int key_index = -1;
+
struct XFormObjectData_Mesh *xod = (struct XFormObjectData_Mesh *)xod_base;
if (xod_base->is_edit_mode) {
BMesh *bm = me->edit_mesh->bm;
BM_mesh_vert_coords_apply(bm, xod->elem_array);
+ /* Always operate on all keys for the moment. */
+ // key_index = bm->shapenr - 1;
}
else {
BKE_mesh_vert_coords_apply(me, xod->elem_array);
}
+
+ if ((key != NULL) && (xod->key_data != NULL)) {
+ BKE_keyblock_data_set(key, key_index, xod->key_data);
+ }
+
break;
}
case ID_LT: {
Lattice *lt_orig = (Lattice *)xod_base->id;
Lattice *lt = xod_base->is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
+
+ struct Key *key = lt->key;
+ const int key_index = -1;
+
struct XFormObjectData_Lattice *xod = (struct XFormObjectData_Lattice *)xod_base;
BKE_lattice_vert_coords_apply(lt, xod->elem_array);
+ if (xod_base->is_edit_mode) {
+ /* Always operate on all keys for the moment. */
+ // key_index = lt_orig->editlatt->shapenr - 1;
+ }
+
+ if ((key != NULL) && (xod->key_data != NULL)) {
+ BKE_keyblock_data_set(key, key_index, xod->key_data);
+ }
+
break;
}
case ID_CU: {
Curve *cu = (Curve *)xod_base->id;
+
+ struct Key *key = cu->key;
+ const int key_index = -1;
+
struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
if (xod_base->is_edit_mode) {
EditNurb *editnurb = cu->editnurb;
BKE_curve_nurbs_vert_coords_apply(&editnurb->nurbs, xod->elem_array, true);
+ /* Always operate on all keys for the moment. */
+ // key_index = editnurb->shapenr - 1;
}
else {
BKE_curve_nurbs_vert_coords_apply(&cu->nurb, xod->elem_array, true);
}
+
+ if ((key != NULL) && (xod->key_data != NULL)) {
+ BKE_keyblock_data_set(key, key_index, xod->key_data);
+ }
+
break;
}
case ID_AR: {
@@ -529,6 +726,12 @@ void ED_object_data_xform_restore(struct XFormObjectData *xod_base)
metaball_coords_and_quats_apply(mb, xod->elem_array);
break;
}
+ case ID_GD: {
+ bGPdata *gpd = (bGPdata *)xod_base->id;
+ struct XFormObjectData_GPencil *xod = (struct XFormObjectData_GPencil *)xod_base;
+ BKE_gpencil_point_coords_apply(gpd, xod->elem_array);
+ break;
+ }
default: {
break;
}
@@ -572,6 +775,12 @@ void ED_object_data_xform_tag_update(struct XFormObjectData *xod_base)
DEG_id_tag_update(&mb->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
break;
}
+ case ID_GD: {
+ /* Generic update. */
+ bGPdata *gpd = (bGPdata *)xod_base->id;
+ DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+ break;
+ }
default: {
break;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 283aaec85ef..04113f70e52 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -126,14 +126,14 @@ static ListBase selected_objects_get(bContext *C);
/** \name Internal Utilities
* \{ */
-Object *ED_object_context(bContext *C)
+Object *ED_object_context(const bContext *C)
{
return CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
}
/* find the correct active object per context
* note: context can be NULL when called from a enum with PROP_ENUM_NO_CONTEXT */
-Object *ED_object_active_context(bContext *C)
+Object *ED_object_active_context(const bContext *C)
{
Object *ob = NULL;
if (C) {
@@ -156,9 +156,7 @@ static bool object_hide_poll(bContext *C)
if (CTX_wm_space_outliner(C) != NULL) {
return ED_outliner_collections_editor_poll(C);
}
- else {
- return ED_operator_view3d_active(C);
- }
+ return ED_operator_view3d_active(C);
}
static int object_hide_view_clear_exec(bContext *C, wmOperator *op)
@@ -897,7 +895,7 @@ void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object)
else {
if (!pd || (pd->shape != PFIELD_SHAPE_SURFACE) ||
ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
- ED_object_modifier_remove(NULL, bmain, object, md);
+ ED_object_modifier_remove(NULL, bmain, scene, object, md);
}
}
}
@@ -1634,15 +1632,14 @@ static bool move_to_collection_poll(bContext *C)
if (CTX_wm_space_outliner(C) != NULL) {
return ED_outliner_collections_editor_poll(C);
}
- else {
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d && v3d->localvd) {
- return false;
- }
+ View3D *v3d = CTX_wm_view3d(C);
- return ED_operator_objectmode(C);
+ if (v3d && v3d->localvd) {
+ return false;
}
+
+ return ED_operator_objectmode(C);
}
static int move_to_collection_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c
index cfdb6fea52d..019ab2c345b 100644
--- a/source/blender/editors/object/object_gpencil_modifier.c
+++ b/source/blender/editors/object/object_gpencil_modifier.c
@@ -245,7 +245,7 @@ static int gpencil_modifier_apply_obdata(
if (ELEM(NULL, ob, ob->data)) {
return 0;
}
- else if (mti->bakeModifier == NULL) {
+ if (mti->bakeModifier == NULL) {
BKE_report(reports, RPT_ERROR, "Not implemented");
return 0;
}
@@ -487,13 +487,12 @@ static bool gpencil_edit_modifier_invoke_properties(bContext *C,
RNA_string_set(op->ptr, "modifier", md->name);
return true;
}
- else {
- BLI_assert(r_retval != NULL); /* We need the return value in this case. */
- if (r_retval != NULL) {
- *r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
- }
- return false;
+
+ BLI_assert(r_retval != NULL); /* We need the return value in this case. */
+ if (r_retval != NULL) {
+ *r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
}
+ return false;
}
}
@@ -555,9 +554,7 @@ static int gpencil_modifier_remove_invoke(bContext *C, wmOperator *op, const wmE
if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_remove_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_gpencil_modifier_remove(wmOperatorType *ot)
@@ -599,9 +596,7 @@ static int gpencil_modifier_move_up_invoke(bContext *C, wmOperator *op, const wm
if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_move_up_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_gpencil_modifier_move_up(wmOperatorType *ot)
@@ -642,9 +637,7 @@ static int gpencil_modifier_move_down_invoke(bContext *C, wmOperator *op, const
if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_move_down_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_gpencil_modifier_move_down(wmOperatorType *ot)
@@ -691,9 +684,7 @@ static int gpencil_modifier_move_to_index_invoke(bContext *C, wmOperator *op, co
if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_move_to_index_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_gpencil_modifier_move_to_index(wmOperatorType *ot)
@@ -753,9 +744,7 @@ static int gpencil_modifier_apply_invoke(bContext *C, wmOperator *op, const wmEv
if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_apply_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
static const EnumPropertyItem gpencil_modifier_apply_as_items[] = {
@@ -814,9 +803,7 @@ static int gpencil_modifier_copy_invoke(bContext *C, wmOperator *op, const wmEve
if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_copy_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_gpencil_modifier_copy(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index 9d2e5e74352..6bb03e62191 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -649,9 +649,7 @@ static int object_add_hook_selob_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_hook_add_selob(wmOperatorType *ot)
@@ -690,9 +688,7 @@ static int object_add_hook_newob_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obedit);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_hook_add_newob(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index afc87c0caba..bc3c263e0a3 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -21,8 +21,7 @@
* \ingroup edobj
*/
-#ifndef __OBJECT_INTERN_H__
-#define __OBJECT_INTERN_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -167,6 +166,7 @@ void OBJECT_OT_modifier_move_up(struct wmOperatorType *ot);
void OBJECT_OT_modifier_move_down(struct wmOperatorType *ot);
void OBJECT_OT_modifier_move_to_index(struct wmOperatorType *ot);
void OBJECT_OT_modifier_apply(struct wmOperatorType *ot);
+void OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType *ot);
void OBJECT_OT_modifier_convert(struct wmOperatorType *ot);
void OBJECT_OT_modifier_copy(struct wmOperatorType *ot);
void OBJECT_OT_multires_subdivide(struct wmOperatorType *ot);
@@ -310,5 +310,3 @@ void OBJECT_OT_datalayout_transfer(struct wmOperatorType *ot);
#ifdef __cplusplus
}
#endif
-
-#endif /* __OBJECT_INTERN_H__ */
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 6b0eff5b6e5..8d6d2e3e31d 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -330,10 +330,8 @@ static bool object_modifier_safe_to_delete(Main *bmain,
!ED_object_iter_other(bmain, ob, false, object_has_modifier_cb, &type));
}
-static bool object_modifier_remove(Main *bmain,
- Object *ob,
- ModifierData *md,
- bool *r_sort_depsgraph)
+static bool object_modifier_remove(
+ Main *bmain, Scene *scene, Object *ob, ModifierData *md, bool *r_sort_depsgraph)
{
/* It seems on rapid delete it is possible to
* get called twice on same modifier, so make
@@ -344,13 +342,11 @@ static bool object_modifier_remove(Main *bmain,
/* special cases */
if (md->type == eModifierType_ParticleSystem) {
- ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
-
- BLI_remlink(&ob->particlesystem, psmd->psys);
- psys_free(ob, psmd->psys);
- psmd->psys = NULL;
+ object_remove_particle_system(bmain, scene, ob);
+ return true;
}
- else if (md->type == eModifierType_Softbody) {
+
+ if (md->type == eModifierType_Softbody) {
if (ob->soft) {
sbFree(ob);
ob->softflag = 0; /* TODO(Sybren): this should probably be moved into sbFree() */
@@ -391,12 +387,13 @@ static bool object_modifier_remove(Main *bmain,
return 1;
}
-bool ED_object_modifier_remove(ReportList *reports, Main *bmain, Object *ob, ModifierData *md)
+bool ED_object_modifier_remove(
+ ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
{
bool sort_depsgraph = false;
bool ok;
- ok = object_modifier_remove(bmain, ob, md, &sort_depsgraph);
+ ok = object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
if (!ok) {
BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", md->name, ob->id.name);
@@ -409,7 +406,7 @@ bool ED_object_modifier_remove(ReportList *reports, Main *bmain, Object *ob, Mod
return 1;
}
-void ED_object_modifier_clear(Main *bmain, Object *ob)
+void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob)
{
ModifierData *md = ob->modifiers.first;
bool sort_depsgraph = false;
@@ -423,7 +420,7 @@ void ED_object_modifier_clear(Main *bmain, Object *ob)
next_md = md->next;
- object_modifier_remove(bmain, ob, md, &sort_depsgraph);
+ object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
md = next_md;
}
@@ -822,7 +819,8 @@ bool ED_object_modifier_apply(Main *bmain,
Scene *scene,
Object *ob,
ModifierData *md,
- int mode)
+ int mode,
+ bool keep_modifier)
{
int prev_mode;
@@ -830,12 +828,12 @@ bool ED_object_modifier_apply(Main *bmain,
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode");
return false;
}
- else if (ID_REAL_USERS(ob->data) > 1) {
+ if (mode != MODIFIER_APPLY_SHAPE && ID_REAL_USERS(ob->data) > 1) {
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
return false;
}
- else if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
- (BKE_modifier_is_same_topology(md) == false)) {
+ if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
+ (BKE_modifier_is_same_topology(md) == false)) {
BKE_report(reports,
RPT_ERROR,
"Constructive modifier cannot be applied to multi-res data in sculpt mode");
@@ -869,18 +867,29 @@ bool ED_object_modifier_apply(Main *bmain,
}
md_eval->mode = prev_mode;
- BLI_remlink(&ob->modifiers, md);
- BKE_modifier_free(md);
+
+ if (!keep_modifier) {
+ BLI_remlink(&ob->modifiers, md);
+ BKE_modifier_free(md);
+ }
BKE_object_free_derived_caches(ob);
return true;
}
-int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
+int ED_object_modifier_copy(
+ ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
{
ModifierData *nmd;
+ if (md->type == eModifierType_ParticleSystem) {
+ nmd = object_copy_particle_system(bmain, scene, ob, ((ParticleSystemModifierData *)md)->psys);
+ BLI_remlink(&ob->modifiers, nmd);
+ BLI_insertlinkafter(&ob->modifiers, md, nmd);
+ return true;
+ }
+
nmd = BKE_modifier_new(md->type);
BKE_modifier_copydata(md, nmd);
BLI_insertlinkafter(&ob->modifiers, md, nmd);
@@ -1078,13 +1087,11 @@ bool edit_modifier_invoke_properties(bContext *C,
RNA_string_set(op->ptr, "modifier", md->name);
return true;
}
- else {
- BLI_assert(r_retval != NULL); /* We need the return value in this case. */
- if (r_retval != NULL) {
- *r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
- }
- return false;
+ BLI_assert(r_retval != NULL); /* We need the return value in this case. */
+ if (r_retval != NULL) {
+ *r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
}
+ return false;
}
}
@@ -1118,6 +1125,7 @@ ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
static int modifier_remove_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
@@ -1131,7 +1139,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
char name[MAX_NAME];
strcpy(name, md->name);
- if (!ED_object_modifier_remove(op->reports, bmain, ob, md)) {
+ if (!ED_object_modifier_remove(op->reports, bmain, scene, ob, md)) {
return OPERATOR_CANCELLED;
}
@@ -1159,9 +1167,7 @@ static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *ev
if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_remove_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_modifier_remove(wmOperatorType *ot)
@@ -1207,9 +1213,7 @@ static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *e
if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_move_up_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
@@ -1254,9 +1258,7 @@ static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent
if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_move_down_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
@@ -1307,9 +1309,7 @@ static int modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEv
if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_move_to_index_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_modifier_move_to_index(wmOperatorType *ot)
@@ -1336,7 +1336,7 @@ void OBJECT_OT_modifier_move_to_index(wmOperatorType *ot)
/** \name Apply Modifier Operator
* \{ */
-static bool modifier_apply_poll(bContext *C)
+static bool modifier_apply_poll_ex(bContext *C, bool allow_shared)
{
if (!edit_modifier_poll_generic(C, &RNA_Modifier, 0, false)) {
return false;
@@ -1347,15 +1347,15 @@ static bool modifier_apply_poll(bContext *C)
Object *ob = (ptr.owner_id != NULL) ? (Object *)ptr.owner_id : ED_object_active_context(C);
ModifierData *md = ptr.data; /* May be NULL. */
- if (ID_IS_OVERRIDE_LIBRARY(ob) || ID_IS_OVERRIDE_LIBRARY(ob->data)) {
+ if (ID_IS_OVERRIDE_LIBRARY(ob) || ((ob->data != NULL) && ID_IS_OVERRIDE_LIBRARY(ob->data))) {
CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied on override data");
return false;
}
- if ((ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) {
+ if (!allow_shared && (ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) {
CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied to multi-user data");
return false;
}
- else if (md != NULL) {
+ if (md != NULL) {
if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
(BKE_modifier_is_same_topology(md) == false)) {
CTX_wm_operator_poll_msg_set(
@@ -1366,14 +1366,18 @@ static bool modifier_apply_poll(bContext *C)
return true;
}
-static int modifier_apply_exec(bContext *C, wmOperator *op)
+static bool modifier_apply_poll(bContext *C)
+{
+ return modifier_apply_poll_ex(C, false);
+}
+
+static int modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, bool keep_modifier)
{
Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- int apply_as = RNA_enum_get(op->ptr, "apply_as");
if (md == NULL) {
return OPERATOR_CANCELLED;
@@ -1383,7 +1387,8 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
char name[MAX_NAME];
strcpy(name, md->name);
- if (!ED_object_modifier_apply(bmain, op->reports, depsgraph, scene, ob, md, apply_as)) {
+ if (!ED_object_modifier_apply(
+ bmain, op->reports, depsgraph, scene, ob, md, apply_as, keep_modifier)) {
return OPERATOR_CANCELLED;
}
@@ -1398,27 +1403,20 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int modifier_apply_exec(bContext *C, wmOperator *op)
+{
+ return modifier_apply_exec_ex(C, op, MODIFIER_APPLY_DATA, false);
+}
+
static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval;
if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_apply_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
-static const EnumPropertyItem modifier_apply_as_items[] = {
- {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
- {MODIFIER_APPLY_SHAPE,
- "SHAPE",
- 0,
- "New Shape",
- "Apply deform-only modifier to a new shape on this object"},
- {0, NULL, 0, NULL, NULL},
-};
-
void OBJECT_OT_modifier_apply(wmOperatorType *ot)
{
ot->name = "Apply Modifier";
@@ -1432,12 +1430,66 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
/* 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);
+ edit_modifier_report_property(ot);
+}
+
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Apply Modifier As Shapekey Operator
+ * \{ */
+
+static bool modifier_apply_as_shapekey_poll(bContext *C)
+{
+ return modifier_apply_poll_ex(C, true);
+}
+
+static int modifier_apply_as_shapekey_exec(bContext *C, wmOperator *op)
+{
+ bool keep = RNA_boolean_get(op->ptr, "keep_modifier");
+
+ return modifier_apply_exec_ex(C, op, MODIFIER_APPLY_SHAPE, keep);
+}
+
+static int modifier_apply_as_shapekey_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ int retval;
+ if (edit_modifier_invoke_properties(C, op, event, &retval)) {
+ return modifier_apply_as_shapekey_exec(C, op);
+ }
+ return retval;
+}
+
+static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED(C),
+ struct wmOperatorType *UNUSED(op),
+ struct PointerRNA *values)
+{
+ bool keep = RNA_boolean_get(values, "keep_modifier");
+
+ if (keep) {
+ return BLI_strdup("Apply modifier as a new shapekey and keep it in the stack");
+ }
+
+ return NULL;
+}
+
+void OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType *ot)
+{
+ ot->name = "Apply Modifier As Shapekey";
+ ot->description = "Apply modifier as a new shapekey and remove from the stack";
+ ot->idname = "OBJECT_OT_modifier_apply_as_shapekey";
+
+ ot->invoke = modifier_apply_as_shapekey_invoke;
+ ot->exec = modifier_apply_as_shapekey_exec;
+ ot->poll = modifier_apply_as_shapekey_poll;
+ ot->get_description = modifier_apply_as_shapekey_get_description;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ RNA_def_boolean(
+ ot->srna, "keep_modifier", false, "Keep Modifier", "Do not remove the modifier from stack");
edit_modifier_properties(ot);
edit_modifier_report_property(ot);
}
@@ -1473,9 +1525,7 @@ static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *U
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return modifier_convert_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_modifier_convert(wmOperatorType *ot)
@@ -1501,10 +1551,12 @@ void OBJECT_OT_modifier_convert(wmOperatorType *ot)
static int modifier_copy_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- if (!md || !ED_object_modifier_copy(op->reports, ob, md)) {
+ if (!md || !ED_object_modifier_copy(op->reports, bmain, scene, ob, md)) {
return OPERATOR_CANCELLED;
}
@@ -1520,9 +1572,7 @@ static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *even
if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_copy_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
void OBJECT_OT_modifier_copy(wmOperatorType *ot)
@@ -1579,9 +1629,7 @@ static int multires_higher_levels_delete_invoke(bContext *C,
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_higher_levels_delete_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
@@ -1657,9 +1705,7 @@ static int multires_subdivide_invoke(bContext *C, wmOperator *op, const wmEvent
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_subdivide_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_multires_subdivide(wmOperatorType *ot)
@@ -1734,9 +1780,7 @@ static int multires_reshape_invoke(bContext *C, wmOperator *op, const wmEvent *U
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_reshape_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_multires_reshape(wmOperatorType *ot)
@@ -1915,9 +1959,7 @@ static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_base_apply_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
@@ -1969,9 +2011,7 @@ static int multires_unsubdivide_invoke(bContext *C, wmOperator *op, const wmEven
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_unsubdivide_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_multires_unsubdivide(wmOperatorType *ot)
@@ -2027,9 +2067,7 @@ static int multires_rebuild_subdiv_invoke(bContext *C,
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_rebuild_subdiv_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_multires_rebuild_subdiv(wmOperatorType *ot)
@@ -2322,7 +2360,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph,
BKE_object_transform_copy(arm_ob, skin_ob);
arm = arm_ob->data;
arm->layer = 1;
- arm_ob->dtx |= OB_DRAWXRAY;
+ arm_ob->dtx |= OB_DRAW_IN_FRONT;
arm->drawtype = ARM_LINE;
arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature");
@@ -2406,9 +2444,7 @@ static int skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEven
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return skin_armature_create_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_skin_armature_create(wmOperatorType *ot)
@@ -2485,9 +2521,7 @@ static int correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEve
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return correctivesmooth_bind_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_correctivesmooth_bind(wmOperatorType *ot)
@@ -2562,9 +2596,7 @@ static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UN
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return meshdeform_bind_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_meshdeform_bind(wmOperatorType *ot)
@@ -2618,9 +2650,7 @@ static int explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent *UN
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return explode_refresh_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_explode_refresh(wmOperatorType *ot)
@@ -2764,12 +2794,16 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
cfra = scene->r.cfra;
/* precalculate time variable before baking */
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
for (f = omd->bakestart; f <= omd->bakeend; f++) {
/* For now only simple animation of time value is supported, nothing else.
* No drivers or other modifier parameters. */
/* TODO(sergey): This operates on an original data, so no flush is needed. However, baking
* usually should happen on an evaluated objects, so this seems to be deeper issue here. */
- BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, f, ADT_RECALC_ANIM, false);
+
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ f);
+ BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, false);
och->time[i] = omd->time;
i++;
@@ -2777,7 +2811,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
/* make a copy of ocean to use for baking - threadsafety */
ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(ocean, omd);
+ BKE_ocean_init_from_modifier(ocean, omd, omd->resolution);
#if 0
BKE_ocean_bake(ocean, och);
@@ -2822,9 +2856,7 @@ static int ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return ocean_bake_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_ocean_bake(wmOperatorType *ot)
@@ -2901,9 +2933,7 @@ static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEven
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return laplaciandeform_bind_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_laplaciandeform_bind(wmOperatorType *ot)
@@ -2970,9 +3000,7 @@ static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent
if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return surfacedeform_bind_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index e28bbb3fb1c..92880e5a114 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -130,6 +130,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_modifier_move_down);
WM_operatortype_append(OBJECT_OT_modifier_move_to_index);
WM_operatortype_append(OBJECT_OT_modifier_apply);
+ WM_operatortype_append(OBJECT_OT_modifier_apply_as_shapekey);
WM_operatortype_append(OBJECT_OT_modifier_convert);
WM_operatortype_append(OBJECT_OT_modifier_copy);
WM_operatortype_append(OBJECT_OT_multires_subdivide);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index a421fd6315c..f4de8f712c8 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -359,7 +359,7 @@ static int make_proxy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
WM_enum_search_invoke(C, op, event);
return OPERATOR_CANCELLED;
}
- else if (ID_IS_LINKED(ob)) {
+ if (ID_IS_LINKED(ob)) {
uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("OK?"), ICON_QUESTION);
uiLayout *layout = UI_popup_menu_layout(pup);
@@ -374,12 +374,10 @@ static int make_proxy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* this invoke just calls another instance of this operator... */
return OPERATOR_INTERFACE;
}
- else {
- /* error.. cannot continue */
- BKE_report(
- op->reports, RPT_ERROR, "Can only make proxy for a referenced object or collection");
- return OPERATOR_CANCELLED;
- }
+
+ /* error.. cannot continue */
+ BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or collection");
+ return OPERATOR_CANCELLED;
}
static int make_proxy_exec(bContext *C, wmOperator *op)
@@ -708,36 +706,34 @@ bool ED_object_parent_set(ReportList *reports,
if (par->type != OB_CURVE) {
return 0;
}
+ Curve *cu = par->data;
+ Curve *cu_eval = parent_eval->data;
+ if ((cu->flag & CU_PATH) == 0) {
+ cu->flag |= CU_PATH | CU_FOLLOW;
+ cu_eval->flag |= CU_PATH | CU_FOLLOW;
+ /* force creation of path data */
+ BKE_displist_make_curveTypes(depsgraph, scene, par, false, false);
+ }
else {
- Curve *cu = par->data;
- Curve *cu_eval = parent_eval->data;
- if ((cu->flag & CU_PATH) == 0) {
- cu->flag |= CU_PATH | CU_FOLLOW;
- cu_eval->flag |= CU_PATH | CU_FOLLOW;
- /* force creation of path data */
- BKE_displist_make_curveTypes(depsgraph, scene, par, false, false);
- }
- else {
- cu->flag |= CU_FOLLOW;
- cu_eval->flag |= CU_FOLLOW;
- }
+ cu->flag |= CU_FOLLOW;
+ cu_eval->flag |= CU_FOLLOW;
+ }
- /* 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 = ED_id_action_ensure(bmain, &cu->id);
- FCurve *fcu = ED_action_fcurve_ensure(bmain, act, NULL, NULL, "eval_time", 0);
+ /* 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 = ED_id_action_ensure(bmain, &cu->id);
+ FCurve *fcu = ED_action_fcurve_ensure(bmain, act, NULL, NULL, "eval_time", 0);
- /* setup dummy 'generator' modifier here to get 1-1 correspondence still working */
- if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) {
- add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu);
- }
+ /* setup dummy 'generator' modifier here to get 1-1 correspondence still working */
+ if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) {
+ add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu);
}
+ }
- /* fall back on regular parenting now (for follow only) */
- if (partype == PAR_FOLLOW) {
- partype = PAR_OBJECT;
- }
+ /* fall back on regular parenting now (for follow only) */
+ if (partype == PAR_FOLLOW) {
+ partype = PAR_OBJECT;
}
}
else if (ELEM(partype, PAR_BONE, PAR_BONE_RELATIVE)) {
@@ -755,188 +751,185 @@ bool ED_object_parent_set(ReportList *reports,
BKE_report(reports, RPT_ERROR, "Loop in parents");
return false;
}
- else {
- Object workob;
- /* apply transformation of previous parenting */
- if (keep_transform) {
- /* was removed because of bug [#23577],
- * but this can be handy in some cases too [#32616], so make optional */
- BKE_object_apply_mat4(ob, ob->obmat, false, false);
- }
+ Object workob;
- /* set the parent (except for follow-path constraint option) */
- if (partype != PAR_PATH_CONST) {
- ob->parent = par;
- /* Always clear parentinv matrix for sake of consistency, see T41950. */
- unit_m4(ob->parentinv);
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
- }
+ /* apply transformation of previous parenting */
+ if (keep_transform) {
+ /* was removed because of bug [#23577],
+ * but this can be handy in some cases too [#32616], so make optional */
+ BKE_object_apply_mat4(ob, ob->obmat, false, false);
+ }
- /* handle types */
- if (pchan) {
- BLI_strncpy(ob->parsubstr, pchan->name, sizeof(ob->parsubstr));
- }
- else {
- ob->parsubstr[0] = 0;
- }
+ /* set the parent (except for follow-path constraint option) */
+ if (partype != PAR_PATH_CONST) {
+ ob->parent = par;
+ /* Always clear parentinv matrix for sake of consistency, see T41950. */
+ unit_m4(ob->parentinv);
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+ }
- if (partype == PAR_PATH_CONST) {
- /* don't do anything here, since this is not technically "parenting" */
- }
- else if (ELEM(partype, PAR_CURVE, PAR_LATTICE) || (pararm)) {
- /* partype is now set to PAROBJECT so that invisible 'virtual'
- * modifiers don't need to be created.
- * NOTE: the old (2.4x) method was to set ob->partype = PARSKEL,
- * creating the virtual modifiers.
- */
- ob->partype = PAROBJECT; /* note, dna define, not operator property */
- /* ob->partype = PARSKEL; */ /* note, dna define, not operator property */
+ /* handle types */
+ if (pchan) {
+ BLI_strncpy(ob->parsubstr, pchan->name, sizeof(ob->parsubstr));
+ }
+ else {
+ ob->parsubstr[0] = 0;
+ }
- /* BUT, to keep the deforms, we need a modifier,
- * and then we need to set the object that it uses
- * - We need to ensure that the modifier we're adding doesn't already exist,
- * so we check this by assuming that the parent is selected too.
- */
- /* XXX currently this should only happen for meshes, curves, surfaces,
- * and lattices - this stuff isn't available for metas yet */
- if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
- ModifierData *md;
-
- switch (partype) {
- case PAR_CURVE: /* curve deform */
- if (BKE_modifiers_is_deformed_by_curve(ob) != par) {
- md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve);
- if (md) {
- ((CurveModifierData *)md)->object = par;
- }
- if (par->runtime.curve_cache && par->runtime.curve_cache->path == NULL) {
- DEG_id_tag_update(&par->id, ID_RECALC_GEOMETRY);
- }
+ if (partype == PAR_PATH_CONST) {
+ /* don't do anything here, since this is not technically "parenting" */
+ }
+ else if (ELEM(partype, PAR_CURVE, PAR_LATTICE) || (pararm)) {
+ /* partype is now set to PAROBJECT so that invisible 'virtual'
+ * modifiers don't need to be created.
+ * NOTE: the old (2.4x) method was to set ob->partype = PARSKEL,
+ * creating the virtual modifiers.
+ */
+ ob->partype = PAROBJECT; /* note, dna define, not operator property */
+ /* ob->partype = PARSKEL; */ /* note, dna define, not operator property */
+
+ /* BUT, to keep the deforms, we need a modifier,
+ * and then we need to set the object that it uses
+ * - We need to ensure that the modifier we're adding doesn't already exist,
+ * so we check this by assuming that the parent is selected too.
+ */
+ /* XXX currently this should only happen for meshes, curves, surfaces,
+ * and lattices - this stuff isn't available for metas yet */
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
+ ModifierData *md;
+
+ switch (partype) {
+ case PAR_CURVE: /* curve deform */
+ if (BKE_modifiers_is_deformed_by_curve(ob) != par) {
+ md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve);
+ if (md) {
+ ((CurveModifierData *)md)->object = par;
}
- break;
- case PAR_LATTICE: /* lattice deform */
- if (BKE_modifiers_is_deformed_by_lattice(ob) != par) {
- md = ED_object_modifier_add(
- reports, bmain, scene, ob, NULL, eModifierType_Lattice);
- if (md) {
- ((LatticeModifierData *)md)->object = par;
- }
+ if (par->runtime.curve_cache && par->runtime.curve_cache->path == NULL) {
+ DEG_id_tag_update(&par->id, ID_RECALC_GEOMETRY);
}
- break;
- default: /* armature deform */
- if (BKE_modifiers_is_deformed_by_armature(ob) != par) {
- md = ED_object_modifier_add(
- reports, bmain, scene, ob, NULL, eModifierType_Armature);
- if (md) {
- ((ArmatureModifierData *)md)->object = par;
- }
+ }
+ break;
+ case PAR_LATTICE: /* lattice deform */
+ if (BKE_modifiers_is_deformed_by_lattice(ob) != par) {
+ md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice);
+ if (md) {
+ ((LatticeModifierData *)md)->object = par;
}
- break;
- }
- }
- }
- else if (partype == PAR_BONE) {
- ob->partype = PARBONE; /* note, dna define, not operator property */
- if (pchan->bone) {
- pchan->bone->flag &= ~BONE_RELATIVE_PARENTING;
- pchan_eval->bone->flag &= ~BONE_RELATIVE_PARENTING;
- }
- }
- else if (partype == PAR_BONE_RELATIVE) {
- ob->partype = PARBONE; /* note, dna define, not operator property */
- if (pchan->bone) {
- pchan->bone->flag |= BONE_RELATIVE_PARENTING;
- pchan_eval->bone->flag |= BONE_RELATIVE_PARENTING;
+ }
+ break;
+ default: /* armature deform */
+ if (BKE_modifiers_is_deformed_by_armature(ob) != par) {
+ md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature);
+ if (md) {
+ ((ArmatureModifierData *)md)->object = par;
+ }
+ }
+ break;
}
}
- else if (partype == PAR_VERTEX) {
- ob->partype = PARVERT1;
- ob->par1 = vert_par[0];
- }
- else if (partype == PAR_VERTEX_TRI) {
- ob->partype = PARVERT3;
- copy_v3_v3_int(&ob->par1, vert_par);
+ }
+ else if (partype == PAR_BONE) {
+ ob->partype = PARBONE; /* note, dna define, not operator property */
+ if (pchan->bone) {
+ pchan->bone->flag &= ~BONE_RELATIVE_PARENTING;
+ pchan_eval->bone->flag &= ~BONE_RELATIVE_PARENTING;
}
- else {
- ob->partype = PAROBJECT; /* note, dna define, not operator property */
+ }
+ else if (partype == PAR_BONE_RELATIVE) {
+ ob->partype = PARBONE; /* note, dna define, not operator property */
+ if (pchan->bone) {
+ pchan->bone->flag |= BONE_RELATIVE_PARENTING;
+ pchan_eval->bone->flag |= BONE_RELATIVE_PARENTING;
}
+ }
+ else if (partype == PAR_VERTEX) {
+ ob->partype = PARVERT1;
+ ob->par1 = vert_par[0];
+ }
+ else if (partype == PAR_VERTEX_TRI) {
+ ob->partype = PARVERT3;
+ copy_v3_v3_int(&ob->par1, vert_par);
+ }
+ else {
+ ob->partype = PAROBJECT; /* note, dna define, not operator property */
+ }
- /* constraint */
- if (partype == PAR_PATH_CONST) {
- bConstraint *con;
- bFollowPathConstraint *data;
- float cmat[4][4], vec[3];
+ /* constraint */
+ if (partype == PAR_PATH_CONST) {
+ bConstraint *con;
+ bFollowPathConstraint *data;
+ float cmat[4][4], vec[3];
- con = BKE_constraint_add_for_object(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH);
+ con = BKE_constraint_add_for_object(ob, "AutoPath", CONSTRAINT_TYPE_FOLLOWPATH);
- data = con->data;
- data->tar = par;
+ data = con->data;
+ data->tar = par;
- BKE_constraint_target_matrix_get(
- depsgraph, scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra);
- sub_v3_v3v3(vec, ob->obmat[3], cmat[3]);
+ BKE_constraint_target_matrix_get(
+ depsgraph, scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra);
+ sub_v3_v3v3(vec, ob->obmat[3], cmat[3]);
- copy_v3_v3(ob->loc, vec);
+ copy_v3_v3(ob->loc, vec);
+ }
+ else if (pararm && (ob->type == OB_MESH) && (par->type == OB_ARMATURE)) {
+ if (partype == PAR_ARMATURE_NAME) {
+ ED_object_vgroup_calc_from_armature(
+ reports, depsgraph, scene, ob, par, ARM_GROUPS_NAME, false);
}
- else if (pararm && (ob->type == OB_MESH) && (par->type == OB_ARMATURE)) {
- if (partype == PAR_ARMATURE_NAME) {
- ED_object_vgroup_calc_from_armature(
- reports, depsgraph, scene, ob, par, ARM_GROUPS_NAME, false);
- }
- else if (partype == PAR_ARMATURE_ENVELOPE) {
- ED_object_vgroup_calc_from_armature(
- reports, depsgraph, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror);
- }
- else if (partype == PAR_ARMATURE_AUTO) {
- WM_cursor_wait(1);
- ED_object_vgroup_calc_from_armature(
- reports, depsgraph, scene, ob, par, ARM_GROUPS_AUTO, xmirror);
- WM_cursor_wait(0);
- }
- /* get corrected inverse */
- ob->partype = PAROBJECT;
- BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
-
- invert_m4_m4(ob->parentinv, workob.obmat);
+ else if (partype == PAR_ARMATURE_ENVELOPE) {
+ ED_object_vgroup_calc_from_armature(
+ reports, depsgraph, scene, ob, par, ARM_GROUPS_ENVELOPE, xmirror);
}
- else if (pararm && (ob->type == OB_GPENCIL) && (par->type == OB_ARMATURE)) {
- if (partype == PAR_ARMATURE) {
- ED_gpencil_add_armature(C, reports, ob, par);
- }
- else if (partype == PAR_ARMATURE_NAME) {
- ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_NAME);
- }
- else if ((partype == PAR_ARMATURE_AUTO) || (partype == PAR_ARMATURE_ENVELOPE)) {
- WM_cursor_wait(1);
- ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_AUTO);
- WM_cursor_wait(0);
- }
- /* get corrected inverse */
- ob->partype = PAROBJECT;
- BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
-
- invert_m4_m4(ob->parentinv, workob.obmat);
+ else if (partype == PAR_ARMATURE_AUTO) {
+ WM_cursor_wait(1);
+ ED_object_vgroup_calc_from_armature(
+ reports, depsgraph, scene, ob, par, ARM_GROUPS_AUTO, xmirror);
+ WM_cursor_wait(0);
}
- else if ((ob->type == OB_GPENCIL) && (par->type == OB_LATTICE)) {
- /* Add Lattice modifier */
- if (partype == PAR_LATTICE) {
- ED_gpencil_add_lattice_modifier(C, reports, ob, par);
- }
- /* get corrected inverse */
- ob->partype = PAROBJECT;
- BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
+ /* get corrected inverse */
+ ob->partype = PAROBJECT;
+ BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ invert_m4_m4(ob->parentinv, workob.obmat);
+ }
+ else if (pararm && (ob->type == OB_GPENCIL) && (par->type == OB_ARMATURE)) {
+ if (partype == PAR_ARMATURE) {
+ ED_gpencil_add_armature(C, reports, ob, par);
}
- else {
- /* calculate inverse parent matrix */
- BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- invert_m4_m4(ob->parentinv, workob.obmat);
+ else if (partype == PAR_ARMATURE_NAME) {
+ ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_NAME);
+ }
+ else if ((partype == PAR_ARMATURE_AUTO) || (partype == PAR_ARMATURE_ENVELOPE)) {
+ WM_cursor_wait(1);
+ ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_AUTO);
+ WM_cursor_wait(0);
+ }
+ /* get corrected inverse */
+ ob->partype = PAROBJECT;
+ BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
+
+ invert_m4_m4(ob->parentinv, workob.obmat);
+ }
+ else if ((ob->type == OB_GPENCIL) && (par->type == OB_LATTICE)) {
+ /* Add Lattice modifier */
+ if (partype == PAR_LATTICE) {
+ ED_gpencil_add_lattice_modifier(C, reports, ob, par);
}
+ /* get corrected inverse */
+ ob->partype = PAROBJECT;
+ BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ invert_m4_m4(ob->parentinv, workob.obmat);
}
+ else {
+ /* calculate inverse parent matrix */
+ BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
+ invert_m4_m4(ob->parentinv, workob.obmat);
+ }
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
}
return true;
@@ -1124,9 +1117,7 @@ static bool parent_set_poll_property(const bContext *UNUSED(C),
if (ELEM(type, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO)) {
return true;
}
- else {
- return false;
- }
+ return false;
}
return true;
@@ -1887,7 +1878,7 @@ static void single_obdata_users(
/* Needed to remap texcomesh below. */
me = ob->data = ID_NEW_SET(ob->data, BKE_mesh_copy(bmain, ob->data));
if (me->key) { /* We do not need to set me->key->id.newid here... */
- BKE_animdata_copy_id_action(bmain, (ID *)me->key, false);
+ BKE_animdata_copy_id_action(bmain, (ID *)me->key);
}
break;
case OB_MBALL:
@@ -1900,13 +1891,13 @@ static void single_obdata_users(
ID_NEW_REMAP(cu->bevobj);
ID_NEW_REMAP(cu->taperobj);
if (cu->key) { /* We do not need to set cu->key->id.newid here... */
- BKE_animdata_copy_id_action(bmain, (ID *)cu->key, false);
+ BKE_animdata_copy_id_action(bmain, (ID *)cu->key);
}
break;
case OB_LATTICE:
ob->data = lat = ID_NEW_SET(ob->data, BKE_lattice_copy(bmain, ob->data));
if (lat->key) { /* We do not need to set lat->key->id.newid here... */
- BKE_animdata_copy_id_action(bmain, (ID *)lat->key, false);
+ BKE_animdata_copy_id_action(bmain, (ID *)lat->key);
}
break;
case OB_ARMATURE:
@@ -1946,7 +1937,7 @@ static void single_obdata_users(
* AnimData structure, which is not what we want.
* (sergey)
*/
- BKE_animdata_copy_id_action(bmain, (ID *)ob->data, false);
+ BKE_animdata_copy_id_action(bmain, (ID *)ob->data);
id_us_min(id);
}
@@ -1967,7 +1958,7 @@ static void single_object_action_users(
FOREACH_OBJECT_FLAG_BEGIN (scene, view_layer, v3d, flag, ob) {
if (!ID_IS_LINKED(ob)) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- BKE_animdata_copy_id_action(bmain, &ob->id, false);
+ BKE_animdata_copy_id_action(bmain, &ob->id);
}
}
FOREACH_OBJECT_FLAG_END;
@@ -1989,7 +1980,7 @@ static void single_mat_users(
if (ma->id.us > 1) {
man = BKE_material_copy(bmain, ma);
- BKE_animdata_copy_id_action(bmain, &man->id, false);
+ BKE_animdata_copy_id_action(bmain, &man->id);
man->id.us = 0;
BKE_object_material_assign(bmain, ob, man, a, BKE_MAT_ASSIGN_USERPREF);
@@ -2251,71 +2242,22 @@ void OBJECT_OT_make_local(wmOperatorType *ot)
/** \name Make Library Override Operator
* \{ */
-static bool make_override_hierarchy_recursive_tag(Main *bmain, ID *id)
+static bool make_override_library_ovject_overridable_check(Main *bmain, Object *object)
{
- MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id);
-
- /* This way we won't process again that ID should we encounter it again through another
- * relationship hierarchy.
- * Note that this does not free any memory from relations, so we can still use the entries.
- */
- BKE_main_relations_ID_remove(bmain, id);
-
- for (; entry != NULL; entry = entry->next) {
- /* We only consider IDs from the same library. */
- if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) {
- if (make_override_hierarchy_recursive_tag(bmain, *entry->id_pointer)) {
- id->tag |= LIB_TAG_DOIT;
- }
+ /* An object is actually overrideable only if it is in at least one local collections.
+ * Unfortunately 'direct link' flag is not enough here. */
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
+ if (!ID_IS_LINKED(collection) && BKE_collection_has_object(collection, object)) {
+ return true;
}
}
-
- return (id->tag & LIB_TAG_DOIT) != 0;
-}
-
-static int make_override_tag_ids_cb(LibraryIDLinkCallbackData *cb_data)
-{
- if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK)) {
- return IDWALK_RET_STOP_RECURSION;
- }
-
- ID *id_root = cb_data->user_data;
- Library *library_root = id_root->lib;
- ID *id = *cb_data->id_pointer;
- ID *id_owner = cb_data->id_owner;
-
- BLI_assert(id_owner == cb_data->id_self);
-
- if (ELEM(id, NULL, id_owner)) {
- return IDWALK_RET_NOP;
- }
-
- BLI_assert(id->lib != NULL);
- BLI_assert(id_owner->lib == library_root);
-
- if (id->tag & LIB_TAG_DOIT) {
- /* Already processed, but maybe not with the same chain of dependency, so we need to check that
- * one nonetheless. */
- return IDWALK_RET_STOP_RECURSION;
- }
-
- if (id->lib != library_root) {
- /* We do not override data-blocks from other libraries, nor do we process them. */
- return IDWALK_RET_STOP_RECURSION;
- }
-
- /* We tag all collections and objects for override. And we also tag all other data-blocks which
- * would user one of those. */
- if (ELEM(GS(id->name), ID_OB, ID_GR)) {
- id->tag |= LIB_TAG_DOIT;
- }
-
- return IDWALK_RET_NOP;
+ return false;
}
/* Set the object to override. */
static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *obact = ED_object_active_context(C);
@@ -2324,14 +2266,9 @@ static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEve
return OPERATOR_CANCELLED;
}
- /* Get object to work on - use a menu if we need to... */
- if (!ID_IS_LINKED(obact) && obact->instance_collection != NULL &&
- ID_IS_LINKED(obact->instance_collection)) {
- /* Gives menu with list of objects in group. */
- WM_enum_search_invoke(C, op, event);
- return OPERATOR_CANCELLED;
- }
- else if (ID_IS_LINKED(obact)) {
+ if ((!ID_IS_LINKED(obact) && obact->instance_collection != NULL &&
+ ID_IS_OVERRIDABLE_LIBRARY(obact->instance_collection)) ||
+ make_override_library_ovject_overridable_check(bmain, obact)) {
uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("OK?"), ICON_QUESTION);
uiLayout *layout = UI_popup_menu_layout(pup);
@@ -2346,22 +2283,28 @@ static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEve
/* This invoke just calls another instance of this operator... */
return OPERATOR_INTERFACE;
}
- else {
- /* Error.. cannot continue. */
- BKE_report(op->reports,
- RPT_ERROR,
- "Can only make library override for a referenced object or collection");
+
+ if (ID_IS_LINKED(obact)) {
+ /* Show menu with list of directly linked collections containing the active object. */
+ WM_enum_search_invoke(C, op, event);
return OPERATOR_CANCELLED;
}
+
+ /* Error.. cannot continue. */
+ BKE_report(op->reports,
+ RPT_ERROR,
+ "Can only make library override for a referenced object or collection");
+ return OPERATOR_CANCELLED;
}
static int make_override_library_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obact = CTX_data_active_object(C);
ID *id_root = NULL;
-
- bool success = false;
+ bool is_override_instancing_object = false;
if (!ID_IS_LINKED(obact) && obact->instance_collection != NULL &&
ID_IS_LINKED(obact->instance_collection)) {
@@ -2374,13 +2317,31 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
}
id_root = &obact->instance_collection->id;
+ is_override_instancing_object = true;
}
- else if (!ID_IS_OVERRIDABLE_LIBRARY(obact)) {
- BKE_reportf(op->reports,
- RPT_ERROR_INVALID_INPUT,
- "Active object '%s' is not overridable",
- obact->id.name + 2);
- return OPERATOR_CANCELLED;
+ else if (!make_override_library_ovject_overridable_check(bmain, obact)) {
+ const int i = RNA_property_enum_get(op->ptr, op->type->prop);
+ const uint collection_session_uuid = *((uint *)&i);
+ if (collection_session_uuid == MAIN_ID_SESSION_UUID_UNSET) {
+ BKE_reportf(op->reports,
+ RPT_ERROR_INVALID_INPUT,
+ "Active object '%s' is not overridable",
+ obact->id.name + 2);
+ return OPERATOR_CANCELLED;
+ }
+
+ Collection *collection = BLI_listbase_bytes_find(&bmain->collections,
+ &collection_session_uuid,
+ sizeof(collection_session_uuid),
+ offsetof(ID, session_uuid));
+ if (!ID_IS_OVERRIDABLE_LIBRARY(collection)) {
+ BKE_reportf(op->reports,
+ RPT_ERROR_INVALID_INPUT,
+ "Could not find an overridable collection containing object '%s'",
+ obact->id.name + 2);
+ return OPERATOR_CANCELLED;
+ }
+ id_root = &collection->id;
}
/* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
else {
@@ -2389,154 +2350,60 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
- /* Tag all collections and objects, as well as other IDs using them. */
- id_root->tag |= LIB_TAG_DOIT;
-
- BKE_main_relations_create(bmain, 0);
-
- BKE_library_foreach_ID_link(
- bmain, id_root, make_override_tag_ids_cb, id_root, IDWALK_READONLY | IDWALK_RECURSE);
+ const bool success = BKE_lib_override_library_create(
+ bmain, scene, view_layer, id_root, &obact->id);
- /* Then, we remove (untag) bone shape objects, you shall never want to override those
- * (hopefully)... */
- LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
- if (ob->type == OB_ARMATURE && ob->pose != NULL && (ob->id.tag & LIB_TAG_DOIT)) {
- for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
- if (pchan->custom != NULL) {
- pchan->custom->id.tag &= ~LIB_TAG_DOIT;
- }
- }
- }
+ /* Remove the instance empty from this scene, the items now have an overridden collection
+ * instead. */
+ if (success && is_override_instancing_object) {
+ ED_object_base_free_and_unlink(bmain, scene, obact);
}
- /* Then we tag all intermediary data-blocks in-between two overridden ones (e.g. if a shapekey
- * has a driver using an armature object's bone, we need to override the shapekey/obdata, the
- * objects using them, etc.) */
- make_override_hierarchy_recursive_tag(bmain, id_root);
-
- BKE_main_relations_free(bmain);
-
- ID *id;
- FOREACH_MAIN_ID_BEGIN (bmain, id) {
- if (id->tag & LIB_TAG_DOIT && id->lib != NULL) {
- printf("ID %s tagged for override\n", id->name);
- }
- }
- FOREACH_MAIN_ID_END;
+ DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
- success = BKE_lib_override_library_create_from_tag(bmain);
+ return success ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+}
- if (success) {
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
+static bool make_override_library_poll(bContext *C)
+{
+ Object *obact = CTX_data_active_object(C);
- BKE_main_collection_sync(bmain);
+ /* Object must be directly linked to be overridable. */
+ return (ED_operator_objectmode(C) && obact != NULL &&
+ (ID_IS_LINKED(obact) || (obact->instance_collection != NULL &&
+ ID_IS_OVERRIDABLE_LIBRARY(obact->instance_collection))));
+}
- switch (GS(id_root->name)) {
- case ID_GR: {
- Collection *collection_new = ((Collection *)id_root->newid);
- BKE_collection_add_from_object(bmain, scene, obact, collection_new);
+static const EnumPropertyItem *make_override_collections_of_linked_object_itemf(
+ bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ EnumPropertyItem item_tmp = {0}, *item = NULL;
+ int totitem = 0;
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection_new, ob_new) {
- if (ob_new != NULL && ob_new->id.override_library != NULL) {
- Base *base;
- if ((base = BKE_view_layer_base_find(view_layer, ob_new)) == NULL) {
- BKE_collection_object_add_from(bmain, scene, obact, ob_new);
- base = BKE_view_layer_base_find(view_layer, ob_new);
- DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
- }
+ Object *object = ED_object_active_context(C);
+ Main *bmain = CTX_data_main(C);
- if (ob_new == (Object *)obact->id.newid) {
- /* TODO: is setting active needed? */
- BKE_view_layer_base_select_and_set_active(view_layer, base);
- }
- }
- }
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
- break;
- }
- case ID_OB: {
- BKE_collection_object_add_from(bmain, scene, obact, ((Object *)id_root->newid));
- break;
- }
- default:
- BLI_assert(0);
- }
-
- /* We need to ensure all new overrides of objects are properly instantiated. */
- LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
- Object *ob_new = (Object *)ob->id.newid;
- if (ob_new != NULL) {
- BLI_assert(ob_new->id.override_library != NULL &&
- ob_new->id.override_library->reference == &ob->id);
-
- Collection *default_instantiating_collection = NULL;
- Base *base;
- if ((base = BKE_view_layer_base_find(view_layer, ob_new)) == NULL) {
- if (default_instantiating_collection == NULL) {
- switch (GS(id_root->name)) {
- case ID_GR: {
- default_instantiating_collection = BKE_collection_add(
- bmain, (Collection *)id_root, "OVERRIDE_HIDDEN");
- break;
- }
- case ID_OB: {
- /* Add the new container collection to one of the collections instantiating the
- * root object, or scene's master collection if none found. */
- Object *ob_root = (Object *)id_root;
- LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
- if (BKE_collection_has_object(collection, ob_root) &&
- BKE_view_layer_has_collection(view_layer, collection)) {
- default_instantiating_collection = BKE_collection_add(
- bmain, collection, "OVERRIDE_HIDDEN");
- }
- }
- if (default_instantiating_collection == NULL) {
- default_instantiating_collection = BKE_collection_add(
- bmain, scene->master_collection, "OVERRIDE_HIDDEN");
- }
- break;
- }
- default:
- BLI_assert(0);
- }
- /* Hide the collection from viewport and render. */
- default_instantiating_collection->flag |= COLLECTION_RESTRICT_VIEWPORT |
- COLLECTION_RESTRICT_RENDER;
- }
+ if (!object || !ID_IS_LINKED(object)) {
+ return DummyRNA_DEFAULT_items;
+ }
- BKE_collection_object_add(bmain, default_instantiating_collection, ob_new);
- DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
- }
- }
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
+ /* Only check for directly linked collections. */
+ if (!ID_IS_LINKED(&collection->id) || (collection->id.tag & LIB_TAG_INDIRECT) != 0) {
+ continue;
}
-
- /* Remove the instance empty from this scene, the items now have an overridden collection
- * instead. */
- if (id_root != &obact->id) {
- ED_object_base_free_and_unlink(bmain, scene, obact);
+ if (BKE_collection_has_object_recursive(collection, object)) {
+ item_tmp.identifier = item_tmp.name = collection->id.name + 2;
+ item_tmp.value = *((int *)&collection->id.session_uuid);
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
}
}
- /* Cleanup. */
- BKE_main_id_clear_newpoins(bmain);
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
-
- DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_WINDOW, NULL);
-
- return success ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
-}
-
-static bool make_override_library_poll(bContext *C)
-{
- Object *obact = CTX_data_active_object(C);
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
- /* Object must be directly linked to be overridable. */
- return (BKE_lib_override_library_is_enabled() && ED_operator_objectmode(C) && obact != NULL &&
- ((ID_IS_LINKED(obact) && obact->id.tag & LIB_TAG_EXTERN) ||
- (!ID_IS_LINKED(obact) && obact->instance_collection != NULL &&
- ID_IS_LINKED(obact->instance_collection))));
+ return item;
}
void OBJECT_OT_make_override_library(wmOperatorType *ot)
@@ -2557,12 +2424,13 @@ void OBJECT_OT_make_override_library(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
prop = RNA_def_enum(ot->srna,
- "object",
+ "collection",
DummyRNA_DEFAULT_items,
- 0,
- "Override Object",
- "Name of lib-linked/collection object to make an override from");
- RNA_def_enum_funcs(prop, proxy_collection_object_itemf);
+ MAIN_ID_SESSION_UUID_UNSET,
+ "Override Collection",
+ "Name of directly linked collection containing the selected object, to make "
+ "an override from");
+ RNA_def_enum_funcs(prop, make_override_collections_of_linked_object_itemf);
RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
ot->prop = prop;
}
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index 84ad17db971..28f58a34814 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -72,7 +72,6 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -1042,7 +1041,7 @@ static bool quadriflow_poll_property(const bContext *C, wmOperator *op, const Pr
if (STREQ(prop_id, "target_edge_length") && mode != QUADRIFLOW_REMESH_EDGE_LENGTH) {
return false;
}
- else if (STREQ(prop_id, "target_faces")) {
+ if (STREQ(prop_id, "target_faces")) {
if (mode != QUADRIFLOW_REMESH_FACES) {
/* Make sure we can edit the target_faces value even if it doesn't start as EDITABLE */
float area = RNA_float_get(op->ptr, "mesh_area");
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 5f9799710dc..e20de5a92ff 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -218,13 +218,9 @@ static int get_base_select_priority(Base *base)
if (base->flag & BASE_SELECTABLE) {
return 3;
}
- else {
- return 2;
- }
- }
- else {
- return 1;
+ return 2;
}
+ return 1;
}
/**
@@ -251,13 +247,12 @@ Base *ED_object_find_first_by_data_id(ViewLayer *view_layer, ID *id)
if (base->flag & BASE_SELECTED) {
return base;
}
- else {
- int priority_test = get_base_select_priority(base);
- if (priority_test > priority_best) {
- priority_best = priority_test;
- base_best = base;
- }
+ int priority_test = get_base_select_priority(base);
+
+ if (priority_test > priority_best) {
+ priority_best = priority_test;
+ base_best = base;
}
}
}
@@ -671,7 +666,7 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
// object_select_all_by_ipo(C, ob->ipo)
return OPERATOR_CANCELLED;
}
- else if (nr == OBJECT_SELECT_LINKED_OBDATA) {
+ if (nr == OBJECT_SELECT_LINKED_OBDATA) {
if (ob->data == NULL) {
return OPERATOR_CANCELLED;
}
@@ -855,7 +850,7 @@ static bool select_grouped_collection(bContext *C, Object *ob)
if (!collection_count) {
return 0;
}
- else if (collection_count == 1) {
+ if (collection_count == 1) {
collection = ob_collections[0];
CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
@@ -998,7 +993,7 @@ static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob), ReportList
BKE_report(reports, RPT_ERROR, "No active Keying Set to use");
return false;
}
- else if (ANIM_validate_keyingset(C, NULL, ks) != 0) {
+ if (ANIM_validate_keyingset(C, NULL, ks) != 0) {
if (ks->paths.first == NULL) {
if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
BKE_report(reports,
@@ -1160,14 +1155,12 @@ static int object_select_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else if (any_visible == false) {
+ if (any_visible == false) {
/* TODO(campbell): Looks like we could remove this,
* if not comment should say why its needed. */
return OPERATOR_PASS_THROUGH;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_select_all(wmOperatorType *ot)
@@ -1386,9 +1379,7 @@ static int object_select_more_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_select_more(wmOperatorType *ot)
@@ -1419,9 +1410,7 @@ static int object_select_less_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_select_less(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_shader_fx.c b/source/blender/editors/object/object_shader_fx.c
index d9f37b8e38b..977d4abd4d4 100644
--- a/source/blender/editors/object/object_shader_fx.c
+++ b/source/blender/editors/object/object_shader_fx.c
@@ -24,6 +24,7 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "MEM_guardedalloc.h"
@@ -55,6 +56,8 @@
#include "ED_object.h"
#include "ED_screen.h"
+#include "UI_interface.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -247,7 +250,7 @@ static int shaderfx_add_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_SHADERFX, ob);
return OPERATOR_FINISHED;
}
@@ -360,22 +363,57 @@ static void edit_shaderfx_properties(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN);
}
-static int edit_shaderfx_invoke_properties(bContext *C, wmOperator *op)
+static void edit_shaderfx_report_property(wmOperatorType *ot)
{
- ShaderFxData *fx;
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "report", false, "Report", "Create a notification after the operation");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+/**
+ * \param event: If this isn't NULL, the operator will also look for panels underneath
+ * the cursor with customdata set to a modifier.
+ * \param r_retval: This should be used if #event is used in order to to return
+ * #OPERATOR_PASS_THROUGH to check other operators with the same key set.
+ */
+static bool edit_shaderfx_invoke_properties(bContext *C,
+ wmOperator *op,
+ const wmEvent *event,
+ int *r_retval)
+{
if (RNA_struct_property_is_set(op->ptr, "shaderfx")) {
return true;
}
- else {
- PointerRNA ptr = CTX_data_pointer_get_type(C, "shaderfx", &RNA_ShaderFx);
- if (ptr.data) {
- fx = ptr.data;
- RNA_string_set(op->ptr, "shaderfx", fx->name);
- return true;
+
+ PointerRNA ctx_ptr = CTX_data_pointer_get_type(C, "shaderfx", &RNA_ShaderFx);
+ if (ctx_ptr.data != NULL) {
+ ShaderFxData *fx = ctx_ptr.data;
+ RNA_string_set(op->ptr, "shaderfx", fx->name);
+ return true;
+ }
+
+ /* Check the custom data of panels under the mouse for an effect. */
+ if (event != NULL) {
+ PointerRNA *panel_ptr = UI_region_panel_custom_data_under_cursor(C, event);
+
+ if (!(panel_ptr == NULL || RNA_pointer_is_null(panel_ptr))) {
+ if (RNA_struct_is_a(panel_ptr->type, &RNA_ShaderFx)) {
+ ShaderFxData *fx = panel_ptr->data;
+ RNA_string_set(op->ptr, "shaderfx", fx->name);
+ return true;
+ }
+
+ BLI_assert(r_retval != NULL); /* We need the return value in this case. */
+ if (r_retval != NULL) {
+ *r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
+ }
+ return false;
}
}
+ if (r_retval != NULL) {
+ *r_retval = OPERATOR_CANCELLED;
+ }
return false;
}
@@ -404,23 +442,30 @@ static int shaderfx_remove_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0);
+ /* Store name temporarily for report. */
+ char name[MAX_NAME];
+ strcpy(name, fx->name);
+
if (!fx || !ED_object_shaderfx_remove(op->reports, bmain, ob, fx)) {
return OPERATOR_CANCELLED;
}
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ if (RNA_boolean_get(op->ptr, "report")) {
+ BKE_reportf(op->reports, RPT_INFO, "Removed effect: %s", name);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_SHADERFX, ob);
return OPERATOR_FINISHED;
}
-static int shaderfx_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int shaderfx_remove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_shaderfx_invoke_properties(C, op)) {
+ int retval;
+ if (edit_shaderfx_invoke_properties(C, op, event, &retval)) {
return shaderfx_remove_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return retval;
}
void OBJECT_OT_shaderfx_remove(wmOperatorType *ot)
@@ -436,6 +481,7 @@ void OBJECT_OT_shaderfx_remove(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_shaderfx_properties(ot);
+ edit_shaderfx_report_property(ot);
}
/************************ move up shaderfx operator *********************/
@@ -450,19 +496,18 @@ static int shaderfx_move_up_exec(bContext *C, wmOperator *op)
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_SHADERFX, ob);
return OPERATOR_FINISHED;
}
-static int shaderfx_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int shaderfx_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_shaderfx_invoke_properties(C, op)) {
+ int retval;
+ if (edit_shaderfx_invoke_properties(C, op, event, &retval)) {
return shaderfx_move_up_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return retval;
}
void OBJECT_OT_shaderfx_move_up(wmOperatorType *ot)
@@ -492,19 +537,18 @@ static int shaderfx_move_down_exec(bContext *C, wmOperator *op)
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_SHADERFX, ob);
return OPERATOR_FINISHED;
}
-static int shaderfx_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int shaderfx_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_shaderfx_invoke_properties(C, op)) {
+ int retval;
+ if (edit_shaderfx_invoke_properties(C, op, event, &retval)) {
return shaderfx_move_down_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return retval;
}
void OBJECT_OT_shaderfx_move_down(wmOperatorType *ot)
@@ -540,19 +584,18 @@ static int shaderfx_move_to_index_exec(bContext *C, wmOperator *op)
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_SHADERFX, ob);
return OPERATOR_FINISHED;
}
-static int shaderfx_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int shaderfx_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_shaderfx_invoke_properties(C, op)) {
+ int retval;
+ if (edit_shaderfx_invoke_properties(C, op, event, &retval)) {
return shaderfx_move_to_index_exec(C, op);
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return retval;
}
void OBJECT_OT_shaderfx_move_to_index(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 71778f92349..52e06f46149 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -305,9 +305,7 @@ static int shape_key_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 161611d59c9..f2d7ad3ac11 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -1002,10 +1002,8 @@ static int object_transform_apply_exec(bContext *C, wmOperator *op)
if (loc || rot || sca) {
return apply_objects_internal(C, op->reports, loc, rot, sca, do_props);
}
- else {
- /* allow for redo */
- return OPERATOR_FINISHED;
- }
+ /* allow for redo */
+ return OPERATOR_FINISHED;
}
void OBJECT_OT_transform_apply(wmOperatorType *ot)
@@ -2036,7 +2034,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
object_transform_axis_target_free_data(op);
return OPERATOR_FINISHED;
}
- else if (ELEM(event->type, EVT_ESCKEY, RIGHTMOUSE)) {
+ if (ELEM(event->type, EVT_ESCKEY, RIGHTMOUSE)) {
object_transform_axis_target_cancel(C, op);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_utils.c b/source/blender/editors/object/object_utils.c
index 00aafc2120f..fbbfde1ebef 100644
--- a/source/blender/editors/object/object_utils.c
+++ b/source/blender/editors/object/object_utils.c
@@ -131,20 +131,18 @@ bool ED_object_calc_active_center(Object *ob, const bool select_only, float r_ce
}
return false;
}
- else if (ob->mode & OB_MODE_POSE) {
+ if (ob->mode & OB_MODE_POSE) {
if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
mul_m4_v3(ob->obmat, r_center);
return true;
}
return false;
}
- else {
- if (!select_only || (ob->base_flag & BASE_SELECTED)) {
- copy_v3_v3(r_center, ob->obmat[3]);
- return true;
- }
- return false;
+ if (!select_only || (ob->base_flag & BASE_SELECTED)) {
+ copy_v3_v3(r_center, ob->obmat[3]);
+ return true;
}
+ return false;
}
/** \} */
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 7ca2a89f61d..253287c382e 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -86,13 +86,11 @@ static bool vertex_group_use_vert_sel(Object *ob)
if (ob->mode == OB_MODE_EDIT) {
return true;
}
- else if ((ob->type == OB_MESH) &&
- ((Mesh *)ob->data)->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL)) {
+ if ((ob->type == OB_MESH) &&
+ ((Mesh *)ob->data)->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL)) {
return true;
}
- else {
- return false;
- }
+ return false;
}
static Lattice *vgroup_edit_lattice(Object *ob)
@@ -189,7 +187,7 @@ bool ED_vgroup_parray_alloc(ID *id,
return true;
}
- else if (me->dvert) {
+ if (me->dvert) {
MVert *mvert = me->mvert;
MDeformVert *dvert = me->dvert;
int i;
@@ -1771,12 +1769,14 @@ static void vgroup_lock_all(Object *ob, int action, int mask)
switch (mask) {
case VGROUP_MASK_INVERT_UNSELECTED:
case VGROUP_MASK_SELECTED:
- if (!selected[i])
+ if (!selected[i]) {
continue;
+ }
break;
case VGROUP_MASK_UNSELECTED:
- if (selected[i])
+ if (selected[i]) {
continue;
+ }
break;
default:;
}
@@ -1791,12 +1791,14 @@ static void vgroup_lock_all(Object *ob, int action, int mask)
for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
switch (mask) {
case VGROUP_MASK_SELECTED:
- if (!selected[i])
+ if (!selected[i]) {
continue;
+ }
break;
case VGROUP_MASK_UNSELECTED:
- if (selected[i])
+ if (selected[i]) {
continue;
+ }
break;
default:;
}
@@ -2115,15 +2117,13 @@ static int inv_cmp_mdef_vert_weights(const void *a1, const void *a2)
if (dw1->weight < dw2->weight) {
return 1;
}
- else if (dw1->weight > dw2->weight) {
+ if (dw1->weight > dw2->weight) {
return -1;
}
- else if (&dw1 < &dw2) {
+ if (&dw1 < &dw2) {
return 1; /* compare address for stable sort algorithm */
}
- else {
- return -1;
- }
+ return -1;
}
/* Used for limiting the number of influencing bones per vertex when exporting
@@ -2719,23 +2719,17 @@ static bool vertex_group_vert_poll_ex(bContext *C,
if (BKE_object_is_in_editmode_vgroup(ob)) {
return true;
}
- else if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (ob->mode & OB_MODE_WEIGHT_PAINT) {
if (needs_select) {
if (BKE_object_is_in_wpaint_select_vert(ob)) {
return true;
}
- else {
- CTX_wm_operator_poll_msg_set(C, "Vertex select needs to be enabled in weight paint mode");
- return false;
- }
- }
- else {
- return true;
+ CTX_wm_operator_poll_msg_set(C, "Vertex select needs to be enabled in weight paint mode");
+ return false;
}
+ return true;
}
- else {
- return false;
- }
+ return false;
}
#if 0
@@ -3011,7 +3005,7 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
/* properties */
prop = RNA_def_boolean(ot->srna, "use_all_groups", 0, "All Groups", "Remove from all groups");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "use_all_verts", 0, "All Verts", "Clear the active group");
+ prop = RNA_def_boolean(ot->srna, "use_all_verts", 0, "All Vertices", "Clear the active group");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -3181,9 +3175,7 @@ static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
/** \} */
@@ -3229,10 +3221,9 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- /* allow to adjust settings */
- return OPERATOR_FINISHED;
- }
+
+ /* allow to adjust settings */
+ return OPERATOR_FINISHED;
}
/** \} */
@@ -3503,12 +3494,12 @@ void OBJECT_OT_vertex_group_invert(wmOperatorType *ot)
"auto_assign",
true,
"Add Weights",
- "Add verts from groups that have zero weight before inverting");
+ "Add vertices from groups that have zero weight before inverting");
RNA_def_boolean(ot->srna,
"auto_remove",
true,
"Remove Weights",
- "Remove verts from groups that have zero weight after inverting");
+ "Remove vertices from groups that have zero weight after inverting");
}
/** \} */
@@ -3723,11 +3714,10 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- /* note, would normally return canceled, except we want the redo
- * UI to show up for users to change */
- return OPERATOR_FINISHED;
- }
+
+ /* note, would normally return canceled, except we want the redo
+ * UI to show up for users to change */
+ return OPERATOR_FINISHED;
}
void OBJECT_OT_vertex_group_limit_total(wmOperatorType *ot)
@@ -4119,8 +4109,6 @@ static void vgroup_sort_bone_hierarchy(Object *ob, ListBase *bonebase)
}
}
}
-
- return;
}
enum {
@@ -4364,7 +4352,7 @@ void OBJECT_OT_vertex_weight_paste(wmOperatorType *ot)
ot->name = "Paste Weight to Selected";
ot->idname = "OBJECT_OT_vertex_weight_paste";
ot->description =
- "Copy this group's weight to other selected verts (disabled if vertex group is locked)";
+ "Copy this group's weight to other selected vertices (disabled if vertex group is locked)";
/* api callbacks */
ot->poll = vertex_group_vert_select_mesh_poll;
@@ -4503,9 +4491,7 @@ static int vertex_weight_normalize_active_vertex_exec(bContext *C, wmOperator *U
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void OBJECT_OT_vertex_weight_normalize_active_vertex(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_volume.c b/source/blender/editors/object/object_volume.c
index 4cdbbea492b..c5dc7f9f24d 100644
--- a/source/blender/editors/object/object_volume.c
+++ b/source/blender/editors/object/object_volume.c
@@ -119,7 +119,7 @@ static int volume_import_exec(bContext *C, wmOperator *op)
BKE_id_delete(bmain, &volume->id);
continue;
}
- else if (BKE_volume_is_points_only(volume)) {
+ if (BKE_volume_is_points_only(volume)) {
BKE_reportf(op->reports,
RPT_WARNING,
"Volume \"%s\" contains points, only voxel grids are supported",
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 6922a03b12f..381bf317bee 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)
/* api callbacks */
ot->exec = surface_slot_add_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -151,7 +151,7 @@ void DPAINT_OT_surface_slot_remove(wmOperatorType *ot)
/* api callbacks */
ot->exec = surface_slot_remove_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -203,7 +203,7 @@ void DPAINT_OT_type_toggle(wmOperatorType *ot)
/* api callbacks */
ot->exec = type_toggle_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -286,7 +286,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot)
/* api callbacks */
ot->exec = output_toggle_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -538,5 +538,5 @@ void DPAINT_OT_bake(wmOperatorType *ot)
/* api callbacks */
ot->exec = dynamicpaint_bake_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 457c8ba30e6..82a1139c860 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -216,11 +216,9 @@ PTCacheEdit *PE_get_current_from_psys(ParticleSystem *psys)
if ((psys->flag & PSYS_HAIR_DYNAMICS) != 0 && (psys->pointcache->flag & PTCACHE_BAKED) != 0) {
return psys->pointcache->edit;
}
- else {
- return psys->edit;
- }
+ return psys->edit;
}
- else if (psys->pointcache->flag & PTCACHE_BAKED) {
+ if (psys->pointcache->flag & PTCACHE_BAKED) {
return psys->pointcache->edit;
}
return NULL;
@@ -561,9 +559,7 @@ static bool key_test_depth(const PEData *data, const float co[3], const int scre
if (win[2] - 0.00001f > depth) {
return 0;
}
- else {
- return 1;
- }
+ return 1;
}
static bool key_inside_circle(const PEData *data, float rad, const float co[3], float *distance)
@@ -618,9 +614,7 @@ static bool key_inside_test(PEData *data, const float co[3])
if (data->mval) {
return key_inside_circle(data, data->rad, co, NULL);
}
- else {
- return key_inside_rect(data, co);
- }
+ return key_inside_rect(data, co);
}
static bool point_is_selected(PTCacheEditPoint *point)
@@ -3372,9 +3366,7 @@ static void PE_mirror_x(Depsgraph *depsgraph, Scene *scene, Object *ob, int tagg
PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, NULL);
continue;
}
- else {
- point->flag |= PEP_TAG;
- }
+ point->flag |= PEP_TAG;
}
}
@@ -4354,7 +4346,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
}
pa->size = 1.0f;
- initialize_particle(&sim, pa);
+ init_particle(&sim, pa);
reset_particle(&sim, pa, 0.0, 1.0);
point->flag |= PEP_EDIT_RECALC;
if (pe_x_mirror(ob)) {
diff --git a/source/blender/editors/physics/particle_edit_utildefines.h b/source/blender/editors/physics/particle_edit_utildefines.h
index dc858687341..289ca193f17 100644
--- a/source/blender/editors/physics/particle_edit_utildefines.h
+++ b/source/blender/editors/physics/particle_edit_utildefines.h
@@ -21,8 +21,7 @@
* \ingroup edphys
*/
-#ifndef __PARTICLE_EDIT_UTILDEFINES_H__
-#define __PARTICLE_EDIT_UTILDEFINES_H__
+#pragma once
#define KEY_K \
PTCacheEditKey *key; \
@@ -58,5 +57,3 @@
if (key->flag & PEK_TAG)
#define KEY_WCO ((key->flag & PEK_USE_WCO) ? key->world_co : key->co)
-
-#endif /* __PARTICLE_EDIT_UTILDEFINES_H__ */
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index e75169a476b..41e30adf724 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -104,7 +104,7 @@ void OBJECT_OT_particle_system_add(wmOperatorType *ot)
ot->description = "Add a particle system";
/* api callbacks */
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
ot->exec = particle_system_add_exec;
/* flags */
@@ -151,7 +151,7 @@ void OBJECT_OT_particle_system_remove(wmOperatorType *ot)
ot->description = "Remove the selected particle system";
/* api callbacks */
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
ot->exec = particle_system_remove_exec;
/* flags */
@@ -1210,7 +1210,7 @@ static bool copy_particle_systems_to_object(const bContext *C,
static bool copy_particle_systems_poll(bContext *C)
{
Object *ob;
- if (!ED_operator_object_active_editable(C)) {
+ if (!ED_operator_object_active_local_editable(C)) {
return false;
}
@@ -1311,7 +1311,7 @@ void PARTICLE_OT_copy_particle_systems(wmOperatorType *ot)
static bool duplicate_particle_systems_poll(bContext *C)
{
- if (!ED_operator_object_active_editable(C)) {
+ if (!ED_operator_object_active_local_editable(C)) {
return false;
}
Object *ob = ED_object_active_context(C);
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 583c68cb284..26b5f7fb2af 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -546,6 +546,7 @@ static int fluid_bake_exec(struct bContext *C, struct wmOperator *op)
return OPERATOR_CANCELLED;
}
if (!fluid_validatepaths(job, op->reports)) {
+ fluid_bake_free(job);
return OPERATOR_CANCELLED;
}
WM_report_banners_cancel(job->bmain);
@@ -574,6 +575,7 @@ static int fluid_bake_invoke(struct bContext *C,
}
if (!fluid_validatepaths(job, op->reports)) {
+ fluid_bake_free(job);
return OPERATOR_CANCELLED;
}
@@ -651,6 +653,7 @@ static int fluid_free_exec(struct bContext *C, struct wmOperator *op)
job->name = op->type->name;
if (!fluid_validatepaths(job, op->reports)) {
+ fluid_bake_free(job);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h
index 87c3a709d47..4dc3ded9bd7 100644
--- a/source/blender/editors/physics/physics_intern.h
+++ b/source/blender/editors/physics/physics_intern.h
@@ -21,8 +21,7 @@
* \ingroup edphys
*/
-#ifndef __PHYSICS_INTERN_H__
-#define __PHYSICS_INTERN_H__
+#pragma once
struct Depsgraph;
struct Object;
@@ -152,5 +151,3 @@ void RIGIDBODY_OT_constraint_remove(struct wmOperatorType *ot);
void RIGIDBODY_OT_world_add(struct wmOperatorType *ot);
void RIGIDBODY_OT_world_remove(struct wmOperatorType *ot);
void RIGIDBODY_OT_world_export(struct wmOperatorType *ot);
-
-#endif /* __PHYSICS_INTERN_H__ */
diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c
index a59b031298c..4939bf0086b 100644
--- a/source/blender/editors/physics/rigidbody_constraint.c
+++ b/source/blender/editors/physics/rigidbody_constraint.c
@@ -68,9 +68,7 @@ static bool ED_operator_rigidbody_con_active_poll(bContext *C)
Object *ob = ED_object_active_context(C);
return (ob && ob->rigidbody_constraint);
}
- else {
- return false;
- }
+ return false;
}
static bool ED_operator_rigidbody_con_add_poll(bContext *C)
@@ -151,9 +149,7 @@ static int rigidbody_con_add_exec(bContext *C, wmOperator *op)
/* done */
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void RIGIDBODY_OT_constraint_add(wmOperatorType *ot)
@@ -193,9 +189,7 @@ static int rigidbody_con_remove_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Object has no Rigid Body Constraint to remove");
return OPERATOR_CANCELLED;
}
- else {
- ED_rigidbody_constraint_remove(bmain, scene, ob);
- }
+ ED_rigidbody_constraint_remove(bmain, scene, ob);
/* send updates */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index 78369345b9a..b91385c502c 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -73,9 +73,7 @@ static bool ED_operator_rigidbody_active_poll(bContext *C)
Object *ob = ED_object_active_context(C);
return (ob && ob->rigidbody_object);
}
- else {
- return 0;
- }
+ return 0;
}
static bool ED_operator_rigidbody_add_poll(bContext *C)
@@ -91,9 +89,7 @@ static bool ED_operator_rigidbody_add_poll(bContext *C)
Object *ob = ED_object_active_context(C);
return (ob && ob->type == OB_MESH);
}
- else {
- return false;
- }
+ return false;
}
/* ----------------- */
@@ -135,9 +131,7 @@ static int rigidbody_object_add_exec(bContext *C, wmOperator *op)
/* done */
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void RIGIDBODY_OT_object_add(wmOperatorType *ot)
@@ -186,10 +180,9 @@ static int rigidbody_object_remove_exec(bContext *C, wmOperator *op)
/* done */
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports, RPT_ERROR, "Object has no Rigid Body settings to remove");
- return OPERATOR_CANCELLED;
- }
+
+ BKE_report(op->reports, RPT_ERROR, "Object has no Rigid Body settings to remove");
+ return OPERATOR_CANCELLED;
}
void RIGIDBODY_OT_object_remove(wmOperatorType *ot)
@@ -233,9 +226,7 @@ static int rigidbody_objects_add_exec(bContext *C, wmOperator *op)
/* done */
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void RIGIDBODY_OT_objects_add(wmOperatorType *ot)
@@ -286,9 +277,7 @@ static int rigidbody_objects_remove_exec(bContext *C, wmOperator *UNUSED(op))
/* done */
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void RIGIDBODY_OT_objects_remove(wmOperatorType *ot)
@@ -340,9 +329,7 @@ static int rigidbody_objects_shape_change_exec(bContext *C, wmOperator *op)
/* done */
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void RIGIDBODY_OT_shape_change(wmOperatorType *ot)
@@ -531,9 +518,7 @@ static int rigidbody_objects_calc_mass_exec(bContext *C, wmOperator *op)
/* done */
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void RIGIDBODY_OT_mass_calculate(wmOperatorType *ot)
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index 88b913b84ca..d3a06f0fc2c 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -21,8 +21,7 @@
* \ingroup edrend
*/
-#ifndef __RENDER_INTERN_H__
-#define __RENDER_INTERN_H__
+#pragma once
struct ScrArea;
struct bContext;
@@ -90,5 +89,3 @@ void RENDER_OT_view_cancel(struct wmOperatorType *ot);
/* render_opengl.c */
void RENDER_OT_opengl(struct wmOperatorType *ot);
-
-#endif /* __RENDER_INTERN_H__ */
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 1db7bf5a766..25b4ddc15fd 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -220,12 +220,10 @@ static void image_buffer_rect_update(RenderJob *rj,
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
return;
}
- else {
- if (rr->renlay == NULL) {
- return;
- }
- rectf = RE_RenderLayerGetPass(rr->renlay, RE_PASSNAME_COMBINED, viewname);
+ if (rr->renlay == NULL) {
+ return;
}
+ rectf = RE_RenderLayerGetPass(rr->renlay, RE_PASSNAME_COMBINED, viewname);
}
if (rectf == NULL) {
return;
@@ -579,7 +577,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
rj->image_outdated = true;
return;
}
- else if (rj->image_outdated) {
+ if (rj->image_outdated) {
/* update entire render */
rj->image_outdated = false;
BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_COLORMANAGE);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index e2444d4e3b5..d279958df8a 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -79,7 +79,6 @@
#include "RNA_define.h"
#include "GPU_framebuffer.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "render_intern.h"
@@ -351,7 +350,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
G.f &= ~G_FLAG_RENDER_VIEWPORT;
gp_rect = MEM_mallocN(sizex * sizey * sizeof(uchar) * 4, "offscreen rect");
- GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect);
+ GPU_offscreen_read_pixels(oglrender->ofs, GPU_DATA_UNSIGNED_BYTE, gp_rect);
for (i = 0; i < sizex * sizey * 4; i += 4) {
blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]);
@@ -963,7 +962,7 @@ static void screen_opengl_render_cancel(bContext *C, wmOperator *op)
}
/* share between invoke and exec */
-static bool screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
+static bool screen_opengl_render_anim_init(bContext *C, wmOperator *op)
{
/* initialize animation */
OGLRender *oglrender;
@@ -1236,9 +1235,8 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent
screen_opengl_render_end(C, op->customdata);
return OPERATOR_FINISHED;
}
- else {
- ret = screen_opengl_render_anim_step(C, op);
- }
+
+ ret = screen_opengl_render_anim_step(C, op);
/* stop at the end or on error */
if (ret == false) {
@@ -1258,7 +1256,7 @@ static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEven
}
if (anim) {
- if (!screen_opengl_render_anim_initialize(C, op)) {
+ if (!screen_opengl_render_anim_init(C, op)) {
return OPERATOR_CANCELLED;
}
}
@@ -1291,16 +1289,15 @@ static int screen_opengl_render_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- bool ret = true;
- if (!screen_opengl_render_anim_initialize(C, op)) {
- return OPERATOR_CANCELLED;
- }
+ bool ret = true;
- while (ret) {
- ret = screen_opengl_render_anim_step(C, op);
- }
+ if (!screen_opengl_render_anim_init(C, op)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ while (ret) {
+ ret = screen_opengl_render_anim_step(C, op);
}
/* no redraw needed, we leave state as we entered it */
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 19e4f652963..85fc6927063 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -82,7 +82,6 @@
#include "BIF_glutil.h"
-#include "GPU_glew.h"
#include "GPU_shader.h"
#include "RE_engine.h"
@@ -632,18 +631,8 @@ static bool ed_preview_draw_rect(ScrArea *area, 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);
+ immDrawPixelsTex(
+ &state, fx, fy, rres.rectx, rres.recty, GPU_RGBA8, false, rect_byte, 1.0f, 1.0f, NULL);
MEM_freeN(rect_byte);
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 49ab2c485b1..711f89b9fda 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -162,7 +162,7 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = material_slot_add_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -207,7 +207,7 @@ void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
/* api callbacks */
ot->exec = material_slot_remove_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -238,7 +238,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
else {
/* Find the first matching material.
* Note: there may be multiple but that's not a common use case. */
- for (short i = 0; i < ob->totcol; i++) {
+ for (int i = 0; i < ob->totcol; i++) {
const Material *mat = BKE_object_material_get(ob, i + 1);
if (mat_active == mat) {
mat_nr_active = i;
@@ -310,7 +310,7 @@ void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
/* api callbacks */
ot->exec = material_slot_assign_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -339,7 +339,7 @@ static int material_slot_de_select(bContext *C, bool select)
else {
/* Find the first matching material.
* Note: there may be multiple but that's not a common use case. */
- for (short i = 0; i < ob->totcol; i++) {
+ for (int i = 0; i < ob->totcol; i++) {
const Material *mat = BKE_object_material_get(ob, i + 1);
if (mat_active == mat) {
mat_nr_active = i;
@@ -465,17 +465,27 @@ static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
Object *ob = ED_object_context(C);
- Material ***matar;
+ Material ***matar_obdata;
- if (!ob || !(matar = BKE_object_material_array_p(ob))) {
+ if (!ob || !(matar_obdata = BKE_object_material_array_p(ob))) {
return OPERATOR_CANCELLED;
}
+ BLI_assert(ob->totcol == *BKE_object_material_len_p(ob));
+
+ Material ***matar_object = &ob->mat;
+
+ Material **matar = MEM_callocN(sizeof(*matar) * (size_t)ob->totcol, __func__);
+ for (int i = ob->totcol; i--;) {
+ matar[i] = ob->matbits[i] ? (*matar_object)[i] : (*matar_obdata)[i];
+ }
+
CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
if (ob != ob_iter && BKE_object_material_array_p(ob_iter)) {
- if (ob->data != ob_iter->data) {
- BKE_object_material_array_assign(bmain, ob_iter, matar, ob->totcol);
- }
+ /* If we are using the same obdata, we only assign slots in ob_iter that are using object
+ * materials, and not obdata ones. */
+ const bool is_same_obdata = ob->data == ob_iter->data;
+ BKE_object_material_array_assign(bmain, ob_iter, &matar, ob->totcol, is_same_obdata);
if (ob_iter->totcol == ob->totcol) {
ob_iter->actcol = ob->actcol;
@@ -486,6 +496,8 @@ static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
}
CTX_DATA_END;
+ MEM_freeN(matar);
+
return OPERATOR_FINISHED;
}
@@ -564,6 +576,7 @@ void OBJECT_OT_material_slot_move(wmOperatorType *ot)
ot->description = "Move the active material up/down in the list";
/* api callbacks */
+ ot->poll = ED_operator_object_active_local_editable;
ot->exec = material_slot_move_exec;
/* flags */
@@ -638,7 +651,7 @@ void OBJECT_OT_material_slot_remove_unused(wmOperatorType *ot)
/* api callbacks */
ot->exec = material_slot_remove_unused_exec;
- ot->poll = ED_operator_object_active_editable;
+ ot->poll = ED_operator_object_active_local_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -707,6 +720,7 @@ void MATERIAL_OT_new(wmOperatorType *ot)
ot->description = "Add a new material";
/* api callbacks */
+ ot->poll = ED_operator_object_active_local_editable;
ot->exec = new_material_exec;
/* flags */
@@ -931,6 +945,11 @@ static int light_cache_bake_modal(bContext *C, wmOperator *op, const wmEvent *ev
/* no running blender, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
+ LightCache *lcache = scene->eevee.light_cache_data;
+ if (lcache && (lcache->flag & LIGHTCACHE_INVALID)) {
+ BKE_report(op->reports, RPT_ERROR, "Lightcache cannot allocate resources");
+ return OPERATOR_CANCELLED;
+ }
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
@@ -1666,13 +1685,13 @@ static int freestyle_get_modifier_type(PointerRNA *ptr)
if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier)) {
return LS_MODIFIER_TYPE_COLOR;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier)) {
+ if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier)) {
return LS_MODIFIER_TYPE_ALPHA;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier)) {
+ if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier)) {
return LS_MODIFIER_TYPE_THICKNESS;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier)) {
+ if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier)) {
return LS_MODIFIER_TYPE_GEOMETRY;
}
return -1;
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index a9c855b14b0..fd5963b217b 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -283,12 +283,12 @@ static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else if (sima->flag & SI_FULLWINDOW) {
+ if (sima->flag & SI_FULLWINDOW) {
sima->flag &= ~SI_FULLWINDOW;
ED_screen_state_toggle(C, win, area, SCREENMAXIMIZED);
return OPERATOR_FINISHED;
}
- else if (WM_window_is_temp_screen(win)) {
+ if (WM_window_is_temp_screen(win)) {
wm_window_close(C, CTX_wm_manager(C), win);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index a1fa5e2d655..fa63a890de7 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -133,8 +133,8 @@ static bool view_layer_remove_poll(const Scene *scene, const ViewLayer *layer)
if (act == -1) {
return false;
}
- else if ((scene->view_layers.first == scene->view_layers.last) &&
- (scene->view_layers.first == layer)) {
+ if ((scene->view_layers.first == scene->view_layers.last) &&
+ (scene->view_layers.first == layer)) {
/* ensure 1 layer is kept */
return false;
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index a182dd662af..9616b8114ba 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -135,7 +135,7 @@ static void region_draw_emboss(const ARegion *region, const rcti *scirct, int si
immUnbindProgram();
GPU_blend(false);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
}
void ED_region_pixelspace(ARegion *region)
@@ -357,12 +357,12 @@ static void region_draw_status_text(ScrArea *area, ARegion *region)
bool overlap = ED_region_is_overlap(area->spacetype, region->regiontype);
if (overlap) {
- GPU_clear_color(0.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
+ GPU_clear(GPU_COLOR_BIT);
}
else {
UI_ThemeClearColor(TH_HEADER);
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear(GPU_COLOR_BIT);
}
int fontid = BLF_set_default();
@@ -527,11 +527,11 @@ void ED_region_do_draw(bContext *C, ARegion *region)
if (area && area_is_pseudo_minimized(area)) {
UI_ThemeClearColor(TH_EDITOR_OUTLINE);
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear(GPU_COLOR_BIT);
return;
}
/* optional header info instead? */
- else if (region->headerstr) {
+ if (region->headerstr) {
region_draw_status_text(area, region);
}
else if (at->draw) {
@@ -813,7 +813,7 @@ void ED_workspace_status_text(bContext *C, const char *str)
/* ************************************************************ */
-static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea *area)
+static void area_azone_init(wmWindow *win, const bScreen *screen, ScrArea *area)
{
AZone *az;
@@ -883,7 +883,7 @@ static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea
}
}
-static void fullscreen_azone_initialize(ScrArea *area, ARegion *region)
+static void fullscreen_azone_init(ScrArea *area, ARegion *region)
{
AZone *az;
@@ -1007,10 +1007,10 @@ static bool region_azone_edge_poll(const ARegion *region, const bool is_fullscre
return true;
}
-static void region_azone_edge_initialize(ScrArea *area,
- ARegion *region,
- AZEdge edge,
- const bool is_fullscreen)
+static void region_azone_edge_init(ScrArea *area,
+ ARegion *region,
+ AZEdge edge,
+ const bool is_fullscreen)
{
AZone *az = NULL;
const bool is_hidden = (region->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL));
@@ -1033,9 +1033,9 @@ static void region_azone_edge_initialize(ScrArea *area,
}
}
-static void region_azone_scrollbar_initialize(ScrArea *area,
- ARegion *region,
- AZScrollDirection direction)
+static void region_azone_scrollbar_init(ScrArea *area,
+ ARegion *region,
+ AZScrollDirection direction)
{
rcti scroller_vert = (direction == AZ_SCROLL_VERT) ? region->v2d.vert : region->v2d.hor;
AZone *az = MEM_callocN(sizeof(*az), __func__);
@@ -1061,16 +1061,16 @@ static void region_azone_scrollbar_initialize(ScrArea *area,
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
-static void region_azones_scrollbars_initialize(ScrArea *area, ARegion *region)
+static void region_azones_scrollbars_init(ScrArea *area, ARegion *region)
{
const View2D *v2d = &region->v2d;
if ((v2d->scroll & V2D_SCROLL_VERTICAL) && ((v2d->scroll & V2D_SCROLL_VERTICAL_HANDLES) == 0)) {
- region_azone_scrollbar_initialize(area, region, AZ_SCROLL_VERT);
+ region_azone_scrollbar_init(area, region, AZ_SCROLL_VERT);
}
if ((v2d->scroll & V2D_SCROLL_HORIZONTAL) &&
((v2d->scroll & V2D_SCROLL_HORIZONTAL_HANDLES) == 0)) {
- region_azone_scrollbar_initialize(area, region, AZ_SCROLL_HOR);
+ region_azone_scrollbar_init(area, region, AZ_SCROLL_HOR);
}
}
@@ -1083,16 +1083,16 @@ static void region_azones_add_edge(ScrArea *area,
/* edge code (t b l r) is along which area edge azone will be drawn */
if (alignment == RGN_ALIGN_TOP) {
- region_azone_edge_initialize(area, region, AE_BOTTOM_TO_TOPLEFT, is_fullscreen);
+ region_azone_edge_init(area, region, AE_BOTTOM_TO_TOPLEFT, is_fullscreen);
}
else if (alignment == RGN_ALIGN_BOTTOM) {
- region_azone_edge_initialize(area, region, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen);
+ region_azone_edge_init(area, region, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen);
}
else if (alignment == RGN_ALIGN_RIGHT) {
- region_azone_edge_initialize(area, region, AE_LEFT_TO_TOPRIGHT, is_fullscreen);
+ region_azone_edge_init(area, region, AE_LEFT_TO_TOPRIGHT, is_fullscreen);
}
else if (alignment == RGN_ALIGN_LEFT) {
- region_azone_edge_initialize(area, region, AE_RIGHT_TO_TOPLEFT, is_fullscreen);
+ region_azone_edge_init(area, region, AE_RIGHT_TO_TOPLEFT, is_fullscreen);
}
}
@@ -1116,10 +1116,10 @@ static void region_azones_add(const bScreen *screen, ScrArea *area, ARegion *reg
}
if (is_fullscreen) {
- fullscreen_azone_initialize(area, region);
+ fullscreen_azone_init(area, region);
}
- region_azones_scrollbars_initialize(area, region);
+ region_azones_scrollbars_init(area, region);
}
/* dir is direction to check, not the splitting edge direction! */
@@ -1128,9 +1128,8 @@ static int rct_fits(const rcti *rect, char dir, int size)
if (dir == 'h') {
return BLI_rcti_size_x(rect) + 1 - size;
}
- else { /* 'v' */
- return BLI_rcti_size_y(rect) + 1 - size;
- }
+ /* 'v' */
+ return BLI_rcti_size_y(rect) + 1 - size;
}
/* *************************************************************** */
@@ -1176,18 +1175,14 @@ static void region_overlap_fix(ScrArea *area, ARegion *region)
region->flag |= RGN_FLAG_TOO_SMALL;
return;
}
- else {
- BLI_rcti_translate(&region->winrct, ar1->winx, 0);
- }
+ BLI_rcti_translate(&region->winrct, ar1->winx, 0);
}
else if (align1 == RGN_ALIGN_RIGHT) {
if (region->winrct.xmin - ar1->winx < U.widget_unit) {
region->flag |= RGN_FLAG_TOO_SMALL;
return;
}
- else {
- BLI_rcti_translate(&region->winrct, -ar1->winx, 0);
- }
+ BLI_rcti_translate(&region->winrct, -ar1->winx, 0);
}
}
@@ -1833,7 +1828,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0);
/* Dynamically sized regions may have changed region sizes, so we have to force azone update. */
- area_azone_initialize(win, screen, area);
+ area_azone_init(win, screen, area);
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
region_subwindow(region);
@@ -1852,7 +1847,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
}
/* called in screen_refresh, or screens_init, also area size changes */
-void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *area)
+void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
{
WorkSpace *workspace = WM_window_get_active_workspace(win);
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
@@ -1895,7 +1890,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *area)
}
/* clear all azones, add the area triangle widgets */
- area_azone_initialize(win, screen, area);
+ area_azone_init(win, screen, area);
/* region windows, default and own handlers */
for (region = area->regionbase.first; region; region = region->next) {
@@ -1949,7 +1944,7 @@ void ED_region_update_rect(ARegion *region)
}
/* externally called for floating regions like menus */
-void ED_region_floating_initialize(ARegion *region)
+void ED_region_floating_init(ARegion *region)
{
BLI_assert(region->alignment == RGN_ALIGN_FLOAT);
@@ -1985,7 +1980,7 @@ void ED_region_visibility_change_update(bContext *C, ScrArea *area, ARegion *reg
WM_event_remove_handlers(C, &region->handlers);
}
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), area);
+ ED_area_init(CTX_wm_manager(C), CTX_wm_window(C), area);
ED_area_tag_redraw(area);
}
@@ -2071,8 +2066,8 @@ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2)
ED_area_data_copy(tmp, sa1, false);
ED_area_data_copy(sa1, sa2, true);
ED_area_data_copy(sa2, tmp, true);
- ED_area_initialize(CTX_wm_manager(C), win, sa1);
- ED_area_initialize(CTX_wm_manager(C), win, sa2);
+ ED_area_init(CTX_wm_manager(C), win, sa1);
+ ED_area_init(CTX_wm_manager(C), win, sa2);
BKE_screen_area_free(tmp);
MEM_freeN(tmp);
@@ -2131,7 +2126,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
area->spacetype = type;
area->type = st;
- /* If st->new may be called, don't use context until then. The
+ /* If st->create may be called, don't use context until then. The
* area->type->context() callback has changed but data may be invalid
* (e.g. with properties editor) until space-data is properly created */
@@ -2171,7 +2166,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
if (st) {
/* Don't get scene from context here which may depend on space-data. */
Scene *scene = WM_window_get_active_scene(win);
- sl = st->new (area, scene);
+ sl = st->create(area, scene);
BLI_addhead(&area->spacedata, sl);
/* swap regions */
@@ -2209,7 +2204,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
}
}
- ED_area_initialize(CTX_wm_manager(C), win, area);
+ ED_area_init(CTX_wm_manager(C), win, area);
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(win);
@@ -3014,7 +3009,7 @@ ScrArea *ED_screen_areas_iter_first(const wmWindow *win, const bScreen *screen)
if (!global_area) {
return screen->areabase.first;
}
- else if ((global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) == 0) {
+ if ((global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) == 0) {
return global_area;
}
/* Find next visible area. */
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 8df1172dda1..07a122c7094 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -39,6 +39,7 @@
#include "GPU_immediate.h"
#include "GPU_matrix.h"
+#include "GPU_texture.h"
#ifdef __APPLE__
# include "GPU_state.h"
@@ -48,30 +49,6 @@
/* ******************************************** */
-static int get_cached_work_texture(int *r_w, int *r_h)
-{
- static GLint texid = -1;
- static int tex_w = 256;
- static int tex_h = 256;
-
- if (texid == -1) {
- glGenTextures(1, (GLuint *)&texid);
-
- glBindTexture(GL_TEXTURE_2D, texid);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- }
-
- *r_w = tex_w;
- *r_h = tex_h;
- return texid;
-}
-
static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state)
{
GPUVertFormat *vert_format = immVertexFormat();
@@ -118,9 +95,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
@@ -132,61 +108,45 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float yzoom,
float color[4])
{
- uchar *uc_rect = (uchar *)rect;
- const float *f_rect = (float *)rect;
- int subpart_x, subpart_y, tex_w, tex_h;
+ int subpart_x, subpart_y, tex_w = 256, tex_h = 256;
int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y;
- int texid = get_cached_work_texture(&tex_w, &tex_h);
int components;
const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y));
float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- GLint unpack_row_length;
- glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length);
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texid);
- glBindSampler(0, 0);
-
- /* don't want nasty border artifacts */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, zoomfilter);
-
- /* setup seamless 2=on, 0=off */
- seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0;
-
- offset_x = tex_w - seamless;
- offset_y = tex_h - seamless;
-
- nsubparts_x = (img_w + (offset_x - 1)) / (offset_x);
- nsubparts_y = (img_h + (offset_y - 1)) / (offset_y);
-
- if (format == GL_RGBA) {
+ if (ELEM(gpu_format, GPU_RGBA8, GPU_RGBA16F)) {
components = 4;
}
- else if (format == GL_RGB) {
+ else if (ELEM(gpu_format, GPU_RGB16F)) {
components = 3;
}
- else if (format == GL_RED) {
+ else if (ELEM(gpu_format, GPU_R8, GPU_R16F)) {
components = 1;
}
else {
- BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled");
+ BLI_assert(!"Incompatible format passed to immDrawPixels");
return;
}
- if (type == GL_FLOAT) {
- /* need to set internal format to higher range float */
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, tex_w, tex_h, 0, format, GL_FLOAT, NULL);
- }
- else {
- /* switch to 8bit RGBA for byte buffer */
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, format, GL_UNSIGNED_BYTE, NULL);
- }
+ const bool use_float_data = ELEM(gpu_format, GPU_RGBA16F, GPU_RGB16F, GPU_R16F);
+ eGPUDataFormat gpu_data = (use_float_data) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+ size_t stride = components * ((use_float_data) ? sizeof(float) : sizeof(uchar));
- uint pos = state->pos, texco = state->texco;
+ GPUTexture *tex = GPU_texture_create_2d(tex_w, tex_h, gpu_format, NULL, NULL);
+
+ GPU_texture_filter_mode(tex, use_filter);
+ GPU_texture_wrap_mode(tex, false, true);
+
+ GPU_texture_bind(tex, 0);
+
+ /* setup seamless 2=on, 0=off */
+ seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0;
+
+ offset_x = tex_w - seamless;
+ offset_y = tex_h - seamless;
+
+ nsubparts_x = (img_w + (offset_x - 1)) / (offset_x);
+ nsubparts_y = (img_h + (offset_y - 1)) / (offset_y);
/* optional */
/* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since
@@ -196,6 +156,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
immUniformColor4fv((color) ? color : white);
}
+ GPU_unpack_row_length_set(img_w);
+
for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) {
for (subpart_x = 0; subpart_x < nsubparts_x; subpart_x++) {
int remainder_x = img_w - subpart_x * offset_x;
@@ -213,141 +175,68 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
continue;
}
+ int right = subpart_w - offset_right;
+ int top = subpart_h - offset_top;
+ int bottom = 0 + offset_bot;
+ int left = 0 + offset_left;
+
if (use_clipping) {
- if (rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX < clip_min_x ||
- rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY < clip_min_y) {
+ if (rast_x + right * xzoom * scaleX < clip_min_x ||
+ rast_y + top * yzoom * scaleY < clip_min_y) {
continue;
}
- if (rast_x + (float)offset_left * xzoom > clip_max_x ||
- rast_y + (float)offset_bot * yzoom > clip_max_y) {
+ if (rast_x + left * xzoom > clip_max_x || rast_y + bottom * yzoom > clip_max_y) {
continue;
}
}
- if (type == GL_FLOAT) {
- glTexSubImage2D(GL_TEXTURE_2D,
- 0,
- 0,
- 0,
- subpart_w,
- subpart_h,
- format,
- GL_FLOAT,
- &f_rect[((size_t)subpart_y) * offset_y * img_w * components +
- subpart_x * offset_x * components]);
-
- /* add an extra border of pixels so linear looks ok at edges of full image */
- if (subpart_w < tex_w) {
- glTexSubImage2D(GL_TEXTURE_2D,
- 0,
- subpart_w,
- 0,
- 1,
- subpart_h,
- format,
- GL_FLOAT,
- &f_rect[((size_t)subpart_y) * offset_y * img_w * components +
- (subpart_x * offset_x + subpart_w - 1) * components]);
- }
- if (subpart_h < tex_h) {
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- 0,
- subpart_h,
- subpart_w,
- 1,
- format,
- GL_FLOAT,
- &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components +
- subpart_x * offset_x * components]);
- }
- if (subpart_w < tex_w && subpart_h < tex_h) {
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- subpart_w,
- subpart_h,
- 1,
- 1,
- format,
- GL_FLOAT,
- &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components +
- (subpart_x * offset_x + subpart_w - 1) * components]);
- }
- }
- else {
- glTexSubImage2D(GL_TEXTURE_2D,
- 0,
- 0,
- 0,
- subpart_w,
- subpart_h,
- format,
- GL_UNSIGNED_BYTE,
- &uc_rect[((size_t)subpart_y) * offset_y * img_w * components +
- subpart_x * offset_x * components]);
+ {
+ int src_y = subpart_y * offset_y;
+ int src_x = subpart_x * offset_x;
+#define DATA(_y, _x) ((char *)rect + stride * ((size_t)(_y)*img_w + (_x)))
+ {
+ void *data = DATA(src_y, src_x);
+ GPU_texture_update_sub(tex, gpu_data, data, 0, 0, 0, subpart_w, subpart_h, 0);
+ }
+ /* Add an extra border of pixels so linear interpolation looks ok
+ * at edges of full image. */
if (subpart_w < tex_w) {
- glTexSubImage2D(GL_TEXTURE_2D,
- 0,
- subpart_w,
- 0,
- 1,
- subpart_h,
- format,
- GL_UNSIGNED_BYTE,
- &uc_rect[((size_t)subpart_y) * offset_y * img_w * components +
- (subpart_x * offset_x + subpart_w - 1) * components]);
+ void *data = DATA(src_y, src_x + subpart_w - 1);
+ int offset[2] = {subpart_w, 0};
+ int extent[2] = {1, subpart_h};
+ GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0);
}
if (subpart_h < tex_h) {
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- 0,
- subpart_h,
- subpart_w,
- 1,
- format,
- GL_UNSIGNED_BYTE,
- &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components +
- subpart_x * offset_x * components]);
+ void *data = DATA(src_y + subpart_h - 1, src_x);
+ int offset[2] = {0, subpart_h};
+ int extent[2] = {subpart_w, 1};
+ GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0);
}
+
if (subpart_w < tex_w && subpart_h < tex_h) {
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- subpart_w,
- subpart_h,
- 1,
- 1,
- format,
- GL_UNSIGNED_BYTE,
- &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components +
- (subpart_x * offset_x + subpart_w - 1) * components]);
+ void *data = DATA(src_y + subpart_h - 1, src_x + subpart_w - 1);
+ int offset[2] = {subpart_w, subpart_h};
+ int extent[2] = {1, 1};
+ GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0);
}
+#undef DATA
}
+ uint pos = state->pos, texco = state->texco;
+
immBegin(GPU_PRIM_TRI_FAN, 4);
- immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h);
- immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom);
-
- immAttr2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h);
- immVertex2f(pos,
- rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX,
- rast_y + (float)offset_bot * yzoom);
-
- immAttr2f(texco,
- (float)(subpart_w - offset_right) / tex_w,
- (float)(subpart_h - offset_top) / tex_h);
- immVertex2f(pos,
- rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX,
- rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
-
- immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(subpart_h - offset_top) / tex_h);
- immVertex2f(pos,
- rast_x + (float)offset_left * xzoom,
- rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
+ immAttr2f(texco, left / (float)tex_w, bottom / (float)tex_h);
+ immVertex2f(pos, rast_x + offset_left * xzoom, rast_y + offset_bot * yzoom);
+
+ immAttr2f(texco, right / (float)tex_w, bottom / (float)tex_h);
+ immVertex2f(pos, rast_x + right * xzoom * scaleX, rast_y + offset_bot * yzoom);
+
+ immAttr2f(texco, right / (float)tex_w, top / (float)tex_h);
+ immVertex2f(pos, rast_x + right * xzoom * scaleX, rast_y + top * yzoom * scaleY);
+
+ immAttr2f(texco, left / (float)tex_w, top / (float)tex_h);
+ immVertex2f(pos, rast_x + offset_left * xzoom, rast_y + top * yzoom * scaleY);
immEnd();
/* NOTE: Weirdly enough this is only required on macOS. Without this there is some sort of
@@ -364,8 +253,11 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
immUnbindProgram();
}
- glBindTexture(GL_TEXTURE_2D, 0);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length);
+ GPU_texture_unbind(tex);
+ GPU_texture_free(tex);
+
+ /* Restore default. */
+ GPU_unpack_row_length_set(0);
}
void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
@@ -373,9 +265,8 @@ void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
@@ -388,9 +279,8 @@ void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
y,
img_w,
img_h,
- format,
- type,
- zoomfilter,
+ gpu_format,
+ use_filter,
rect,
scaleX,
scaleY,
@@ -408,9 +298,8 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float xzoom,
float yzoom,
@@ -421,9 +310,8 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state,
y,
img_w,
img_h,
- format,
- type,
- zoomfilter,
+ gpu_format,
+ use_filter,
rect,
1.0f,
1.0f,
@@ -441,9 +329,8 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float clip_min_x,
float clip_min_y,
@@ -458,9 +345,8 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
y,
img_w,
img_h,
- format,
- type,
- zoomfilter,
+ gpu_format,
+ use_filter,
rect,
1.0f,
1.0f,
@@ -473,76 +359,13 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
color);
}
-/* *************** glPolygonOffset hack ************* */
-
-float bglPolygonOffsetCalc(const float winmat[16], float viewdist, float dist)
-{
- /* Seems like we have a factor of 2 more offset than 2.79 for some reason. Correct for this. */
- dist *= 0.5f;
-
- if (winmat[15] > 0.5f) {
-#if 1
- return 0.00001f * dist * viewdist; // ortho tweaking
-#else
- static float depth_fac = 0.0f;
- if (depth_fac == 0.0f) {
- int depthbits;
- glGetIntegerv(GL_DEPTH_BITS, &depthbits);
- depth_fac = 1.0f / (float)((1 << depthbits) - 1);
- }
- offs = (-1.0 / winmat[10]) * dist * depth_fac;
-
- UNUSED_VARS(viewdist);
-#endif
- }
- else {
- /* This adjustment effectively results in reducing the Z value by 0.25%.
- *
- * winmat[14] actually evaluates to `-2 * far * near / (far - near)`,
- * is very close to -0.2 with default clip range,
- * and is used as the coefficient multiplied by `w / z`,
- * thus controlling the z dependent part of the depth value.
- */
- return winmat[14] * -0.0025f * dist;
- }
-}
-
-/**
- * \note \a viewdist is only for ortho at the moment.
- */
-void bglPolygonOffset(float viewdist, float dist)
-{
- static float winmat[16], offset = 0.0f;
-
- if (dist != 0.0f) {
- // glEnable(GL_POLYGON_OFFSET_FILL);
- // glPolygonOffset(-1.0, -1.0);
-
- /* hack below is to mimic polygon offset */
- GPU_matrix_projection_get(winmat);
-
- /* dist is from camera to center point */
-
- float offs = bglPolygonOffsetCalc(winmat, viewdist, dist);
-
- winmat[14] -= offs;
- offset += offs;
- }
- else {
- winmat[14] += offset;
- offset = 0.0;
- }
-
- GPU_matrix_projection_set(winmat);
-}
-
/* **** Color management helper functions for GLSL display/transform ***** */
/* Draw given image buffer on a screen using GLSL for display transform */
void ED_draw_imbuf_clipping(ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
ColorManagedViewSettings *view_settings,
ColorManagedDisplaySettings *display_settings,
float clip_min_x,
@@ -592,13 +415,13 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
if (ok) {
if (ibuf->rect_float) {
- int format = 0;
+ eGPUTextureFormat format = 0;
if (ibuf->channels == 3) {
- format = GL_RGB;
+ format = GPU_RGB16F;
}
else if (ibuf->channels == 4) {
- format = GL_RGBA;
+ format = GPU_RGBA16F;
}
else {
BLI_assert(!"Incompatible number of channels for GLSL display");
@@ -611,8 +434,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
ibuf->x,
ibuf->y,
format,
- GL_FLOAT,
- zoomfilter,
+ use_filter,
ibuf->rect_float,
clip_min_x,
clip_min_y,
@@ -630,9 +452,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- zoomfilter,
+ GPU_RGBA8,
+ use_filter,
ibuf->rect,
clip_min_x,
clip_min_y,
@@ -664,9 +485,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- zoomfilter,
+ GPU_RGBA8,
+ use_filter,
display_buffer,
clip_min_x,
clip_min_y,
@@ -684,7 +504,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
void ED_draw_imbuf(ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
ColorManagedViewSettings *view_settings,
ColorManagedDisplaySettings *display_settings,
float zoom_x,
@@ -693,7 +513,7 @@ void ED_draw_imbuf(ImBuf *ibuf,
ED_draw_imbuf_clipping(ibuf,
x,
y,
- zoomfilter,
+ use_filter,
view_settings,
display_settings,
0.0f,
@@ -708,7 +528,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C,
ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
float clip_min_x,
float clip_min_y,
float clip_max_x,
@@ -724,7 +544,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C,
ED_draw_imbuf_clipping(ibuf,
x,
y,
- zoomfilter,
+ use_filter,
view_settings,
display_settings,
clip_min_x,
@@ -736,9 +556,9 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C,
}
void ED_draw_imbuf_ctx(
- const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter, float zoom_x, float zoom_y)
+ const bContext *C, ImBuf *ibuf, float x, float y, bool use_filter, float zoom_x, float zoom_y)
{
- ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
+ ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, use_filter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
}
int ED_draw_imbuf_method(ImBuf *ibuf)
@@ -752,9 +572,7 @@ int ED_draw_imbuf_method(ImBuf *ibuf)
return (size > threshold) ? IMAGE_DRAW_METHOD_2DTEXTURE : IMAGE_DRAW_METHOD_GLSL;
}
- else {
- return U.image_draw_method;
- }
+ return U.image_draw_method;
}
/* don't move to GPU_immediate_util.h because this uses user-prefs
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 3202dc68f37..c17a34f97b9 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -125,11 +125,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_dir_set(result, screen_context_dir);
return 1;
}
- else if (CTX_data_equals(member, "scene")) {
+ if (CTX_data_equals(member, "scene")) {
CTX_data_id_pointer_set(result, &scene->id);
return 1;
}
- else if (CTX_data_equals(member, "visible_objects")) {
+ if (CTX_data_equals(member, "visible_objects")) {
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
if (BASE_VISIBLE(v3d, base)) {
CTX_data_id_list_add(result, &base->object->id);
@@ -138,7 +138,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "selectable_objects")) {
+ if (CTX_data_equals(member, "selectable_objects")) {
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
if (BASE_SELECTABLE(v3d, base)) {
CTX_data_id_list_add(result, &base->object->id);
@@ -147,7 +147,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "selected_objects")) {
+ if (CTX_data_equals(member, "selected_objects")) {
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
if (BASE_SELECTED(v3d, base)) {
CTX_data_id_list_add(result, &base->object->id);
@@ -156,7 +156,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "selected_editable_objects")) {
+ if (CTX_data_equals(member, "selected_editable_objects")) {
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
if (BASE_SELECTED_EDITABLE(v3d, base)) {
CTX_data_id_list_add(result, &base->object->id);
@@ -165,7 +165,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "editable_objects")) {
+ if (CTX_data_equals(member, "editable_objects")) {
/* Visible + Editable, but not necessarily selected */
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
if (BASE_EDITABLE(v3d, base)) {
@@ -175,7 +175,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "objects_in_mode")) {
+ if (CTX_data_equals(member, "objects_in_mode")) {
if (obact && (obact->mode != OB_MODE_OBJECT)) {
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
CTX_data_id_list_add(result, &ob_iter->id);
@@ -185,7 +185,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "objects_in_mode_unique_data")) {
+ if (CTX_data_equals(member, "objects_in_mode_unique_data")) {
if (obact && (obact->mode != OB_MODE_OBJECT)) {
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
ob_iter->id.tag |= LIB_TAG_DOIT;
@@ -202,7 +202,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
+ if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
EditBone *ebone, *flipbone = NULL;
const bool editable_bones = CTX_data_equals(member, "editable_bones");
@@ -257,9 +257,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "selected_bones") ||
- CTX_data_equals(member, "selected_editable_bones")) {
+ if (CTX_data_equals(member, "selected_bones") ||
+ CTX_data_equals(member, "selected_editable_bones")) {
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");
@@ -314,8 +315,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "visible_pose_bones")) {
+ if (CTX_data_equals(member, "visible_pose_bones")) {
Object *obpose = BKE_object_pose_armature_get(obact);
if (obpose && obpose->pose && obpose->data) {
if (obpose != obact) {
@@ -336,8 +338,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "selected_pose_bones")) {
+ if (CTX_data_equals(member, "selected_pose_bones")) {
Object *obpose = BKE_object_pose_armature_get(obact);
if (obpose && obpose->pose && obpose->data) {
if (obpose != obact) {
@@ -358,8 +361,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "selected_pose_bones_from_active_object")) {
+ if (CTX_data_equals(member, "selected_pose_bones_from_active_object")) {
Object *obpose = BKE_object_pose_armature_get(obact);
if (obpose && obpose->pose && obpose->data) {
if (obpose != obact) {
@@ -377,8 +381,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "active_bone")) {
+ if (CTX_data_equals(member, "active_bone")) {
if (obact && obact->type == OB_ARMATURE) {
bArmature *arm = obact->data;
if (arm->edbo) {
@@ -394,8 +399,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
}
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "active_pose_bone")) {
+ if (CTX_data_equals(member, "active_pose_bone")) {
bPoseChannel *pchan;
Object *obpose = BKE_object_pose_armature_get(obact);
@@ -404,22 +410,23 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "active_object")) {
+ if (CTX_data_equals(member, "active_object")) {
if (obact) {
CTX_data_id_pointer_set(result, &obact->id);
}
return 1;
}
- else if (CTX_data_equals(member, "object")) {
+ if (CTX_data_equals(member, "object")) {
if (obact) {
CTX_data_id_pointer_set(result, &obact->id);
}
return 1;
}
- else if (CTX_data_equals(member, "edit_object")) {
+ if (CTX_data_equals(member, "edit_object")) {
/* convenience for now, 1 object per scene in editmode */
if (obedit) {
CTX_data_id_pointer_set(result, &obedit->id);
@@ -427,49 +434,49 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
- else if (CTX_data_equals(member, "sculpt_object")) {
+ if (CTX_data_equals(member, "sculpt_object")) {
if (obact && (obact->mode & OB_MODE_SCULPT)) {
CTX_data_id_pointer_set(result, &obact->id);
}
return 1;
}
- else if (CTX_data_equals(member, "vertex_paint_object")) {
+ if (CTX_data_equals(member, "vertex_paint_object")) {
if (obact && (obact->mode & OB_MODE_VERTEX_PAINT)) {
CTX_data_id_pointer_set(result, &obact->id);
}
return 1;
}
- else if (CTX_data_equals(member, "weight_paint_object")) {
+ if (CTX_data_equals(member, "weight_paint_object")) {
if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT)) {
CTX_data_id_pointer_set(result, &obact->id);
}
return 1;
}
- else if (CTX_data_equals(member, "image_paint_object")) {
+ if (CTX_data_equals(member, "image_paint_object")) {
if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) {
CTX_data_id_pointer_set(result, &obact->id);
}
return 1;
}
- else if (CTX_data_equals(member, "particle_edit_object")) {
+ if (CTX_data_equals(member, "particle_edit_object")) {
if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) {
CTX_data_id_pointer_set(result, &obact->id);
}
return 1;
}
- else if (CTX_data_equals(member, "pose_object")) {
+ if (CTX_data_equals(member, "pose_object")) {
Object *obpose = BKE_object_pose_armature_get(obact);
if (obpose) {
CTX_data_id_pointer_set(result, &obpose->id);
}
return 1;
}
- else if (CTX_data_equals(member, "sequences")) {
+ if (CTX_data_equals(member, "sequences")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
Sequence *seq;
@@ -479,8 +486,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "selected_sequences")) {
+ if (CTX_data_equals(member, "selected_sequences")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
Sequence *seq;
@@ -492,8 +500,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "selected_editable_sequences")) {
+ if (CTX_data_equals(member, "selected_editable_sequences")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
Sequence *seq;
@@ -505,8 +514,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "selected_nla_strips")) {
+ if (CTX_data_equals(member, "selected_nla_strips")) {
bAnimContext ac;
if (ANIM_animdata_get_context(C, &ac) != 0) {
ListBase anim_data = {NULL, NULL};
@@ -530,8 +540,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "gpencil_data")) {
+ 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 called from context.
@@ -543,8 +554,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_id_pointer_set(result, &gpd->id);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "gpencil_data_owner")) {
+ 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). */
bGPdata **gpd_ptr = NULL;
@@ -557,16 +569,18 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "annotation_data")) {
+ if (CTX_data_equals(member, "annotation_data")) {
bGPdata *gpd = ED_annotation_data_get_active_direct((ID *)screen, area, scene);
if (gpd) {
CTX_data_id_pointer_set(result, &gpd->id);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "annotation_data_owner")) {
+ if (CTX_data_equals(member, "annotation_data_owner")) {
/* Pointer to which data/datablock owns the reference to the Grease Pencil data being used. */
bGPdata **gpd_ptr = NULL;
PointerRNA ptr;
@@ -578,8 +592,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "active_gpencil_layer")) {
+ if (CTX_data_equals(member, "active_gpencil_layer")) {
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
@@ -590,8 +605,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "active_annotation_layer")) {
+ if (CTX_data_equals(member, "active_annotation_layer")) {
bGPdata *gpd = ED_annotation_data_get_active_direct((ID *)screen, area, scene);
if (gpd) {
@@ -602,8 +618,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "active_gpencil_frame")) {
+ if (CTX_data_equals(member, "active_gpencil_frame")) {
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
@@ -614,8 +631,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "visible_gpencil_layers")) {
+ if (CTX_data_equals(member, "visible_gpencil_layers")) {
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
@@ -629,8 +647,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "editable_gpencil_layers")) {
+ if (CTX_data_equals(member, "editable_gpencil_layers")) {
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
@@ -644,8 +663,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "editable_gpencil_strokes")) {
+ if (CTX_data_equals(member, "editable_gpencil_strokes")) {
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
@@ -684,8 +704,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "active_operator")) {
+ if (CTX_data_equals(member, "active_operator")) {
wmOperator *op = NULL;
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -706,11 +727,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_pointer_set(result, NULL, &RNA_Operator, op);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "editable_fcurves") ||
- CTX_data_equals(member, "visible_fcurves") ||
- CTX_data_equals(member, "selected_editable_fcurves") ||
- CTX_data_equals(member, "selected_visible_fcurves")) {
+ if (CTX_data_equals(member, "editable_fcurves") || CTX_data_equals(member, "visible_fcurves") ||
+ CTX_data_equals(member, "selected_editable_fcurves") ||
+ CTX_data_equals(member, "selected_visible_fcurves")) {
bAnimContext ac;
if (ANIM_animdata_get_context(C, &ac) && ELEM(ac.spacetype, SPACE_ACTION, SPACE_GRAPH)) {
@@ -740,8 +761,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "active_editable_fcurve")) {
+ if (CTX_data_equals(member, "active_editable_fcurve")) {
bAnimContext ac;
if (ANIM_animdata_get_context(C, &ac) && ELEM(ac.spacetype, SPACE_GRAPH)) {
@@ -762,10 +784,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
ANIM_animdata_freelist(&anim_data);
return 1;
}
- }
- else {
- return 0; /* not found */
+ return -1; /* found but not available */
}
- return -1; /* found but not available */
+ return 0; /* not found */
}
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index 3700deb8d77..40a452a5363 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -404,7 +404,7 @@ void ED_screen_draw_edges(wmWindow *win)
/* It seems that all areas gets smaller when pixelsize is > 1.
* So in order to avoid missing pixels we just disable de scissors. */
if (U.pixelsize <= 1.0f) {
- glEnable(GL_SCISSOR_TEST);
+ GPU_scissor_test(true);
}
UI_GetThemeColor4fv(TH_EDITOR_OUTLINE, col);
@@ -429,7 +429,7 @@ void ED_screen_draw_edges(wmWindow *win)
GPU_blend(false);
if (U.pixelsize <= 1.0f) {
- glDisable(GL_SCISSOR_TEST);
+ GPU_scissor_test(false);
}
}
@@ -619,7 +619,7 @@ void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, uin
screen_preview_draw(screen, size_x, size_y);
- GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect);
+ GPU_offscreen_read_pixels(offscreen, GPU_DATA_UNSIGNED_BYTE, r_rect);
GPU_offscreen_unbind(offscreen, true);
GPU_offscreen_free(offscreen);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index b6f210d7f13..62720d8ca37 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -516,7 +516,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
ED_screen_areas_iter (win, screen, area) {
/* set spacetype and region callbacks, calls init() */
/* sets subwindows for regions, adds handlers */
- ED_area_initialize(wm, win, area);
+ ED_area_init(wm, win, area);
}
/* wake up animtimer */
@@ -536,7 +536,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
}
/* file read, set all screens, ... */
-void ED_screens_initialize(Main *bmain, wmWindowManager *wm)
+void ED_screens_init(Main *bmain, wmWindowManager *wm)
{
wmWindow *win;
@@ -897,7 +897,7 @@ static void screen_global_area_refresh(wmWindow *win,
else {
area = screen_area_create_with_geometry(&win->global_areas, rect, space_type);
SpaceType *stype = BKE_spacetype_from_id(space_type);
- SpaceLink *slink = stype->new (area, WM_window_get_active_scene(win));
+ SpaceLink *slink = stype->create(area, WM_window_get_active_scene(win));
area->regionbase = slink->regionbase;
@@ -985,39 +985,14 @@ void ED_screen_global_areas_refresh(wmWindow *win)
/* -------------------------------------------------------------------- */
/* Screen changing */
-static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen)
-{
- for (bScreen *screen_iter = bmain->screens.first; screen_iter;
- screen_iter = screen_iter->id.next) {
- if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) {
- ScrArea *area = screen_iter->areabase.first;
- if (area && area->full == screen) {
- return screen_iter;
- }
- }
- }
-
- return screen;
-}
-
/**
* \return the screen to activate.
* \warning The returned screen may not always equal \a screen_new!
*/
-bScreen *screen_change_prepare(
+void screen_change_prepare(
bScreen *screen_old, bScreen *screen_new, Main *bmain, bContext *C, wmWindow *win)
{
- /* validate screen, it's called with notifier reference */
- if (BLI_findindex(&bmain->screens, screen_new) == -1) {
- return NULL;
- }
-
- screen_new = screen_fullscreen_find_associated_normal_screen(bmain, screen_new);
-
- /* check for valid winid */
- if (!(screen_new->winid == 0 || screen_new->winid == win->winid)) {
- return NULL;
- }
+ BLI_assert(BLI_findindex(&bmain->screens, screen_new) != -1);
if (screen_old != screen_new) {
wmTimer *wt = screen_old->animtimer;
@@ -1038,11 +1013,7 @@ bScreen *screen_change_prepare(
if (wt) {
screen_new->animtimer = wt;
}
-
- return screen_new;
}
-
- return NULL;
}
void screen_change_update(bContext *C, wmWindow *win, bScreen *screen)
@@ -1075,12 +1046,20 @@ bool ED_screen_change(bContext *C, bScreen *screen)
{
Main *bmain = CTX_data_main(C);
wmWindow *win = CTX_wm_window(C);
+ WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
+ WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, screen);
bScreen *screen_old = CTX_wm_screen(C);
- bScreen *screen_new = screen_change_prepare(screen_old, screen, bmain, C, win);
- if (screen_new) {
- WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
- WM_window_set_active_screen(win, workspace, screen);
+ /* Get the actual layout/screen to be activated (guaranteed to be unused, even if that means
+ * having to duplicate an existing one). */
+ WorkSpaceLayout *layout_new = ED_workspace_screen_change_ensure_unused_layout(
+ bmain, workspace, layout, layout, win);
+ bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new);
+
+ screen_change_prepare(screen_old, screen_new, bmain, C, win);
+
+ if (screen_old != screen_new) {
+ WM_window_set_active_screen(win, workspace, screen_new);
screen_change_update(C, win, screen_new);
return true;
diff --git a/source/blender/editors/screen/screen_geometry.c b/source/blender/editors/screen/screen_geometry.c
index 47580c2f4b3..0b83a657265 100644
--- a/source/blender/editors/screen/screen_geometry.c
+++ b/source/blender/editors/screen/screen_geometry.c
@@ -327,27 +327,26 @@ short screen_geom_find_area_split_point(const ScrArea *area,
return y;
}
- else {
- x = area->v1->vec.x + round_fl_to_short(fac * cur_area_width);
- area_min = area_min_x;
+ x = area->v1->vec.x + round_fl_to_short(fac * cur_area_width);
- if (area->v1->vec.x > window_rect->xmin) {
- area_min += U.pixelsize;
- }
- if (area->v4->vec.x < (window_rect->xmax - 1)) {
- area_min += U.pixelsize;
- }
+ area_min = area_min_x;
- if (x - area->v1->vec.x < area_min) {
- x = area->v1->vec.x + area_min;
- }
- else if (area->v4->vec.x - x < area_min) {
- x = area->v4->vec.x - area_min;
- }
+ if (area->v1->vec.x > window_rect->xmin) {
+ area_min += U.pixelsize;
+ }
+ if (area->v4->vec.x < (window_rect->xmax - 1)) {
+ area_min += U.pixelsize;
+ }
- return x;
+ if (x - area->v1->vec.x < area_min) {
+ x = area->v1->vec.x + area_min;
}
+ else if (area->v4->vec.x - x < area_min) {
+ x = area->v4->vec.x - area_min;
+ }
+
+ return x;
}
/**
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index 2d42313d528..a5b5e222ae9 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -21,8 +21,7 @@
* \ingroup edscr
*/
-#ifndef __SCREEN_INTERN_H__
-#define __SCREEN_INTERN_H__
+#pragma once
struct Main;
struct bContext;
@@ -50,11 +49,11 @@ 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 *screen);
-bScreen *screen_change_prepare(bScreen *screen_old,
- bScreen *screen_new,
- struct Main *bmain,
- struct bContext *C,
- wmWindow *win);
+void screen_change_prepare(bScreen *screen_old,
+ bScreen *screen_new,
+ struct Main *bmain,
+ struct bContext *C,
+ wmWindow *win);
ScrArea *area_split(
const wmWindow *win, bScreen *screen, ScrArea *area, char dir, float fac, int merge);
int screen_area_join(struct bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2);
@@ -97,5 +96,3 @@ void SCREEN_OT_screenshot(struct wmOperatorType *ot);
/* workspace_layout_edit.c */
bool workspace_layout_set_poll(const struct WorkSpaceLayout *layout);
-
-#endif /* __SCREEN_INTERN_H__ */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 5de8ccd404d..f4d36a15d30 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -89,6 +89,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "GPU_extensions.h"
+
#include "screen_intern.h" /* own module include */
#define KM_MODAL_CANCEL 1
@@ -260,9 +262,7 @@ bool ED_operator_outliner_active_no_editobject(bContext *C)
if (ob && ob == obedit) {
return 0;
}
- else {
- return 1;
- }
+ return 1;
}
return 0;
}
@@ -362,6 +362,13 @@ bool ED_operator_object_active_editable(bContext *C)
return ED_operator_object_active_editable_ex(C, ob);
}
+/** Object must be editable and fully local (i.e. not an override). */
+bool ED_operator_object_active_local_editable(bContext *C)
+{
+ Object *ob = ED_object_active_context(C);
+ return ED_operator_object_active_editable_ex(C, ob) && !ID_IS_OVERRIDE_LIBRARY(ob);
+}
+
bool ED_operator_object_active_editable_mesh(bContext *C)
{
Object *ob = ED_object_active_context(C);
@@ -762,10 +769,10 @@ static AZone *area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const b
if (az->type == AZONE_AREA) {
break;
}
- else if (az->type == AZONE_REGION) {
+ if (az->type == AZONE_REGION) {
break;
}
- else if (az->type == AZONE_FULLSCREEN) {
+ if (az->type == AZONE_FULLSCREEN) {
rcti click_rect;
fullscreen_click_rcti_init(&click_rect, az->x1, az->y1, az->x2, az->y2);
const bool click_isect = BLI_rcti_isect_pt_v(&click_rect, xy);
@@ -997,14 +1004,13 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
actionzone_exit(op);
return OPERATOR_FINISHED;
}
- else {
- BLI_assert(ELEM(sad->az->type, AZONE_AREA, AZONE_REGION_SCROLL));
- /* add modal handler */
- G.moving |= G_TRANSFORM_WM;
- WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ BLI_assert(ELEM(sad->az->type, AZONE_AREA, AZONE_REGION_SCROLL));
+
+ /* add modal handler */
+ G.moving |= G_TRANSFORM_WM;
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
}
static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
@@ -1392,9 +1398,7 @@ finally:
if (newwin) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static void SCREEN_OT_area_dupli(wmOperatorType *ot)
@@ -1492,21 +1496,21 @@ static void area_move_set_limits(wmWindow *win,
return;
}
/* top edge */
- else if ((area->v2->editflag && area->v3->editflag)) {
+ if ((area->v2->editflag && area->v3->editflag)) {
*smaller = area->v1->vec.y + size_min;
*bigger = area->v1->vec.y + size_max;
*use_bigger_smaller_snap = true;
return;
}
/* right edge */
- else if ((area->v3->editflag && area->v4->editflag)) {
+ if ((area->v3->editflag && area->v4->editflag)) {
*smaller = area->v1->vec.x + size_min;
*bigger = area->v1->vec.x + size_max;
*use_bigger_smaller_snap = true;
return;
}
/* lower edge */
- else if ((area->v4->editflag && area->v1->editflag)) {
+ if ((area->v4->editflag && area->v1->editflag)) {
*smaller = area->v2->vec.y - size_max;
*bigger = area->v2->vec.y - size_min;
*use_bigger_smaller_snap = true;
@@ -2046,13 +2050,13 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *area, ScrArea *sb)
if (sav1 == sbv4 && sav2 == sbv3) { /* area to right of sb = W */
return BKE_screen_find_edge(screen, sav1, sav2);
}
- else if (sav2 == sbv1 && sav3 == sbv4) { /* area to bottom of sb = N */
+ if (sav2 == sbv1 && sav3 == sbv4) { /* area to bottom of sb = N */
return BKE_screen_find_edge(screen, sav2, sav3);
}
- else if (sav3 == sbv2 && sav4 == sbv1) { /* area to left of sb = E */
+ if (sav3 == sbv2 && sav4 == sbv1) { /* area to left of sb = E */
return BKE_screen_find_edge(screen, sav3, sav4);
}
- else if (sav1 == sbv2 && sav4 == sbv3) { /* area on top of sb = S*/
+ if (sav1 == sbv2 && sav4 == sbv3) { /* area on top of sb = S*/
return BKE_screen_find_edge(screen, sav1, sav4);
}
@@ -3028,15 +3032,14 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- else {
- areas_do_frame_follow(C, true);
- DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
+ areas_do_frame_follow(C, true);
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
- return OPERATOR_FINISHED;
- }
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+
+ return OPERATOR_FINISHED;
}
static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
@@ -3092,17 +3095,16 @@ static int marker_jump_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- else {
- CFRA = closest;
- areas_do_frame_follow(C, true);
+ CFRA = closest;
- DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
+ areas_do_frame_follow(C, true);
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK);
- return OPERATOR_FINISHED;
- }
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+
+ return OPERATOR_FINISHED;
}
static void SCREEN_OT_marker_jump(wmOperatorType *ot)
@@ -3366,10 +3368,8 @@ static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (sad->sa1 == sad->sa2) {
return OPERATOR_PASS_THROUGH;
}
- else {
- if (!area_join_init(C, op, sad->sa1, sad->sa2)) {
- return OPERATOR_CANCELLED;
- }
+ if (!area_join_init(C, op, sad->sa1, sad->sa2)) {
+ return OPERATOR_CANCELLED;
}
}
@@ -3677,9 +3677,7 @@ static int repeat_last_exec(bContext *C, wmOperator *UNUSED(op))
if (lastop->type->flag & OPTYPE_REGISTER) {
break;
}
- else {
- lastop = lastop->prev;
- }
+ lastop = lastop->prev;
}
if (lastop) {
@@ -4131,12 +4129,6 @@ static void SCREEN_OT_header_toggle_menus(wmOperatorType *ot)
/** \name Region Context Menu Operator (Header/Footer/Navbar)
* \{ */
-static bool screen_region_context_menu_poll(bContext *C)
-{
- ScrArea *area = CTX_wm_area(C);
- return (area && area->spacetype != SPACE_STATUSBAR);
-}
-
void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg))
{
ScrArea *area = CTX_wm_area(C);
@@ -4225,15 +4217,35 @@ void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout,
uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip");
}
+static void ed_screens_statusbar_menu_create(uiLayout *layout, void *UNUSED(arg))
+{
+ PointerRNA ptr;
+
+ RNA_pointer_create(NULL, &RNA_PreferencesView, &U, &ptr);
+ uiItemR(layout, &ptr, "show_statusbar_stats", 0, IFACE_("Scene Statistics"), ICON_NONE);
+ uiItemR(layout, &ptr, "show_statusbar_memory", 0, IFACE_("System Memory"), ICON_NONE);
+ if (GPU_mem_stats_supported()) {
+ uiItemR(layout, &ptr, "show_statusbar_vram", 0, IFACE_("Video Memory"), ICON_NONE);
+ }
+ uiItemR(layout, &ptr, "show_statusbar_version", 0, IFACE_("Blender Version"), ICON_NONE);
+}
+
static int screen_context_menu_invoke(bContext *C,
wmOperator *UNUSED(op),
const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
+ const ScrArea *area = CTX_wm_area(C);
const ARegion *region = CTX_wm_region(C);
- if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
+ if (area && area->spacetype == SPACE_STATUSBAR) {
+ pup = UI_popup_menu_begin(C, IFACE_("Status Bar"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ ed_screens_statusbar_menu_create(layout, NULL);
+ UI_popup_menu_end(C, pup);
+ }
+ else if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
pup = UI_popup_menu_begin(C, IFACE_("Header"), ICON_NONE);
layout = UI_popup_menu_layout(pup);
ED_screens_header_tools_menu_create(C, layout, NULL);
@@ -4263,7 +4275,6 @@ static void SCREEN_OT_region_context_menu(wmOperatorType *ot)
ot->idname = "SCREEN_OT_region_context_menu";
/* api callbacks */
- ot->poll = screen_region_context_menu_poll;
ot->invoke = screen_context_menu_invoke;
}
@@ -4391,7 +4402,7 @@ static void screen_animation_region_tag_redraw(ScrArea *area,
ED_region_tag_redraw(region);
return;
}
- else if (scene->r.cfra > region->v2d.cur.xmax) {
+ if (scene->r.cfra > region->v2d.cur.xmax) {
region->v2d.cur.xmin = scene->r.cfra;
region->v2d.cur.xmax = region->v2d.cur.xmin + w;
ED_region_tag_redraw(region);
@@ -4916,10 +4927,8 @@ static int userpref_show_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
- return OPERATOR_CANCELLED;
- }
+ BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
+ return OPERATOR_CANCELLED;
}
static void SCREEN_OT_userpref_show(struct wmOperatorType *ot)
@@ -4994,10 +5003,8 @@ static int drivers_editor_show_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
- return OPERATOR_CANCELLED;
- }
+ BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
+ return OPERATOR_CANCELLED;
}
static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot)
@@ -5038,10 +5045,8 @@ static int info_log_show_exec(bContext *C, wmOperator *op)
false) != NULL) {
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
- return OPERATOR_CANCELLED;
- }
+ BKE_report(op->reports, RPT_ERROR, "Failed to open window!");
+ return OPERATOR_CANCELLED;
}
static void SCREEN_OT_info_log_show(struct wmOperatorType *ot)
@@ -5179,7 +5184,7 @@ static void region_blend_end(bContext *C, ARegion *region, const bool is_running
else {
if (rgi->hidden) {
rgi->region->flag |= rgi->hidden;
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), rgi->area);
+ ED_area_init(CTX_wm_manager(C), CTX_wm_window(C), rgi->area);
}
/* area decoration needs redraw in end */
ED_area_tag_redraw(rgi->area);
@@ -5210,7 +5215,7 @@ void ED_region_visibility_change_update_animated(bContext *C, ScrArea *area, ARe
/* blend in, reinitialize regions because it got unhidden */
if (rgi->hidden == 0) {
- ED_area_initialize(wm, win, area);
+ ED_area_init(wm, win, area);
}
else {
WM_event_remove_handlers(C, &region->handlers);
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 83ded5b3503..f80c13a7fb7 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -91,10 +91,8 @@ static int screenshot_data_create(bContext *C, wmOperator *op)
return true;
}
- else {
- op->customdata = NULL;
- return false;
- }
+ op->customdata = NULL;
+ return false;
}
static void screenshot_data_free(wmOperator *op)
@@ -207,6 +205,8 @@ static void screenshot_draw(bContext *UNUSED(C), wmOperator *op)
ScreenshotData *scd = op->customdata;
PointerRNA ptr;
+ uiLayoutSetPropSep(layout, true);
+
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &scd->im_format, &ptr);
uiTemplateImageSettings(layout, &ptr, false);
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 478a0adfd9a..b20dc80d158 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -88,22 +88,15 @@ static void workspace_change_update(WorkSpace *workspace_new,
#endif
}
-static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
-{
- /* return false to stop the iterator if we've found a layout that can be activated */
- return workspace_layout_set_poll(layout) ? false : true;
-}
-
static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain,
WorkSpace *workspace_new,
wmWindow *win)
{
- /* ED_workspace_duplicate may have stored a layout to activate
- * once the workspace gets activated. */
WorkSpaceLayout *layout_old = WM_window_get_active_layout(win);
WorkSpaceLayout *layout_new;
- bScreen *screen_new;
+ /* ED_workspace_duplicate may have stored a layout to activate
+ * once the workspace gets activated. */
if (win->workspace_hook->temp_workspace_store) {
layout_new = win->workspace_hook->temp_layout_store;
}
@@ -113,20 +106,9 @@ static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain,
layout_new = workspace_new->layouts.first;
}
}
- screen_new = BKE_workspace_layout_screen_get(layout_new);
-
- if (screen_new->winid) {
- /* screen is already used, try to find a free one */
- WorkSpaceLayout *layout_temp = BKE_workspace_layout_iter_circular(
- workspace_new, layout_new, workspace_change_find_new_layout_cb, NULL, false);
- if (!layout_temp) {
- /* fallback solution: duplicate layout from old workspace */
- layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win);
- }
- layout_new = layout_temp;
- }
- return layout_new;
+ return ED_workspace_screen_change_ensure_unused_layout(
+ bmain, workspace_new, layout_new, layout_old, win);
}
/**
@@ -153,10 +135,7 @@ bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager
return false;
}
- screen_new = screen_change_prepare(screen_old, screen_new, bmain, C, win);
- if (BKE_workspace_layout_screen_get(layout_new) != screen_new) {
- layout_new = BKE_workspace_layout_find(workspace_new, screen_new);
- }
+ screen_change_prepare(screen_old, screen_new, bmain, C, win);
if (screen_new == NULL) {
return false;
diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c
index 0af81e0db21..8a36cffa1f1 100644
--- a/source/blender/editors/screen/workspace_layout_edit.c
+++ b/source/blender/editors/screen/workspace_layout_edit.c
@@ -160,6 +160,66 @@ bool ED_workspace_layout_delete(WorkSpace *workspace, WorkSpaceLayout *layout_ol
return false;
}
+static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
+{
+ /* return false to stop the iterator if we've found a layout that can be activated */
+ return workspace_layout_set_poll(layout) ? false : true;
+}
+
+static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen)
+{
+ for (bScreen *screen_iter = bmain->screens.first; screen_iter;
+ screen_iter = screen_iter->id.next) {
+ if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) {
+ ScrArea *area = screen_iter->areabase.first;
+ if (area && area->full == screen) {
+ return screen_iter;
+ }
+ }
+ }
+
+ return screen;
+}
+
+static bool screen_is_used_by_other_window(const wmWindow *win, const bScreen *screen)
+{
+ return BKE_screen_is_used(screen) && (screen->winid != win->winid);
+}
+
+/**
+ * Make sure there is a non-fullscreen layout to switch to that is not used yet by an other window.
+ * Needed for workspace or screen switching to ensure valid screens.
+ *
+ * \param layout_fallback_base: As last resort, this layout is duplicated and returned.
+ */
+WorkSpaceLayout *ED_workspace_screen_change_ensure_unused_layout(
+ Main *bmain,
+ WorkSpace *workspace,
+ WorkSpaceLayout *layout_new,
+ const WorkSpaceLayout *layout_fallback_base,
+ wmWindow *win)
+{
+ WorkSpaceLayout *layout_temp = layout_new;
+ bScreen *screen_temp = BKE_workspace_layout_screen_get(layout_new);
+
+ screen_temp = screen_fullscreen_find_associated_normal_screen(bmain, screen_temp);
+ layout_temp = BKE_workspace_layout_find(workspace, screen_temp);
+
+ if (screen_is_used_by_other_window(win, screen_temp)) {
+ /* Screen is already used, try to find a free one. */
+ layout_temp = BKE_workspace_layout_iter_circular(
+ workspace, layout_new, workspace_change_find_new_layout_cb, NULL, false);
+ screen_temp = layout_temp ? BKE_workspace_layout_screen_get(layout_temp) : NULL;
+
+ if (!layout_temp || screen_is_used_by_other_window(win, screen_temp)) {
+ /* Fallback solution: duplicate layout. */
+ layout_temp = ED_workspace_layout_duplicate(bmain, workspace, layout_fallback_base, win);
+ }
+ }
+
+ return layout_temp;
+}
+
static bool workspace_layout_cycle_iter_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
{
/* return false to stop iterator when we have found a layout to activate */
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 909eae64e72..c5f1063d494 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -56,11 +56,11 @@
#include "DEG_depsgraph.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
+#include "GPU_texture.h"
#include "UI_resources.h"
@@ -79,7 +79,7 @@
*/
typedef struct TexSnapshot {
- GLuint overlay_texture;
+ GPUTexture *overlay_texture;
int winx;
int winy;
int old_size;
@@ -88,7 +88,7 @@ typedef struct TexSnapshot {
} TexSnapshot;
typedef struct CursorSnapshot {
- GLuint overlay_texture;
+ GPUTexture *overlay_texture;
int size;
int zoom;
int curve_preset;
@@ -102,13 +102,13 @@ static CursorSnapshot cursor_snap = {0};
void paint_cursor_delete_textures(void)
{
if (primary_snap.overlay_texture) {
- glDeleteTextures(1, &primary_snap.overlay_texture);
+ GPU_texture_free(primary_snap.overlay_texture);
}
if (secondary_snap.overlay_texture) {
- glDeleteTextures(1, &secondary_snap.overlay_texture);
+ GPU_texture_free(secondary_snap.overlay_texture);
}
if (cursor_snap.overlay_texture) {
- glDeleteTextures(1, &cursor_snap.overlay_texture);
+ GPU_texture_free(cursor_snap.overlay_texture);
}
memset(&primary_snap, 0, sizeof(TexSnapshot));
@@ -298,15 +298,15 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
size = 512;
}
- if (target->old_size != size) {
+ if (target->old_size != size || target->old_col != col) {
if (target->overlay_texture) {
- glDeleteTextures(1, &target->overlay_texture);
- target->overlay_texture = 0;
+ GPU_texture_free(target->overlay_texture);
+ target->overlay_texture = NULL;
}
-
init = false;
target->old_size = size;
+ target->old_col = col;
}
if (col) {
buffer = MEM_mallocN(sizeof(GLubyte) * size * size * 4, "load_tex");
@@ -347,41 +347,27 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
}
if (!target->overlay_texture) {
- glGenTextures(1, &target->overlay_texture);
+ eGPUTextureFormat format = col ? GPU_RGBA8 : GPU_R8;
+ target->overlay_texture = GPU_texture_create_nD(
+ size, size, 0, 2, buffer, format, GPU_DATA_UNSIGNED_BYTE, 0, false, NULL);
+
+ if (!col) {
+ GPU_texture_bind(target->overlay_texture, 0);
+ GPU_texture_swizzle_set(target->overlay_texture, "rrrr");
+ GPU_texture_unbind(target->overlay_texture);
+ }
}
- }
- else {
- size = target->old_size;
- }
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, target->overlay_texture);
-
- if (refresh) {
- GLenum format = col ? GL_RGBA : GL_RED;
- GLenum internalformat = col ? GL_RGBA8 : GL_R8;
-
- if (!init || (target->old_col != col)) {
- glTexImage2D(
- GL_TEXTURE_2D, 0, internalformat, size, size, 0, format, GL_UNSIGNED_BYTE, buffer);
- }
- else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, format, GL_UNSIGNED_BYTE, buffer);
+ if (init) {
+ GPU_texture_update(target->overlay_texture, GPU_DATA_UNSIGNED_BYTE, buffer);
}
if (buffer) {
MEM_freeN(buffer);
}
-
- target->old_col = col;
}
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ else {
+ size = target->old_size;
}
BKE_paint_reset_overlay_invalid(invalid);
@@ -459,8 +445,8 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
if (cursor_snap.size != size) {
if (cursor_snap.overlay_texture) {
- glDeleteTextures(1, &cursor_snap.overlay_texture);
- cursor_snap.overlay_texture = 0;
+ GPU_texture_free(cursor_snap.overlay_texture);
+ cursor_snap.overlay_texture = NULL;
}
init = false;
@@ -469,7 +455,7 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
}
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
- BKE_curvemapping_initialize(br->curve);
+ BKE_curvemapping_init(br->curve);
LoadTexData data = {
.br = br,
@@ -482,34 +468,25 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
BLI_task_parallel_range(0, size, &data, load_tex_cursor_task_cb, &settings);
if (!cursor_snap.overlay_texture) {
- glGenTextures(1, &cursor_snap.overlay_texture);
- }
- }
- else {
- size = cursor_snap.size;
- }
+ cursor_snap.overlay_texture = GPU_texture_create_nD(
+ size, size, 0, 2, buffer, GPU_R8, GPU_DATA_UNSIGNED_BYTE, 0, false, NULL);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, cursor_snap.overlay_texture);
-
- if (refresh) {
- if (!init) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size, size, 0, GL_RED, GL_UNSIGNED_BYTE, buffer);
+ GPU_texture_bind(cursor_snap.overlay_texture, 0);
+ GPU_texture_swizzle_set(cursor_snap.overlay_texture, "rrrr");
+ GPU_texture_unbind(cursor_snap.overlay_texture);
}
- else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_RED, GL_UNSIGNED_BYTE, buffer);
+
+ if (init) {
+ GPU_texture_update(cursor_snap.overlay_texture, GPU_DATA_UNSIGNED_BYTE, buffer);
}
if (buffer) {
MEM_freeN(buffer);
}
}
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ else {
+ size = cursor_snap.size;
+ }
cursor_snap.curve_preset = br->curve_preset;
BKE_paint_reset_overlay_invalid(PAINT_OVERLAY_INVALID_CURVE);
@@ -557,59 +534,9 @@ static int project_brush_radius(ViewContext *vc, float radius, const float locat
/* The distance between these points is the size of the projected brush in pixels. */
return len_v2v2(p1, p2);
}
- else {
- /* Assert because the code that sets up the vectors should disallow this. */
- BLI_assert(0);
- return 0;
- }
-}
-
-static bool sculpt_get_brush_geometry(bContext *C,
- ViewContext *vc,
- int x,
- int y,
- int *pixel_radius,
- float location[3],
- UnifiedPaintSettings *ups)
-{
- Scene *scene = CTX_data_scene(C);
- Paint *paint = BKE_paint_get_active_from_context(C);
- float mouse[2];
- bool hit = false;
-
- mouse[0] = x;
- mouse[1] = y;
-
- if (vc->obact->sculpt && vc->obact->sculpt->pbvh) {
- if (!ups->stroke_active) {
- hit = SCULPT_stroke_get_location(C, location, mouse);
- }
- else {
- hit = ups->last_hit;
- copy_v3_v3(location, ups->last_location);
- }
- }
-
- if (hit) {
- Brush *brush = BKE_paint_brush(paint);
-
- *pixel_radius = project_brush_radius(
- vc, BKE_brush_unprojected_radius_get(scene, brush), location);
-
- if (*pixel_radius == 0) {
- *pixel_radius = BKE_brush_size_get(scene, brush);
- }
-
- mul_m4_v3(vc->obact->obmat, location);
- }
- else {
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- Brush *brush = BKE_paint_brush(&sd->paint);
-
- *pixel_radius = BKE_brush_size_get(scene, brush);
- }
-
- return hit;
+ /* Assert because the code that sets up the vectors should disallow this. */
+ BLI_assert(0);
+ return 0;
}
/* Draw an overlay that shows what effect the brush's texture will
@@ -638,11 +565,8 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
}
if (load_tex(brush, vc, zoom, col, primary)) {
- GPU_blend(true);
-
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glDepthMask(GL_FALSE);
- glDepthFunc(GL_ALWAYS);
+ GPU_color_mask(true, true, true, true);
+ GPU_depth_test(false);
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
GPU_matrix_push();
@@ -709,19 +633,28 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- if (col) {
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
- immUniformColor4f(1.0f, 1.0f, 1.0f, overlay_alpha * 0.01f);
- }
- else {
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA_COLOR);
- immUniformColor3fvAlpha(U.sculpt_paint_overlay_col, overlay_alpha * 0.01f);
+ /* Premultiplied alpha blending. */
+ GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
+
+ float final_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ if (!col) {
+ copy_v3_v3(final_color, U.sculpt_paint_overlay_col);
}
+ mul_v4_fl(final_color, overlay_alpha * 0.01f);
+ immUniformColor4fv(final_color);
- /* Draw textured quad. */
- immUniform1i("image", 0);
+ GPUTexture *texture = (primary) ? primary_snap.overlay_texture :
+ secondary_snap.overlay_texture;
+ eGPUSamplerState state = GPU_SAMPLER_FILTER;
+ state |= (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) ? GPU_SAMPLER_CLAMP_BORDER :
+ GPU_SAMPLER_REPEAT;
+ immBindTextureSampler("image", texture, state);
+
+ /* Draw textured quad. */
immBegin(GPU_PRIM_TRI_FAN, 4);
immAttr2f(texCoord, 0.0f, 0.0f);
immVertex2f(pos, quad.xmin, quad.ymin);
@@ -734,6 +667,9 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
immEnd();
immUnbindProgram();
+
+ GPU_texture_unbind(texture);
+
GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) {
@@ -758,11 +694,9 @@ static bool paint_draw_cursor_overlay(
if (load_tex_cursor(brush, vc, zoom)) {
bool do_pop = false;
float center[2];
- GPU_blend(true);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glDepthMask(GL_FALSE);
- glDepthFunc(GL_ALWAYS);
+ GPU_color_mask(true, true, true, true);
+ GPU_depth_test(false);
if (ups->draw_anchored) {
copy_v2_v2(center, ups->anchored_initial_mouse);
@@ -796,14 +730,17 @@ static bool paint_draw_cursor_overlay(
uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA_COLOR);
+ GPU_blend(true);
- immUniformColor3fvAlpha(U.sculpt_paint_overlay_col, brush->cursor_overlay_alpha * 0.01f);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
- /* Draw textured quad. */
+ float final_color[4] = {UNPACK3(U.sculpt_paint_overlay_col), 1.0f};
+ mul_v4_fl(final_color, brush->cursor_overlay_alpha * 0.01f);
+ immUniformColor4fv(final_color);
/* Draw textured quad. */
- immUniform1i("image", 0);
+ immBindTextureSampler(
+ "image", cursor_snap.overlay_texture, GPU_SAMPLER_FILTER | GPU_SAMPLER_CLAMP_BORDER);
immBegin(GPU_PRIM_TRI_FAN, 4);
immAttr2f(texCoord, 0.0f, 0.0f);
@@ -816,6 +753,8 @@ static bool paint_draw_cursor_overlay(
immVertex2f(pos, quad.xmin, quad.ymax);
immEnd();
+ GPU_texture_unbind(cursor_snap.overlay_texture);
+
immUnbindProgram();
GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
@@ -877,8 +816,12 @@ static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups,
return alpha_overlay_active;
}
-BLI_INLINE void draw_tri_point(
- uint pos, const float sel_col[4], float pivot_col[4], float *co, float width, bool selected)
+BLI_INLINE void draw_tri_point(uint pos,
+ const float sel_col[4],
+ const float pivot_col[4],
+ float *co,
+ float width,
+ bool selected)
{
immUniformColor4fv(selected ? sel_col : pivot_col);
@@ -907,8 +850,12 @@ BLI_INLINE void draw_tri_point(
immEnd();
}
-BLI_INLINE void draw_rect_point(
- uint pos, const float sel_col[4], float handle_col[4], float *co, float width, bool selected)
+BLI_INLINE void draw_rect_point(uint pos,
+ const float sel_col[4],
+ const float handle_col[4],
+ const float *co,
+ float width,
+ bool selected)
{
immUniformColor4fv(selected ? sel_col : handle_col);
@@ -1046,10 +993,10 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
/* Special actions taken when paint cursor goes over mesh */
/* TODO: sculpt only for now. */
-static void paint_cursor_on_hit(UnifiedPaintSettings *ups,
- Brush *brush,
- ViewContext *vc,
- const float location[3])
+static void paint_cursor_update_unprojected_radius(UnifiedPaintSettings *ups,
+ Brush *brush,
+ ViewContext *vc,
+ const float location[3])
{
float unprojected_radius, projected_radius;
@@ -1081,18 +1028,6 @@ static void paint_cursor_on_hit(UnifiedPaintSettings *ups,
}
}
-static bool ommit_cursor_drawing(Paint *paint, ePaintMode mode, Brush *brush)
-{
- if (paint->flags & PAINT_SHOW_BRUSH) {
- if (ELEM(mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D) &&
- brush->imagepaint_tool == PAINT_TOOL_FILL) {
- return true;
- }
- return false;
- }
- return true;
-}
-
static void cursor_draw_point_screen_space(const uint gpuattr,
const ARegion *region,
const float true_location[3],
@@ -1192,8 +1127,27 @@ static void cursor_draw_point_with_symmetry(const uint gpuattr,
}
}
-static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession *ss)
+static void sculpt_geometry_preview_lines_draw(const uint gpuattr,
+ Brush *brush,
+ const bool is_multires,
+ SculptSession *ss)
{
+ if (!(brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) {
+ return;
+ }
+
+ if (is_multires) {
+ return;
+ }
+
+ if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
+ return;
+ }
+
+ if (!ss->deform_modifiers_active) {
+ return;
+ }
+
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.6f);
/* Cursor normally draws on top, but for this part we need depth tests. */
@@ -1219,30 +1173,21 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession
static void SCULPT_layer_brush_height_preview_draw(const uint gpuattr,
const Brush *brush,
- const float obmat[4][4],
- const float location[3],
- const float normal[3],
const float rds,
const float line_width,
const float outline_col[3],
const float alpha)
{
- float cursor_trans[4][4], cursor_rot[4][4];
- float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
- float quat[4];
- float height_preview_trans[3];
- copy_m4_m4(cursor_trans, obmat);
- madd_v3_v3v3fl(height_preview_trans, location, normal, brush->height);
- translate_m4(
- cursor_trans, height_preview_trans[0], height_preview_trans[1], height_preview_trans[2]);
- rotation_between_vecs_to_quat(quat, z_axis, normal);
- quat_to_mat4(cursor_rot, quat);
+ float cursor_trans[4][4];
+ unit_m4(cursor_trans);
+ translate_m4(cursor_trans, 0.0f, 0.0f, brush->height);
+ GPU_matrix_push();
GPU_matrix_mul(cursor_trans);
- GPU_matrix_mul(cursor_rot);
GPU_line_width(line_width);
immUniformColor3fvAlpha(outline_col, alpha * 0.5f);
imm_draw_circle_wire_3d(gpuattr, 0, 0, rds, 80);
+ GPU_matrix_pop();
}
static bool paint_use_2d_cursor(ePaintMode mode)
@@ -1253,428 +1198,667 @@ static bool paint_use_2d_cursor(ePaintMode mode)
return false;
}
-static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
+typedef enum PaintCursorDrawingType {
+ PAINT_CURSOR_CURVE,
+ PAINT_CURSOR_2D,
+ PAINT_CURSOR_3D,
+} PaintCursorDrawingType;
+
+typedef struct PaintCursorContext {
+ bContext *C;
+ ARegion *region;
+ wmWindow *win;
+ wmWindowManager *wm;
+ Depsgraph *depsgraph;
+ Scene *scene;
+ UnifiedPaintSettings *ups;
+ Brush *brush;
+ Paint *paint;
+ ePaintMode mode;
+ ViewContext vc;
+
+ /* Sculpt related data. */
+ Sculpt *sd;
+ SculptSession *ss;
+ int prev_active_vertex_index;
+ bool is_stroke_active;
+ bool is_cursor_over_mesh;
+ bool is_multires;
+ float radius;
+
+ /* 3D view cursor position and normal. */
+ float location[3];
+ float scene_space_location[3];
+ float normal[3];
+
+ /* Cursor main colors. */
+ float outline_col[3];
+ float outline_alpha;
+
+ /* GPU attribute for drawing. */
+ uint pos;
+
+ PaintCursorDrawingType cursor_type;
+
+ /* This variable is set after drawing the overlay, not on initialization. It can't be used for
+ * checking if alpha overlay is enabled before drawing it. */
+ bool alpha_overlay_drawn;
+
+ float zoomx;
+ int x, y;
+ float translation[2];
+
+ float final_radius;
+ int pixel_radius;
+
+} PaintCursorContext;
+
+static bool paint_cursor_context_init(bContext *C,
+ const int x,
+ const int y,
+ PaintCursorContext *pcontext)
{
ARegion *region = CTX_wm_region(C);
if (region && region->regiontype != RGN_TYPE_WINDOW) {
- return;
+ return false;
}
- const wmWindowManager *wm = CTX_wm_manager(C);
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- Scene *scene = CTX_data_scene(C);
- UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
- Paint *paint = BKE_paint_get_active_from_context(C);
- Brush *brush = BKE_paint_brush(paint);
- ePaintMode mode = BKE_paintmode_get_active_from_context(C);
+ pcontext->C = C;
+ pcontext->region = region;
+ pcontext->wm = CTX_wm_manager(C);
+ pcontext->win = CTX_wm_window(C);
+ pcontext->depsgraph = CTX_data_depsgraph_pointer(C);
+ pcontext->scene = CTX_data_scene(C);
+ pcontext->ups = &pcontext->scene->toolsettings->unified_paint_settings;
+ pcontext->paint = BKE_paint_get_active_from_context(C);
+ pcontext->brush = BKE_paint_brush(pcontext->paint);
+ pcontext->mode = BKE_paintmode_get_active_from_context(C);
+
+ ED_view3d_viewcontext_init(C, &pcontext->vc, pcontext->depsgraph);
+
+ if (pcontext->brush->flag & BRUSH_CURVE) {
+ pcontext->cursor_type = PAINT_CURSOR_CURVE;
+ }
+ else if (paint_use_2d_cursor(pcontext->mode)) {
+ pcontext->cursor_type = PAINT_CURSOR_2D;
+ }
+ else {
+ pcontext->cursor_type = PAINT_CURSOR_3D;
+ }
- /* 2d or 3d painting? */
- const bool use_2d_cursor = paint_use_2d_cursor(mode);
+ pcontext->x = x;
+ pcontext->y = y;
+ pcontext->translation[0] = (float)x;
+ pcontext->translation[1] = (float)y;
- /* check that brush drawing is enabled */
- if (ommit_cursor_drawing(paint, mode, brush)) {
- return;
+ float zoomx, zoomy;
+ get_imapaint_zoom(C, &zoomx, &zoomy);
+ pcontext->zoomx = max_ff(zoomx, zoomy);
+ pcontext->final_radius = (BKE_brush_size_get(pcontext->scene, pcontext->brush) * zoomx);
+
+ /* There is currently no way to check if the direction is invertex before starting the stroke, so
+ * this does not reflect the state of the brush in the UI. */
+ if (((pcontext->ups->draw_inverted == 0) ^ ((pcontext->brush->flag & BRUSH_DIR_IN) == 0)) &&
+ BKE_brush_sculpt_has_secondary_color(pcontext->brush)) {
+ copy_v3_v3(pcontext->outline_col, pcontext->brush->sub_col);
+ }
+ else {
+ copy_v3_v3(pcontext->outline_col, pcontext->brush->add_col);
}
+ pcontext->outline_alpha = pcontext->brush->add_col[3];
- /* Can't use stroke vc here because this will be called during
- * mouse over too, not just during a stroke. */
- ViewContext vc;
- ED_view3d_viewcontext_init(C, &vc, depsgraph);
+ Object *active_object = pcontext->vc.obact;
+ pcontext->ss = active_object ? active_object->sculpt : NULL;
- if (vc.rv3d && (vc.rv3d->rflag & RV3D_NAVIGATING)) {
- return;
+ pcontext->is_stroke_active = pcontext->ups->stroke_active;
+
+ return true;
+}
+
+static void paint_cursor_update_pixel_radius(PaintCursorContext *pcontext)
+{
+ if (pcontext->is_cursor_over_mesh) {
+ Brush *brush = BKE_paint_brush(pcontext->paint);
+ pcontext->pixel_radius = project_brush_radius(
+ &pcontext->vc,
+ BKE_brush_unprojected_radius_get(pcontext->scene, brush),
+ pcontext->location);
+
+ if (pcontext->pixel_radius == 0) {
+ pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush);
+ }
+
+ copy_v3_v3(pcontext->scene_space_location, pcontext->location);
+ mul_m4_v3(pcontext->vc.obact->obmat, pcontext->scene_space_location);
}
+ else {
+ Sculpt *sd = CTX_data_tool_settings(pcontext->C)->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
- /* Skip everything and draw brush here. */
- if (brush->flag & BRUSH_CURVE) {
- paint_draw_curve_cursor(brush, &vc);
- return;
+ pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush);
}
+}
- float zoomx, zoomy;
- get_imapaint_zoom(C, &zoomx, &zoomy);
- zoomx = max_ff(zoomx, zoomy);
+static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcontext)
+{
+ BLI_assert(pcontext->ss != NULL);
+ BLI_assert(pcontext->mode == PAINT_MODE_SCULPT);
+
+ bContext *C = pcontext->C;
+ SculptSession *ss = pcontext->ss;
+ Brush *brush = pcontext->brush;
+ Scene *scene = pcontext->scene;
+ UnifiedPaintSettings *ups = pcontext->ups;
+ ViewContext *vc = &pcontext->vc;
+ SculptCursorGeometryInfo gi;
+
+ float mouse[2] = {pcontext->x - pcontext->region->winrct.xmin,
+ pcontext->y - pcontext->region->winrct.ymin};
+
+ /* This updates the active vertex, which is needed for most of the Sculpt/Vertex Colors tools to
+ * work correctly */
+ pcontext->prev_active_vertex_index = ss->active_vertex_index;
+ if (!ups->stroke_active) {
+ pcontext->is_cursor_over_mesh = SCULPT_cursor_geometry_info_update(
+ C, &gi, mouse, (pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE));
+ copy_v3_v3(pcontext->location, gi.location);
+ copy_v3_v3(pcontext->normal, gi.normal);
+ }
+ else {
+ pcontext->is_cursor_over_mesh = ups->last_hit;
+ copy_v3_v3(pcontext->location, ups->last_location);
+ }
- /* Set various defaults. */
- const float *outline_col = brush->add_col;
- const float outline_alpha = brush->add_col[3];
- float translation[2] = {x, y};
- float final_radius = (BKE_brush_size_get(scene, brush) * zoomx);
+ paint_cursor_update_pixel_radius(pcontext);
- /* Don't calculate rake angles while a stroke is active because the rake variables are global
- * and we may get interference with the stroke itself.
- * For line strokes, such interference is visible. */
- if (!ups->stroke_active) {
- paint_calculate_rake_rotation(ups, brush, translation);
+ if (BKE_brush_use_locked_size(scene, brush)) {
+ BKE_brush_size_set(scene, brush, pcontext->pixel_radius);
}
- /* Draw overlay. */
- bool alpha_overlay_active = paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode);
+ if (pcontext->is_cursor_over_mesh) {
+ paint_cursor_update_unprojected_radius(ups, brush, vc, pcontext->scene_space_location);
+ }
- if (ups->draw_anchored) {
- final_radius = ups->anchored_size;
- copy_v2_fl2(translation,
- ups->anchored_initial_mouse[0] + region->winrct.xmin,
- ups->anchored_initial_mouse[1] + region->winrct.ymin);
+ pcontext->is_multires = ss->pbvh != NULL && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
+
+ pcontext->sd = CTX_data_tool_settings(pcontext->C)->sculpt;
+}
+
+static void paint_update_mouse_cursor(PaintCursorContext *pcontext)
+{
+ WM_cursor_set(pcontext->win, WM_CURSOR_PAINT);
+}
+
+static void paint_draw_2D_view_brush_cursor(PaintCursorContext *pcontext)
+{
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
+
+ /* Draw brush outline. */
+ if (pcontext->ups->stroke_active && BKE_brush_use_size_pressure(pcontext->brush)) {
+ imm_draw_circle_wire_2d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius * pcontext->ups->size_pressure_value,
+ 40);
+ /* Outer at half alpha. */
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f);
}
- /* Make lines pretty. */
+ GPU_line_width(1.0f);
+ imm_draw_circle_wire_2d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius,
+ 40);
+
+ immUnbindProgram();
+}
+
+static void paint_draw_legacy_3D_view_brush_cursor(PaintCursorContext *pcontext)
+{
+ GPU_line_width(1.0f);
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
+ imm_draw_circle_wire_3d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius,
+ 40);
+}
+
+static void paint_draw_3D_view_inactive_brush_cursor(PaintCursorContext *pcontext)
+{
+ GPU_line_width(1.0f);
+ /* Reduce alpha to increase the contrast when the cursor is over the mesh. */
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.8);
+ imm_draw_circle_wire_3d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius,
+ 80);
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.35f);
+ imm_draw_circle_wire_3d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f),
+ 80);
+}
+
+static void paint_cursor_update_object_space_radius(PaintCursorContext *pcontext)
+{
+ if (!BKE_brush_use_locked_size(pcontext->scene, pcontext->brush)) {
+ pcontext->radius = paint_calc_object_space_radius(
+ &pcontext->vc, pcontext->location, BKE_brush_size_get(pcontext->scene, pcontext->brush));
+ }
+ else {
+ pcontext->radius = BKE_brush_unprojected_radius_get(pcontext->scene, pcontext->brush);
+ }
+}
+
+static void paint_cursor_drawing_setup_cursor_space(PaintCursorContext *pcontext)
+{
+ float cursor_trans[4][4], cursor_rot[4][4];
+ float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
+ float quat[4];
+ copy_m4_m4(cursor_trans, pcontext->vc.obact->obmat);
+ translate_m4(cursor_trans, pcontext->location[0], pcontext->location[1], pcontext->location[2]);
+ rotation_between_vecs_to_quat(quat, z_axis, pcontext->normal);
+ quat_to_mat4(cursor_rot, quat);
+ GPU_matrix_mul(cursor_trans);
+ GPU_matrix_mul(cursor_rot);
+}
+
+static void paint_cursor_draw_main_inactive_cursor(PaintCursorContext *pcontext)
+{
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
GPU_line_width(2.0f);
+ imm_draw_circle_wire_3d(pcontext->pos, 0, 0, pcontext->radius, 80);
- /* TODO: also set blend mode? */
- GPU_blend(true);
+ GPU_line_width(1.0f);
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f);
+ imm_draw_circle_wire_3d(
+ pcontext->pos, 0, 0, pcontext->radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f), 80);
+}
- GPU_line_smooth(true);
+static void paint_cursor_pose_brush_segments_draw(PaintCursorContext *pcontext)
+{
+ SculptSession *ss = pcontext->ss;
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
+ GPU_line_width(2.0f);
- if (use_2d_cursor) {
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBegin(GPU_PRIM_LINES, ss->pose_ik_chain_preview->tot_segments * 2);
+ for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
+ immVertex3fv(pcontext->pos, ss->pose_ik_chain_preview->segments[i].initial_orig);
+ immVertex3fv(pcontext->pos, ss->pose_ik_chain_preview->segments[i].initial_head);
+ }
- immUniformColor3fvAlpha(outline_col, outline_alpha);
+ immEnd();
+}
- /* Draw brush outline. */
- if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
- imm_draw_circle_wire_2d(
- pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
- /* Outer at half alpha. */
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f);
- }
+static void paint_cursor_pose_brush_origins_draw(PaintCursorContext *pcontext)
+{
- GPU_line_width(1.0f);
- imm_draw_circle_wire_2d(pos, translation[0], translation[1], final_radius, 40);
+ SculptSession *ss = pcontext->ss;
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
+ for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
+ cursor_draw_point_screen_space(pcontext->pos,
+ pcontext->region,
+ ss->pose_ik_chain_preview->segments[i].initial_orig,
+ pcontext->vc.obact->obmat,
+ 3);
}
- else {
- /* 3D Painting. */
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
- /* TODO: as sculpt and other paint modes are unified, this
- * special mode of drawing will go away. */
- Object *obact = vc.obact;
- SculptSession *ss = obact ? obact->sculpt : NULL;
- if ((mode == PAINT_MODE_SCULPT) && ss) {
- float location[3];
- int pixel_radius;
-
- /* Test if brush is over the mesh. */
- bool hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location, ups);
-
- if (BKE_brush_use_locked_size(scene, brush)) {
- BKE_brush_size_set(scene, brush, pixel_radius);
- }
+}
- /* Check if brush is subtracting, use different color then */
- /* TODO: no way currently to know state of pen flip or
- * invert key modifier without starting a stroke. */
- if (((ups->draw_inverted == 0) ^ ((brush->flag & BRUSH_DIR_IN) == 0)) &&
- BKE_brush_sculpt_has_secondary_color(brush)) {
- outline_col = brush->sub_col;
- }
+static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *pcontext)
+{
+ Brush *brush = pcontext->brush;
+
+ /* 2D fallof is better represented with the default 2D cursor, there is no need to draw anything
+ * else. */
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ paint_draw_legacy_3D_view_brush_cursor(pcontext);
+ return;
+ }
- /* Only do if brush is over the mesh. */
- if (hit) {
- paint_cursor_on_hit(ups, brush, &vc, location);
+ if (pcontext->alpha_overlay_drawn) {
+ paint_draw_legacy_3D_view_brush_cursor(pcontext);
+ return;
+ }
+
+ if (!pcontext->is_cursor_over_mesh) {
+ paint_draw_3D_view_inactive_brush_cursor(pcontext);
+ return;
+ }
+
+ paint_cursor_update_object_space_radius(pcontext);
+
+ const bool update_previews = pcontext->prev_active_vertex_index !=
+ SCULPT_active_vertex_get(pcontext->ss);
+
+ /* Setup drawing. */
+ wmViewport(&pcontext->region->winrct);
+
+ /* Drawing of Cursor overlays in 2D screen space. */
+
+ /* Cursor location symmetry points. */
+
+ const float *active_vertex_co = SCULPT_active_vertex_co_get(pcontext->ss);
+ if (len_v3v3(active_vertex_co, pcontext->location) < pcontext->radius) {
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
+ cursor_draw_point_with_symmetry(pcontext->pos,
+ pcontext->region,
+ active_vertex_co,
+ pcontext->sd,
+ pcontext->vc.obact,
+ pcontext->radius);
+ }
+
+ /* Pose brush updates and rotation origins. */
+
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
+ /* Just after switching to the Pose Brush, the active vertex can be the same and the
+ * cursor won't be tagged to update, so always initialize the preview chain if it is
+ * null before drawing it. */
+ SculptSession *ss = pcontext->ss;
+ if (update_previews || !ss->pose_ik_chain_preview) {
+ BKE_sculpt_update_object_for_edit(
+ pcontext->depsgraph, pcontext->vc.obact, true, false, false);
+
+ /* Free the previous pose brush preview. */
+ if (ss->pose_ik_chain_preview) {
+ SCULPT_pose_ik_chain_free(ss->pose_ik_chain_preview);
}
+
+ /* Generate a new pose brush preview from the current cursor location. */
+ ss->pose_ik_chain_preview = SCULPT_pose_ik_chain_init(
+ pcontext->sd, pcontext->vc.obact, ss, brush, pcontext->location, pcontext->radius);
}
- immUniformColor3fvAlpha(outline_col, outline_alpha);
+ /* Draw the pose brush rotation origins. */
+ paint_cursor_pose_brush_origins_draw(pcontext);
+ }
- if (ups->stroke_active && BKE_brush_use_size_pressure(brush) && mode != PAINT_MODE_SCULPT) {
- imm_draw_circle_wire_3d(
- pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
- /* Outer at half alpha. */
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f);
- }
+ /* Setup 3D perspective drawing. */
+ GPU_matrix_push_projection();
+ ED_view3d_draw_setup_view(pcontext->wm,
+ pcontext->win,
+ pcontext->depsgraph,
+ pcontext->scene,
+ pcontext->region,
+ CTX_wm_view3d(pcontext->C),
+ NULL,
+ NULL,
+ NULL);
+
+ GPU_matrix_push();
+ GPU_matrix_mul(pcontext->vc.obact->obmat);
+
+ /* Drawing Cursor overlays in 3D object space. */
+ if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) {
+ SCULPT_geometry_preview_lines_update(pcontext->C, pcontext->ss, pcontext->radius);
+ sculpt_geometry_preview_lines_draw(
+ pcontext->pos, pcontext->brush, pcontext->is_multires, pcontext->ss);
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
+ paint_cursor_pose_brush_segments_draw(pcontext);
+ }
+
+ GPU_matrix_pop();
+
+ /* Drawing Cursor overlays in Paint Cursor space (as additional info on top of the brush cursor)
+ */
+ GPU_matrix_push();
+ paint_cursor_drawing_setup_cursor_space(pcontext);
+ /* Main inactive cursor. */
+ paint_cursor_draw_main_inactive_cursor(pcontext);
+
+ /* Cloth brush local simulation areas. */
+ if (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
+ brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
+ const float white[3] = {1.0f, 1.0f, 1.0f};
+ const float zero_v[3] = {0.0f};
+ /* This functions sets its own drawing space in order to draw the simulation limits when the
+ * cursor is active. When used here, this cursor overlay is already in cursor space, so its
+ * position and normal should be set to 0. */
+ SCULPT_cloth_simulation_limits_draw(
+ pcontext->pos, brush, zero_v, zero_v, pcontext->radius, 1.0f, white, 0.25f);
+ }
+
+ /* Layer brush height. */
+ if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
+ SCULPT_layer_brush_height_preview_draw(pcontext->pos,
+ brush,
+ pcontext->radius,
+ 1.0f,
+ pcontext->outline_col,
+ pcontext->outline_alpha);
+ }
+
+ GPU_matrix_pop();
+
+ /* Reset drawing. */
+ GPU_matrix_pop_projection();
+ wmWindowViewport(pcontext->win);
+}
+
+static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorContext *pcontext)
+{
+ BLI_assert(pcontext->ss != NULL);
+ BLI_assert(pcontext->mode == PAINT_MODE_SCULPT);
+
+ SculptSession *ss = pcontext->ss;
+ Brush *brush = pcontext->brush;
+
+ /* The cursor can be updated as active before creating the StrokeCache, so this needs to be
+ * checked. */
+ if (!ss->cache) {
+ return;
+ }
- /* Only sculpt mode cursor for now. */
- /* Disable for PBVH_GRIDS. */
- bool is_multires = ss && ss->pbvh && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
+ /* Most of the brushes initialize the necessary data for the custom cursor drawing after the
+ * first brush step, so make sure that it is not drawn before being initialized. */
+ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ return;
+ }
+
+ /* Setup drawing. */
+ wmViewport(&pcontext->region->winrct);
+ GPU_matrix_push_projection();
+ ED_view3d_draw_setup_view(pcontext->wm,
+ pcontext->win,
+ pcontext->depsgraph,
+ pcontext->scene,
+ pcontext->region,
+ CTX_wm_view3d(pcontext->C),
+ NULL,
+ NULL,
+ NULL);
+ GPU_matrix_push();
+ GPU_matrix_mul(pcontext->vc.obact->obmat);
+
+ /* Draw the special active cursors different tools may have. */
- SculptCursorGeometryInfo gi;
- float mouse[2] = {x - region->winrct.xmin, y - region->winrct.ymin};
- int prev_active_vertex_index = -1;
- bool is_cursor_over_mesh = false;
+ if (brush->sculpt_tool == SCULPT_TOOL_GRAB) {
+ sculpt_geometry_preview_lines_draw(pcontext->pos, brush, pcontext->is_multires, ss);
+ }
- /* Update the active vertex. */
- if ((mode == PAINT_MODE_SCULPT) && ss && !ups->stroke_active) {
- prev_active_vertex_index = ss->active_vertex_index;
- is_cursor_over_mesh = SCULPT_cursor_geometry_info_update(
- C, &gi, mouse, (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE));
+ if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE) {
+ SCULPT_multiplane_scrape_preview_draw(
+ pcontext->pos, brush, ss, pcontext->outline_col, pcontext->outline_alpha);
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
+ if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) {
+ SCULPT_cloth_plane_falloff_preview_draw(
+ pcontext->pos, ss, pcontext->outline_col, pcontext->outline_alpha);
}
- /* Use special paint crosshair cursor in all paint modes. */
- wmWindow *win = CTX_wm_window(C);
- WM_cursor_set(win, WM_CURSOR_PAINT);
-
- if ((mode == PAINT_MODE_SCULPT) && ss &&
- (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE)) {
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
-
- if (!ups->stroke_active) {
- bool update_previews = false;
- if (is_cursor_over_mesh && !alpha_overlay_active) {
-
- if (prev_active_vertex_index != ss->active_vertex_index) {
- update_previews = true;
- }
-
- float rds;
- if (!BKE_brush_use_locked_size(scene, brush)) {
- rds = paint_calc_object_space_radius(
- &vc, gi.location, BKE_brush_size_get(scene, brush));
- }
- else {
- rds = BKE_brush_unprojected_radius_get(scene, brush);
- }
-
- wmViewport(&region->winrct);
-
- /* Draw 3D active vertex preview with symmetry. */
- if (len_v3v3(gi.active_vertex_co, gi.location) < rds) {
- cursor_draw_point_with_symmetry(pos, region, gi.active_vertex_co, sd, vc.obact, rds);
- }
-
- /* Draw pose brush origins. */
- if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
-
- /* Just after switching to the Pose Brush, the active vertex can be the same and the
- * cursor won't be tagged to update, so always initialize the preview chain if it is
- * null before drawing it. */
- if (update_previews || !ss->pose_ik_chain_preview) {
- BKE_sculpt_update_object_for_edit(depsgraph, vc.obact, true, false, false);
-
- /* Free the previous pose brush preview. */
- if (ss->pose_ik_chain_preview) {
- SCULPT_pose_ik_chain_free(ss->pose_ik_chain_preview);
- }
-
- /* Generate a new pose brush preview from the current cursor location. */
- ss->pose_ik_chain_preview = SCULPT_pose_ik_chain_init(
- sd, vc.obact, ss, brush, gi.location, rds);
- }
-
- /* Draw the pose brush rotation origins. */
- for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
- cursor_draw_point_screen_space(pos,
- region,
- ss->pose_ik_chain_preview->segments[i].initial_orig,
- vc.obact->obmat,
- 3);
- }
- }
-
- /* Draw 3D brush cursor. */
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(wm,
- CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- region,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
-
- float cursor_trans[4][4], cursor_rot[4][4];
- float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
- float quat[4];
-
- copy_m4_m4(cursor_trans, vc.obact->obmat);
- translate_m4(cursor_trans, gi.location[0], gi.location[1], gi.location[2]);
- rotation_between_vecs_to_quat(quat, z_axis, gi.normal);
- quat_to_mat4(cursor_rot, quat);
-
- GPU_matrix_push();
- GPU_matrix_mul(cursor_trans);
- GPU_matrix_mul(cursor_rot);
- immUniformColor3fvAlpha(outline_col, outline_alpha);
- GPU_line_width(2.0f);
- imm_draw_circle_wire_3d(pos, 0, 0, rds, 80);
-
- GPU_line_width(1.0f);
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f);
- imm_draw_circle_wire_3d(pos, 0, 0, rds * clamp_f(brush->alpha, 0.0f, 1.0f), 80);
- GPU_matrix_pop();
-
- /* Cloth brush simulation areas. */
- if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
- GPU_matrix_push();
- const float white[3] = {1.0f, 1.0f, 1.0f};
- SCULPT_cloth_simulation_limits_draw(
- pos, brush, vc.obact->obmat, gi.location, gi.normal, rds, 1.0f, white, 0.25f);
- GPU_matrix_pop();
- }
-
- /* Layer brush height. */
- if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
- GPU_matrix_push();
- SCULPT_layer_brush_height_preview_draw(pos,
- brush,
- vc.obact->obmat,
- gi.location,
- gi.normal,
- rds,
- 1.0f,
- outline_col,
- outline_alpha);
- GPU_matrix_pop();
- }
-
- /* Update and draw dynamic mesh preview lines. */
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) &&
- !is_multires) {
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->deform_modifiers_active) {
- SCULPT_geometry_preview_lines_update(C, ss, rds);
- sculpt_geometry_preview_lines_draw(pos, ss);
- }
- }
-
- /* Draw pose brush line preview. */
- if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
- GPU_line_width(2.0f);
-
- immBegin(GPU_PRIM_LINES, ss->pose_ik_chain_preview->tot_segments * 2);
- for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
- immVertex3fv(pos, ss->pose_ik_chain_preview->segments[i].initial_orig);
- immVertex3fv(pos, ss->pose_ik_chain_preview->segments[i].initial_head);
- }
-
- immEnd();
- }
-
- GPU_matrix_pop();
-
- GPU_matrix_pop_projection();
-
- wmWindowViewport(win);
- }
- else {
- /* Draw default cursor when the mouse is not over the mesh or there are no supported
- * overlays active. */
- GPU_line_width(1.0f);
- /* Reduce alpha to increase the contrast when the cursor is over the mesh. */
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.8);
- imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 80);
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.35f);
- imm_draw_circle_wire_3d(pos,
- translation[0],
- translation[1],
- final_radius * clamp_f(brush->alpha, 0.0f, 1.0f),
- 80);
- }
- }
- else {
- if (vc.obact->sculpt->cache &&
- !SCULPT_stroke_is_first_brush_step_of_symmetry_pass(vc.obact->sculpt->cache)) {
- wmViewport(&region->winrct);
-
- /* Draw cached dynamic mesh preview lines. */
- if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) &&
- !is_multires) {
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->deform_modifiers_active) {
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(wm,
- CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- region,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- sculpt_geometry_preview_lines_draw(pos, ss);
- GPU_matrix_pop();
- GPU_matrix_pop_projection();
- }
- }
-
- if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE &&
- brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW &&
- !SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(wm,
- CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- region,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- SCULPT_multiplane_scrape_preview_draw(pos, ss, outline_col, outline_alpha);
- GPU_matrix_pop();
- GPU_matrix_pop_projection();
- }
-
- if (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
- !SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(CTX_wm_manager(C),
- CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- region,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
-
- /* Plane falloff preview */
- if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) {
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- SCULPT_cloth_plane_falloff_preview_draw(pos, ss, outline_col, outline_alpha);
- GPU_matrix_pop();
- }
-
- /* Display the simulation limits if sculpting outside them. */
- /* This does not makes much sense of plane fallof as the fallof is infinte. */
- else if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_RADIAL) {
- if (len_v3v3(ss->cache->true_location, ss->cache->true_initial_location) >
- ss->cache->radius * (1.0f + brush->cloth_sim_limit)) {
- const float red[3] = {1.0f, 0.2f, 0.2f};
- GPU_matrix_push();
- SCULPT_cloth_simulation_limits_draw(pos,
- brush,
- vc.obact->obmat,
- ss->cache->true_initial_location,
- ss->cache->true_initial_normal,
- ss->cache->radius,
- 2.0f,
- red,
- 0.8f);
- GPU_matrix_pop();
- }
- }
-
- GPU_matrix_pop_projection();
- }
-
- wmWindowViewport(win);
- }
+ else if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_RADIAL &&
+ brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
+ /* Display the simulation limits if sculpting outside them. */
+ /* This does not makes much sense of plane fallof as the fallof is infinte or global. */
+
+ if (len_v3v3(ss->cache->true_location, ss->cache->true_initial_location) >
+ ss->cache->radius * (1.0f + brush->cloth_sim_limit)) {
+ const float red[3] = {1.0f, 0.2f, 0.2f};
+ SCULPT_cloth_simulation_limits_draw(pcontext->pos,
+ brush,
+ ss->cache->true_initial_location,
+ ss->cache->true_initial_normal,
+ ss->cache->radius,
+ 2.0f,
+ red,
+ 0.8f);
}
}
- else {
- /* Draw default cursor in unsupported modes. */
- GPU_line_width(1.0f);
- imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 40);
+ }
+
+ GPU_matrix_pop();
+
+ /* This Cloth brush cursor overlay always works in cursor space. */
+ paint_cursor_drawing_setup_cursor_space(pcontext);
+
+ GPU_matrix_pop_projection();
+ wmWindowViewport(pcontext->win);
+}
+
+static void paint_cursor_draw_3D_view_brush_cursor(PaintCursorContext *pcontext)
+{
+
+ /* These paint tools are not using the SculptSession, so they need to use the default 2D brush
+ * cursor in the 3D view. */
+ if (pcontext->mode != PAINT_MODE_SCULPT || !pcontext->ss) {
+ paint_draw_legacy_3D_view_brush_cursor(pcontext);
+ return;
+ }
+
+ paint_cursor_sculpt_session_update_and_init(pcontext);
+
+ if (pcontext->is_stroke_active) {
+ paint_cursor_cursor_draw_3d_view_brush_cursor_active(pcontext);
+ }
+ else {
+ paint_cursor_draw_3d_view_brush_cursor_inactive(pcontext);
+ }
+}
+
+static bool paint_cursor_is_3d_view_navigating(PaintCursorContext *pcontext)
+{
+ ViewContext *vc = &pcontext->vc;
+ return vc->rv3d && (vc->rv3d->rflag & RV3D_NAVIGATING);
+}
+
+static bool paint_cursor_is_brush_cursor_enabled(PaintCursorContext *pcontext)
+{
+ if (pcontext->paint->flags & PAINT_SHOW_BRUSH) {
+ if (ELEM(pcontext->mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D) &&
+ pcontext->brush->imagepaint_tool == PAINT_TOOL_FILL) {
+ return false;
}
+ return true;
}
+ return false;
+}
- immUnbindProgram();
+static void paint_cursor_update_rake_rotation(PaintCursorContext *pcontext)
+{
+ /* Don't calculate rake angles while a stroke is active because the rake variables are global
+ * and we may get interference with the stroke itself.
+ * For line strokes, such interference is visible. */
+ if (!pcontext->ups->stroke_active) {
+ paint_calculate_rake_rotation(pcontext->ups, pcontext->brush, pcontext->translation);
+ }
+}
- /* Restore GL state. */
+static void paint_cursor_check_and_draw_alpha_overlays(PaintCursorContext *pcontext)
+{
+ pcontext->alpha_overlay_drawn = paint_draw_alpha_overlay(pcontext->ups,
+ pcontext->brush,
+ &pcontext->vc,
+ pcontext->x,
+ pcontext->y,
+ pcontext->zoomx,
+ pcontext->mode);
+}
+
+static void paint_cursor_update_anchored_location(PaintCursorContext *pcontext)
+{
+ UnifiedPaintSettings *ups = pcontext->ups;
+ if (ups->draw_anchored) {
+ pcontext->final_radius = ups->anchored_size;
+ copy_v2_fl2(pcontext->translation,
+ ups->anchored_initial_mouse[0] + pcontext->region->winrct.xmin,
+ ups->anchored_initial_mouse[1] + pcontext->region->winrct.ymin);
+ }
+}
+
+static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext)
+{
+ GPU_line_width(2.0f);
+ GPU_blend(true);
+ GPU_line_smooth(true);
+ pcontext->pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+}
+
+static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext)
+{
+ GPU_line_width(2.0f);
+ GPU_blend(true);
+ GPU_line_smooth(true);
+ pcontext->pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+}
+
+static void paint_cursor_restore_drawing_state(void)
+{
+ immUnbindProgram();
GPU_blend(false);
GPU_line_smooth(false);
}
+static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
+{
+ PaintCursorContext pcontext;
+ if (!paint_cursor_context_init(C, x, y, &pcontext)) {
+ return;
+ }
+
+ if (!paint_cursor_is_brush_cursor_enabled(&pcontext)) {
+ return;
+ }
+ if (paint_cursor_is_3d_view_navigating(&pcontext)) {
+ return;
+ }
+
+ switch (pcontext.cursor_type) {
+ case PAINT_CURSOR_CURVE:
+ paint_draw_curve_cursor(pcontext.brush, &pcontext.vc);
+ break;
+ case PAINT_CURSOR_2D:
+ paint_cursor_update_rake_rotation(&pcontext);
+ paint_cursor_check_and_draw_alpha_overlays(&pcontext);
+ paint_cursor_update_anchored_location(&pcontext);
+
+ paint_cursor_setup_2D_drawing(&pcontext);
+ paint_draw_2D_view_brush_cursor(&pcontext);
+ paint_cursor_restore_drawing_state();
+ break;
+ case PAINT_CURSOR_3D:
+ paint_update_mouse_cursor(&pcontext);
+
+ paint_cursor_update_rake_rotation(&pcontext);
+ paint_cursor_check_and_draw_alpha_overlays(&pcontext);
+ paint_cursor_update_anchored_location(&pcontext);
+
+ paint_cursor_setup_3D_drawing(&pcontext);
+ paint_cursor_draw_3D_view_brush_cursor(&pcontext);
+ paint_cursor_restore_drawing_state();
+ break;
+ }
+}
+
/* Public API */
void paint_cursor_start(Paint *p, bool (*poll)(bContext *C))
diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c
index 68fd2f15877..74e022bf84f 100644
--- a/source/blender/editors/sculpt_paint/paint_curve.c
+++ b/source/blender/editors/sculpt_paint/paint_curve.c
@@ -142,19 +142,15 @@ static char paintcurve_point_side_index(const BezTriple *bezt,
if ((bezt->f1 & SELECT) == (bezt->f3 & SELECT)) {
return is_first ? SEL_F1 : SEL_F3;
}
- else if (bezt->f1 & SELECT) {
+ if (bezt->f1 & SELECT) {
return SEL_F1;
}
- else if (bezt->f3 & SELECT) {
+ if (bezt->f3 & SELECT) {
return SEL_F3;
}
- else {
- return fallback;
- }
- }
- else {
- return 0;
+ return fallback;
}
+ return 0;
}
/******************* Operators *********************************/
@@ -491,9 +487,7 @@ static int paintcurve_select_point_invoke(bContext *C, wmOperator *op, const wmE
RNA_int_set_array(op->ptr, "location", loc);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static int paintcurve_select_point_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index e9dcc4a356a..339921fe601 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -70,13 +70,12 @@ static bool is_effected(PartialVisArea area,
if (area == PARTIALVIS_ALL) {
return true;
}
- else if (area == PARTIALVIS_MASKED) {
+ if (area == PARTIALVIS_MASKED) {
return mask > 0.5f;
}
- else {
- bool inside = isect_point_planes_v3(planes, 4, co);
- return ((inside && area == PARTIALVIS_INSIDE) || (!inside && area == PARTIALVIS_OUTSIDE));
- }
+
+ bool inside = isect_point_planes_v3(planes, 4, co);
+ return ((inside && area == PARTIALVIS_INSIDE) || (!inside && area == PARTIALVIS_OUTSIDE));
}
static void partialvis_update_mesh(Object *ob,
@@ -418,9 +417,7 @@ static int hide_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (!ELEM(area, PARTIALVIS_ALL, PARTIALVIS_MASKED)) {
return WM_gesture_box_invoke(C, op, event);
}
- else {
- return op->type->exec(C, op);
- }
+ return op->type->exec(C, op);
}
void PAINT_OT_hide_show(struct wmOperatorType *ot)
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 7f64fdf3501..34c9cac67c8 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -74,7 +74,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@@ -182,7 +181,7 @@ void imapaint_image_update(
int h = imapaintpartial.y2 - imapaintpartial.y1;
if (w && h) {
/* Testing with partial update in uv editor too */
- GPU_paint_update_image(image, iuser, imapaintpartial.x1, imapaintpartial.y1, w, h);
+ BKE_image_update_gputexture(image, iuser, imapaintpartial.x1, imapaintpartial.y1, w, h);
}
}
}
@@ -1118,7 +1117,6 @@ void PAINT_OT_sample_color(wmOperatorType *ot)
void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob)
{
- bScreen *screen;
Image *ima = NULL;
ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
@@ -1142,17 +1140,16 @@ void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob
}
if (ima) {
- for (screen = bmain->screens.first; screen; screen = screen->id.next) {
- ScrArea *area;
- for (area = screen->areabase.first; area; area = area->next) {
- SpaceLink *sl;
- for (sl = area->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
-
- if (!sima->pin) {
- ED_space_image_set(bmain, sima, NULL, ima, true);
- }
+ wmWindowManager *wm = bmain->wm.first;
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ const bScreen *screen = WM_window_get_active_screen(win);
+ for (ScrArea *area = screen->areabase.first; area; area = area->next) {
+ SpaceLink *sl = area->spacedata.first;
+ if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ if (!sima->pin) {
+ ED_space_image_set(bmain, sima, NULL, ima, true);
}
}
}
@@ -1166,9 +1163,9 @@ void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob
BKE_paint_toolslots_brush_validate(bmain, &imapaint->paint);
if (U.glreslimit != 0) {
- GPU_free_images(bmain);
+ BKE_image_free_all_gputextures(bmain);
}
- GPU_paint_set_mipmap(bmain, 0);
+ BKE_image_paint_set_mipmap(bmain, 0);
toggle_paint_cursor(scene, true);
@@ -1191,9 +1188,9 @@ void ED_object_texture_paint_mode_exit_ex(Main *bmain, Scene *scene, Object *ob)
ob->mode &= ~OB_MODE_TEXTURE_PAINT;
if (U.glreslimit != 0) {
- GPU_free_images(bmain);
+ BKE_image_free_all_gputextures(bmain);
}
- GPU_paint_set_mipmap(bmain, 1);
+ BKE_image_paint_set_mipmap(bmain, 1);
toggle_paint_cursor(scene, false);
Mesh *me = BKE_mesh_from_object(ob);
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 16ccfaf8286..6d588d1450b 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -57,8 +57,6 @@
#include "UI_view2d.h"
-#include "GPU_draw.h"
-
#include "paint_intern.h"
/* Brush Painting for 2D image editor */
@@ -257,7 +255,7 @@ static ushort *brush_painter_mask_ibuf_new(BrushPainter *painter, const int size
/* update rectangular section of the brush image */
static void brush_painter_mask_imbuf_update(BrushPainter *painter,
ImagePaintTile *tile,
- ushort *tex_mask_old,
+ const ushort *tex_mask_old,
int origx,
int origy,
int w,
@@ -1052,7 +1050,7 @@ static void paint_2d_lift_soften(ImagePaintState *s,
ImagePaintTile *tile,
ImBuf *ibuf,
ImBuf *ibufb,
- int *pos,
+ const int *pos,
const short paint_tile)
{
bool sharpen = (tile->cache.invert ^ ((s->brush->flag & BRUSH_DIR_IN) != 0));
@@ -1255,7 +1253,7 @@ static void paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos, short paint
}
}
-static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
+static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, const int *pos)
{
/* note: allocImbuf returns zero'd memory, so regions outside image will
* have zero alpha, and hence not be blended onto the image */
@@ -1784,7 +1782,7 @@ void paint_2d_redraw(const bContext *C, void *ps, bool final)
if (final) {
if (s->image && !(s->sima && s->sima->lock)) {
- GPU_free_image(s->image);
+ BKE_image_free_gputextures(s->image);
}
/* compositor listener deals with updating */
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index dfb8f03fa6e..af2762889e8 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -100,8 +100,6 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
-#include "GPU_draw.h"
-
#include "IMB_colormanagement.h"
//#include "bmesh_tools.h"
@@ -557,12 +555,11 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i
if (ps->do_stencil_brush) {
return ps->stencil_ima;
}
- else {
- const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
- Material *ma = ps->mat_array[mp->mat_nr];
- TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : NULL;
- return slot ? slot->ima : ps->canvas_ima;
- }
+
+ const MPoly *mp = ps_tri_index_to_mpoly(ps, tri_index);
+ Material *ma = ps->mat_array[mp->mat_nr];
+ TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : NULL;
+ return slot ? slot->ima : ps->canvas_ima;
}
static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int tri_index)
@@ -605,9 +602,7 @@ static int project_bucket_offset_safe(const ProjPaintState *ps, const float proj
if (bucket_index < 0 || bucket_index >= ps->buckets_x * ps->buckets_y) {
return -1;
}
- else {
- return bucket_index;
- }
+ return bucket_index;
}
static float VecZDepthOrtho(
@@ -840,18 +835,17 @@ static int project_paint_occlude_ptv(const float pt[3],
if (v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
return 1;
}
- else {
- /* we intersect? - find the exact depth at the point of intersection */
- /* Is this point is occluded by another face? */
- if (is_ortho) {
- if (VecZDepthOrtho(pt, v1, v2, v3, w) < pt[2]) {
- return 2;
- }
+
+ /* we intersect? - find the exact depth at the point of intersection */
+ /* Is this point is occluded by another face? */
+ if (is_ortho) {
+ if (VecZDepthOrtho(pt, v1, v2, v3, w) < pt[2]) {
+ return 2;
}
- else {
- if (VecZDepthPersp(pt, v1, v2, v3, w) < pt[2]) {
- return 2;
- }
+ }
+ else {
+ if (VecZDepthPersp(pt, v1, v2, v3, w) < pt[2]) {
+ return 2;
}
}
return -1;
@@ -977,14 +971,12 @@ static int line_isect_y(const float p1[2], const float p2[2], const float y_leve
*x_isect = (p2[0] * (p1[1] - y_level) + p1[0] * (y_level - p2[1])) / y_diff;
return ISECT_TRUE;
}
- else if (p1[1] < y_level && p2[1] > y_level) {
+ if (p1[1] < y_level && p2[1] > y_level) {
/* (p2[1] - p1[1]); */
*x_isect = (p2[0] * (y_level - p1[1]) + p1[0] * (p2[1] - y_level)) / y_diff;
return ISECT_TRUE;
}
- else {
- return 0;
- }
+ return 0;
}
static int line_isect_x(const float p1[2], const float p2[2], const float x_level, float *y_isect)
@@ -1014,14 +1006,12 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve
*y_isect = (p2[1] * (p1[0] - x_level) + p1[1] * (x_level - p2[0])) / x_diff;
return ISECT_TRUE;
}
- else if (p1[0] < x_level && p2[0] > x_level) {
+ if (p1[0] < x_level && p2[0] > x_level) {
/* (p2[0] - p1[0]); */
*y_isect = (p2[1] * (x_level - p1[0]) + p1[1] * (p2[0] - x_level)) / x_diff;
return ISECT_TRUE;
}
- else {
- return 0;
- }
+ return 0;
}
/* simple func use for comparing UV locations to check if there are seams.
@@ -1204,10 +1194,8 @@ static bool check_seam(const ProjPaintState *ps,
// printf("SEAM (NONE)\n");
return false;
}
- else {
- // printf("SEAM (UV GAP)\n");
- return true;
- }
+ // printf("SEAM (UV GAP)\n");
+ return true;
}
}
}
@@ -1436,7 +1424,7 @@ static void insert_seam_vert_array(const ProjPaintState *ps,
* Be tricky with flags, first 4 bits are #PROJ_FACE_SEAM0 to 4,
* last 4 bits are #PROJ_FACE_NOSEAM0 to 4. `1 << i` - where i is `(0..3)`.
*
- * If we're multithreadng, make sure threads are locked when this is called.
+ * If we're multi-threading, make sure threads are locked when this is called.
*/
static void project_face_seams_init(const ProjPaintState *ps,
MemArena *arena,
@@ -1788,7 +1776,7 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps,
/* outsize the normal limit*/
return 0.0f;
}
- else if (angle_cos < ps->normal_angle_inner__cos) {
+ if (angle_cos < ps->normal_angle_inner__cos) {
mask *= (ps->normal_angle - acosf(angle_cos)) / ps->normal_angle_range;
} /* otherwise no mask normal is needed, we're within the limit */
}
@@ -1805,9 +1793,7 @@ static int project_paint_pixel_sizeof(const short tool)
if ((tool == PAINT_TOOL_CLONE) || (tool == PAINT_TOOL_SMEAR)) {
return sizeof(ProjPixelClone);
}
- else {
- return sizeof(ProjPixel);
- }
+ return sizeof(ProjPixel);
}
static int project_paint_undo_subtiles(const TileInfo *tinf, int tx, int ty)
@@ -2083,9 +2069,7 @@ static bool line_clip_rect2f(const rctf *cliprect,
copy_v2_v2(l2_clip, l2);
return true;
}
- else {
- return false;
- }
+ return false;
}
copy_v2_v2(l1_clip, l1);
@@ -2094,7 +2078,7 @@ static bool line_clip_rect2f(const rctf *cliprect,
CLAMP(l2_clip[0], rect->xmin, rect->xmax);
return true;
}
- else if (fabsf(l1[0] - l2[0]) < PROJ_PIXEL_TOLERANCE) {
+ if (fabsf(l1[0] - l2[0]) < PROJ_PIXEL_TOLERANCE) {
/* is the line out of range on its X axis? */
if (l1[0] < rect->xmin || l1[0] > rect->xmax) {
return 0;
@@ -2112,9 +2096,7 @@ static bool line_clip_rect2f(const rctf *cliprect,
copy_v2_v2(l2_clip, l2);
return true;
}
- else {
- return false;
- }
+ return false;
}
copy_v2_v2(l1_clip, l1);
@@ -2123,106 +2105,103 @@ static bool line_clip_rect2f(const rctf *cliprect,
CLAMP(l2_clip[1], rect->ymin, rect->ymax);
return true;
}
- else {
- float isect;
- short ok1 = 0;
- short ok2 = 0;
- /* Done with vertical lines */
+ float isect;
+ short ok1 = 0;
+ short ok2 = 0;
- /* are either of the points inside the rectangle ? */
- if (BLI_rctf_isect_pt_v(rect, l1)) {
- copy_v2_v2(l1_clip, l1);
- ok1 = 1;
- }
+ /* Done with vertical lines */
- if (BLI_rctf_isect_pt_v(rect, l2)) {
- copy_v2_v2(l2_clip, l2);
- ok2 = 1;
- }
+ /* are either of the points inside the rectangle ? */
+ if (BLI_rctf_isect_pt_v(rect, l1)) {
+ copy_v2_v2(l1_clip, l1);
+ ok1 = 1;
+ }
- /* line inside rect */
- if (ok1 && ok2) {
- return 1;
- }
+ if (BLI_rctf_isect_pt_v(rect, l2)) {
+ copy_v2_v2(l2_clip, l2);
+ ok2 = 1;
+ }
- /* top/bottom */
- if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= cliprect->xmin) &&
- (isect <= cliprect->xmax)) {
- if (l1[1] < l2[1]) { /* line 1 is outside */
- l1_clip[0] = isect;
- l1_clip[1] = rect->ymin;
- ok1 = 1;
- }
- else {
- l2_clip[0] = isect;
- l2_clip[1] = rect->ymin;
- ok2 = 2;
- }
- }
+ /* line inside rect */
+ if (ok1 && ok2) {
+ return 1;
+ }
- if (ok1 && ok2) {
- return true;
+ /* top/bottom */
+ if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= cliprect->xmin) &&
+ (isect <= cliprect->xmax)) {
+ if (l1[1] < l2[1]) { /* line 1 is outside */
+ l1_clip[0] = isect;
+ l1_clip[1] = rect->ymin;
+ ok1 = 1;
}
-
- if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= cliprect->xmin) &&
- (isect <= cliprect->xmax)) {
- if (l1[1] > l2[1]) { /* line 1 is outside */
- l1_clip[0] = isect;
- l1_clip[1] = rect->ymax;
- ok1 = 1;
- }
- else {
- l2_clip[0] = isect;
- l2_clip[1] = rect->ymax;
- ok2 = 2;
- }
+ else {
+ l2_clip[0] = isect;
+ l2_clip[1] = rect->ymin;
+ ok2 = 2;
}
+ }
- if (ok1 && ok2) {
- return true;
- }
+ if (ok1 && ok2) {
+ return true;
+ }
- /* left/right */
- if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= cliprect->ymin) &&
- (isect <= cliprect->ymax)) {
- if (l1[0] < l2[0]) { /* line 1 is outside */
- l1_clip[0] = rect->xmin;
- l1_clip[1] = isect;
- ok1 = 1;
- }
- else {
- l2_clip[0] = rect->xmin;
- l2_clip[1] = isect;
- ok2 = 2;
- }
+ if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= cliprect->xmin) &&
+ (isect <= cliprect->xmax)) {
+ if (l1[1] > l2[1]) { /* line 1 is outside */
+ l1_clip[0] = isect;
+ l1_clip[1] = rect->ymax;
+ ok1 = 1;
}
-
- if (ok1 && ok2) {
- return true;
+ else {
+ l2_clip[0] = isect;
+ l2_clip[1] = rect->ymax;
+ ok2 = 2;
}
+ }
- if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= cliprect->ymin) &&
- (isect <= cliprect->ymax)) {
- if (l1[0] > l2[0]) { /* line 1 is outside */
- l1_clip[0] = rect->xmax;
- l1_clip[1] = isect;
- ok1 = 1;
- }
- else {
- l2_clip[0] = rect->xmax;
- l2_clip[1] = isect;
- ok2 = 2;
- }
+ if (ok1 && ok2) {
+ return true;
+ }
+
+ /* left/right */
+ if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= cliprect->ymin) &&
+ (isect <= cliprect->ymax)) {
+ if (l1[0] < l2[0]) { /* line 1 is outside */
+ l1_clip[0] = rect->xmin;
+ l1_clip[1] = isect;
+ ok1 = 1;
}
+ else {
+ l2_clip[0] = rect->xmin;
+ l2_clip[1] = isect;
+ ok2 = 2;
+ }
+ }
- if (ok1 && ok2) {
- return true;
+ if (ok1 && ok2) {
+ return true;
+ }
+
+ if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= cliprect->ymin) &&
+ (isect <= cliprect->ymax)) {
+ if (l1[0] > l2[0]) { /* line 1 is outside */
+ l1_clip[0] = rect->xmax;
+ l1_clip[1] = isect;
+ ok1 = 1;
}
else {
- return false;
+ l2_clip[0] = rect->xmax;
+ l2_clip[1] = isect;
+ ok2 = 2;
}
}
+
+ if (ok1 && ok2) {
+ return true;
+ }
+ return false;
}
/**
@@ -2299,7 +2278,7 @@ static bool project_bucket_isect_circle(const float cent[2],
false;
}
/* top left test */
- else if (cent[1] > bucket_bounds->ymax) {
+ if (cent[1] > bucket_bounds->ymax) {
return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymax) <
radius_squared) ?
true :
@@ -2315,7 +2294,7 @@ static bool project_bucket_isect_circle(const float cent[2],
false;
}
/* top right test */
- else if (cent[1] > bucket_bounds->ymax) {
+ if (cent[1] > bucket_bounds->ymax) {
return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymax) <
radius_squared) ?
true :
@@ -2670,7 +2649,8 @@ static void project_bucket_clip_face(const bool is_ortho,
*tot = 4;
return;
}
- else {
+
+ {
/* The Complicated Case!
*
* The 2 cases above are where the face is inside the bucket
@@ -3584,8 +3564,8 @@ static bool project_bucket_face_isect(ProjPaintState *ps,
int bucket_y,
const MLoopTri *lt)
{
- /* TODO - replace this with a tricker method that uses sideofline for all
- * screenCoords's edges against the closest bucket corner */
+ /* TODO - replace this with a trickier method that uses side-of-line for all
+ * #ProjPaintState.screenCoords edges against the closest bucket corner. */
const int lt_vtri[3] = {PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt)};
rctf bucket_bounds;
float p1[2], p2[2], p3[2], p4[2];
@@ -4209,9 +4189,7 @@ static bool project_paint_check_face_sel(const ProjPaintState *ps,
return ((mp->flag & ME_FACE_SEL) != 0);
}
- else {
- return true;
- }
+ return true;
}
typedef struct {
@@ -5906,8 +5884,6 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
ps->dither = settings->imapaint.dither;
ps->use_colormanagement = BKE_scene_check_color_management_enabled(CTX_data_scene(C));
-
- return;
}
void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int mode)
@@ -6146,19 +6122,18 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Could not get valid evaluated mesh");
return OPERATOR_CANCELLED;
}
- else {
- float pos[2] = {0.0, 0.0};
- float lastpos[2] = {0.0, 0.0};
- int a;
- project_paint_op(&ps, lastpos, pos);
+ float pos[2] = {0.0, 0.0};
+ float lastpos[2] = {0.0, 0.0};
+ int a;
- project_image_refresh_tagged(&ps);
+ project_paint_op(&ps, lastpos, pos);
- for (a = 0; a < ps.image_tot; a++) {
- GPU_free_image(ps.projImages[a].ima);
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima);
- }
+ project_image_refresh_tagged(&ps);
+
+ for (a = 0; a < ps.image_tot; a++) {
+ BKE_image_free_gputextures(ps.projImages[a].ima);
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima);
}
project_paint_end(&ps);
@@ -6198,7 +6173,7 @@ static bool texture_paint_image_from_view_poll(bContext *C)
CTX_wm_operator_poll_msg_set(C, "No 3D viewport found to create image from");
return false;
}
- if (G.background || !GPU_is_initialized()) {
+ if (G.background || !GPU_is_init()) {
return false;
}
return true;
@@ -6699,9 +6674,7 @@ static int texture_paint_add_texture_paint_slot_exec(bContext *C, wmOperator *op
if (proj_paint_add_slot(C, op)) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static void get_default_texture_layer_name_for_object(Object *ob,
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 0d4e957c77b..65f78a2d988 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -21,8 +21,7 @@
* \ingroup edsculpt
*/
-#ifndef __PAINT_INTERN_H__
-#define __PAINT_INTERN_H__
+#pragma once
struct ARegion;
struct Brush;
@@ -341,6 +340,7 @@ typedef enum {
void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot);
void PAINT_OT_mask_lasso_gesture(struct wmOperatorType *ot);
+void PAINT_OT_mask_box_gesture(struct wmOperatorType *ot);
/* paint_curve.c */
void PAINTCURVE_OT_new(struct wmOperatorType *ot);
@@ -366,5 +366,3 @@ void paint_delete_blur_kernel(BlurKernel *);
/* paint curve defines */
#define PAINT_CURVE_NUM_SEGMENTS 40
-
-#endif /* __PAINT_INTERN_H__ */
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 6e0402fc6e0..c255cbcaaab 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -25,6 +25,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "DNA_vec_types.h"
#include "BLI_bitmap_draw_2d.h"
#include "BLI_lasso_2d.h"
@@ -290,27 +291,32 @@ static void mask_box_select_task_cb(void *__restrict userdata,
}
}
-bool ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select)
+static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op)
{
+ ViewContext vc;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Sculpt *sd = vc->scene->toolsettings->sculpt;
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
+
+ Sculpt *sd = vc.scene->toolsettings->sculpt;
BoundBox bb;
float clip_planes[4][4];
float clip_planes_final[4][4];
- ARegion *region = vc->region;
- Object *ob = vc->obact;
- PaintMaskFloodMode mode;
+ ARegion *region = vc.region;
+ Object *ob = vc.obact;
bool multires;
PBVH *pbvh;
PBVHNode **nodes;
int totnode;
int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
- mode = PAINT_MASK_FLOOD_VALUE;
- float value = select ? 1.0f : 0.0f;
+ const PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode");
+ const float value = RNA_float_get(op->ptr, "value");
+
+ rcti rect;
+ WM_operator_properties_border_to_rcti(op, &rect);
/* Transform the clip planes in object space. */
- ED_view3d_clipping_calc(&bb, clip_planes, vc->region, vc->obact, rect);
+ ED_view3d_clipping_calc(&bb, clip_planes, vc.region, vc.obact, &rect);
BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
pbvh = ob->sculpt->pbvh;
@@ -589,3 +595,33 @@ void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
0.0f,
1.0f);
}
+
+void PAINT_OT_mask_box_gesture(wmOperatorType *ot)
+{
+ ot->name = "Mask Box Gesture";
+ ot->idname = "PAINT_OT_mask_box_gesture";
+ ot->description = "Add mask within the box as you move the brush";
+
+ ot->invoke = WM_gesture_box_invoke;
+ ot->modal = WM_gesture_box_modal;
+ ot->exec = paint_mask_gesture_box_exec;
+
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER;
+
+ /* Properties. */
+ WM_operator_properties_border(ot);
+
+ RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL);
+ RNA_def_float(
+ ot->srna,
+ "value",
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ "Value",
+ "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
+ 0.0f,
+ 1.0f);
+}
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 191ae1da343..0fe6e259d8d 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -246,7 +246,11 @@ static int palette_color_add_exec(bContext *C, wmOperator *UNUSED(op))
color = BKE_palette_color_add(palette);
palette->active_color = BLI_listbase_count(&palette->colors) - 1;
- if (ELEM(mode, PAINT_MODE_TEXTURE_3D, PAINT_MODE_TEXTURE_2D, PAINT_MODE_VERTEX)) {
+ if (ELEM(mode,
+ PAINT_MODE_TEXTURE_3D,
+ PAINT_MODE_TEXTURE_2D,
+ PAINT_MODE_VERTEX,
+ PAINT_MODE_SCULPT)) {
copy_v3_v3(color->rgb, BKE_brush_color_get(scene, brush));
color->value = 0.0;
}
@@ -695,14 +699,12 @@ static Brush *brush_tool_toggle(Main *bmain, Paint *paint, Brush *brush_orig, co
return br;
}
- else if (brush_orig->toggle_brush) {
+ if (brush_orig->toggle_brush) {
/* if current brush is using the desired tool, try to toggle
* back to the previously selected brush. */
return brush_orig->toggle_brush;
}
- else {
- return NULL;
- }
+ return NULL;
}
static bool brush_generic_tool_set(bContext *C,
@@ -751,9 +753,7 @@ static bool brush_generic_tool_set(bContext *C,
return true;
}
- else {
- return false;
- }
+ return false;
}
static const ePaintMode brush_select_paint_modes[] = {
@@ -1356,6 +1356,7 @@ void ED_operatortypes_paint(void)
/* paint masking */
WM_operatortype_append(PAINT_OT_mask_flood_fill);
WM_operatortype_append(PAINT_OT_mask_lasso_gesture);
+ WM_operatortype_append(PAINT_OT_mask_box_gesture);
}
void ED_keymap_paint(wmKeyConfig *keyconf)
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 447d5373a48..b9361726826 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -696,9 +696,7 @@ static float paint_space_stroke_spacing(bContext *C,
if (paint_stroke_use_scene_spacing(brush, mode)) {
return max_ff(0.001f, size_clamp * spacing / 50.f);
}
- else {
- return max_ff(stroke->zoom_2d, size_clamp * spacing / 50.0f);
- }
+ return max_ff(stroke->zoom_2d, size_clamp * spacing / 50.0f);
}
static float paint_stroke_overlapped_curve(Brush *br, float x, float spacing)
@@ -751,9 +749,7 @@ static float paint_stroke_integrate_overlap(Brush *br, float factor)
if (max == 0.0f) {
return 1.0f;
}
- else {
- return 1.0f / max;
- }
+ return 1.0f / max;
}
static float paint_space_stroke_spacing_variable(bContext *C,
@@ -781,10 +777,9 @@ static float paint_space_stroke_spacing_variable(bContext *C,
return 0.5f * (last_spacing + new_spacing);
}
- else {
- /* no size pressure */
- return paint_space_stroke_spacing(C, scene, stroke, 1.0f, pressure);
- }
+
+ /* no size pressure */
+ return paint_space_stroke_spacing(C, scene, stroke, 1.0f, pressure);
}
/* For brushes with stroke spacing enabled, moves mouse in steps
@@ -925,9 +920,9 @@ PaintStroke *paint_stroke_new(bContext *C,
ups->average_stroke_counter = 0;
/* initialize here to avoid initialization conflict with threaded strokes */
- BKE_curvemapping_initialize(br->curve);
+ BKE_curvemapping_init(br->curve);
if (p->flags & PAINT_USE_CAVITY_MASK) {
- BKE_curvemapping_initialize(p->cavity_curve);
+ BKE_curvemapping_init(p->cavity_curve);
}
BKE_paint_set_overlay_override(br->overlay_flags);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index c84a3b9cbfc..6c5d6f4ee4e 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -55,9 +55,10 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "GPU_glew.h"
+#include "GPU_framebuffer.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
+#include "GPU_texture.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
@@ -246,7 +247,7 @@ static void imapaint_project(float matrix[4][4], const float co[3], float pco[4]
}
static void imapaint_tri_weights(float matrix[4][4],
- const GLint view[4],
+ const int view[4],
const float v1[3],
const float v2[3],
const float v3[3],
@@ -300,7 +301,7 @@ static void imapaint_pick_uv(
int i, findex;
float p[2], w[3], absw, minabsw;
float matrix[4][4], proj[4][4];
- GLint view[4];
+ int view[4];
const eImagePaintMode mode = scene->toolsettings->imapaint.mode;
const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval);
@@ -576,20 +577,16 @@ void paint_sample_color(
}
if (!sample_success) {
- glReadBuffer(GL_FRONT);
- glReadPixels(
- x + region->winrct.xmin, y + region->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
- glReadBuffer(GL_BACK);
+ GPU_frontbuffer_read_pixels(
+ x + region->winrct.xmin, y + region->winrct.ymin, 1, 1, 4, GPU_DATA_UNSIGNED_BYTE, &col);
}
else {
return;
}
}
else {
- glReadBuffer(GL_FRONT);
- glReadPixels(
- x + region->winrct.xmin, y + region->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
- glReadBuffer(GL_BACK);
+ GPU_frontbuffer_read_pixels(
+ x + region->winrct.xmin, y + region->winrct.ymin, 1, 1, 4, GPU_DATA_UNSIGNED_BYTE, &col);
}
cp = (uchar *)&col;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 7ac778630ac..e6b0c2fbd1b 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -137,13 +137,11 @@ static float view_angle_limits_apply_falloff(const struct NormalAnglePrecalc *a,
/* outsize the normal limit */
return false;
}
- else if (angle_cos < a->angle_inner__cos) {
+ if (angle_cos < a->angle_inner__cos) {
*mask_p *= (a->angle - acosf(angle_cos)) / a->angle_range;
return true;
}
- else {
- return true;
- }
+ return true;
}
static bool vwpaint_use_normal(const VPaint *vp)
@@ -405,12 +403,10 @@ static float wpaint_clamp_monotonic(float oldval, float curval, float newval)
if (newval < oldval) {
return MIN2(newval, curval);
}
- else if (newval > oldval) {
+ if (newval > oldval) {
return MAX2(newval, curval);
}
- else {
- return newval;
- }
+ return newval;
}
static float wpaint_undo_lock_relative(
@@ -535,7 +531,7 @@ static bool do_weight_paint_normalize_all_locked(MDeformVert *dvert,
return (lock_weight == 1.0f);
}
- else if (sum_unlock != 0.0f) {
+ if (sum_unlock != 0.0f) {
fac = (1.0f - lock_weight) / sum_unlock;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
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 addf7e9f868..d05b1673c9a 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
@@ -115,9 +115,7 @@ static int vertex_color_set_exec(bContext *C, wmOperator *UNUSED(op))
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void PAINT_OT_vertex_color_set(wmOperatorType *ot)
@@ -182,9 +180,7 @@ static int vertex_paint_from_weight_exec(bContext *C, wmOperator *UNUSED(op))
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void PAINT_OT_vertex_color_from_weight(wmOperatorType *ot)
@@ -210,7 +206,7 @@ void PAINT_OT_vertex_color_from_weight(wmOperatorType *ot)
/** \name Smooth Vertex Colors Operator
* \{ */
-static void vertex_color_smooth_looptag(Mesh *me, bool *mlooptag)
+static void vertex_color_smooth_looptag(Mesh *me, const bool *mlooptag)
{
const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
const MPoly *mp;
@@ -323,9 +319,7 @@ static int vertex_color_smooth_exec(bContext *C, wmOperator *UNUSED(op))
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void PAINT_OT_vertex_color_smooth(wmOperatorType *ot)
@@ -402,9 +396,7 @@ static int vertex_color_brightness_contrast_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void PAINT_OT_vertex_color_brightness_contrast(wmOperatorType *ot)
@@ -469,9 +461,7 @@ static int vertex_color_hsv_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void PAINT_OT_vertex_color_hsv(wmOperatorType *ot)
@@ -509,9 +499,7 @@ static int vertex_color_invert_exec(bContext *C, wmOperator *UNUSED(op))
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void PAINT_OT_vertex_color_invert(wmOperatorType *ot)
@@ -555,9 +543,7 @@ static int vertex_color_levels_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void PAINT_OT_vertex_color_levels(wmOperatorType *ot)
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c
index c26db3e265b..637ce8193c1 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c
@@ -220,7 +220,7 @@ BLI_INLINE uint mcol_lighten(uint col_src, uint col_dst, int fac)
if (fac == 0) {
return col_src;
}
- else if (fac >= 255) {
+ if (fac >= 255) {
return col_dst;
}
@@ -254,7 +254,7 @@ BLI_INLINE uint mcol_darken(uint col_src, uint col_dst, int fac)
if (fac == 0) {
return col_src;
}
- else if (fac >= 255) {
+ if (fac >= 255) {
return col_dst;
}
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 08ffd8e620e..83d76c166ce 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -272,9 +272,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void PAINT_OT_weight_sample(wmOperatorType *ot)
@@ -541,9 +539,7 @@ static int weight_paint_set_exec(bContext *C, wmOperator *op)
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void PAINT_OT_weight_set(wmOperatorType *ot)
@@ -815,7 +811,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
VPaint *wp = ts->wpaint;
struct Brush *brush = BKE_paint_brush(&wp->paint);
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
data.brush = brush;
data.weightpaint = BKE_brush_weight_get(scene, brush);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 178b29edfff..d0b834a3dc0 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -139,9 +139,7 @@ const float *SCULPT_vertex_co_get(SculptSession *ss, int index)
const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh);
return mverts[index].co;
}
- else {
- return ss->mvert[index].co;
- }
+ return ss->mvert[index].co;
}
case PBVH_BMESH:
return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co;
@@ -198,7 +196,7 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
}
}
-static const float *sculpt_vertex_persistent_co_get(SculptSession *ss, int index)
+const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index)
{
if (ss->persistent_base) {
return ss->persistent_base[index].co;
@@ -206,7 +204,7 @@ static const float *sculpt_vertex_persistent_co_get(SculptSession *ss, int index
return SCULPT_vertex_co_get(ss, index);
}
-static void sculpt_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3])
+void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3])
{
if (ss->persistent_base) {
copy_v3_v3(no, ss->persistent_base[index].no);
@@ -391,7 +389,7 @@ bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, int index)
return true;
}
-bool SCULPT_vertex_all_face_sets_visible_get(SculptSession *ss, int index)
+bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, int index)
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
@@ -549,28 +547,82 @@ void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss)
}
}
-bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index)
+static bool sculpt_check_unique_face_set_in_base_mesh(SculptSession *ss, int index)
{
- switch (BKE_pbvh_type(ss->pbvh)) {
- case PBVH_FACES: {
- MeshElemMap *vert_map = &ss->pmap[index];
- int face_set = -1;
- for (int i = 0; i < ss->pmap[index].count; i++) {
- if (face_set == -1) {
- face_set = abs(ss->face_sets[vert_map->indices[i]]);
+ MeshElemMap *vert_map = &ss->pmap[index];
+ int face_set = -1;
+ for (int i = 0; i < ss->pmap[index].count; i++) {
+ if (face_set == -1) {
+ face_set = abs(ss->face_sets[vert_map->indices[i]]);
+ }
+ else {
+ if (abs(ss->face_sets[vert_map->indices[i]]) != face_set) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/**
+ * Checks if the face sets of the adjacent faces to the edge between \a v1 and \a v2
+ * in the base mesh are equal.
+ */
+static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss, int v1, int v2)
+{
+ MeshElemMap *vert_map = &ss->pmap[v1];
+ int p1 = -1, p2 = -1;
+ for (int i = 0; i < ss->pmap[v1].count; i++) {
+ MPoly *p = &ss->mpoly[vert_map->indices[i]];
+ for (int l = 0; l < p->totloop; l++) {
+ MLoop *loop = &ss->mloop[p->loopstart + l];
+ if (loop->v == v2) {
+ if (p1 == -1) {
+ p1 = vert_map->indices[i];
+ break;
}
- else {
- if (abs(ss->face_sets[vert_map->indices[i]]) != face_set) {
- return false;
- }
+
+ if (p2 == -1) {
+ p2 = vert_map->indices[i];
+ break;
}
}
- return true;
+ }
+ }
+
+ if (p1 != -1 && p2 != -1) {
+ return abs(ss->face_sets[p1]) == (ss->face_sets[p2]);
+ }
+ return true;
+}
+
+bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index)
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES: {
+ return sculpt_check_unique_face_set_in_base_mesh(ss, index);
}
case PBVH_BMESH:
return false;
- case PBVH_GRIDS:
- return true;
+ case PBVH_GRIDS: {
+ const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
+ const int grid_index = index / key->grid_area;
+ const int vertex_index = index - grid_index * key->grid_area;
+ const SubdivCCGCoord coord = {.grid_index = grid_index,
+ .x = vertex_index % key->grid_size,
+ .y = vertex_index / key->grid_size};
+ int v1, v2;
+ const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
+ ss->subdiv_ccg, &coord, ss->mloop, ss->mpoly, &v1, &v2);
+ switch (adjacency) {
+ case SUBDIV_CCG_ADJACENT_VERTEX:
+ return sculpt_check_unique_face_set_in_base_mesh(ss, v1);
+ case SUBDIV_CCG_ADJACENT_EDGE:
+ return sculpt_check_unique_face_set_for_edge_in_base_mesh(ss, v1, v2);
+ case SUBDIV_CCG_ADJACENT_NONE:
+ return true;
+ }
+ }
}
return false;
}
@@ -737,44 +789,49 @@ void SCULPT_vertex_neighbors_get(SculptSession *ss,
}
}
-bool SCULPT_vertex_is_boundary(SculptSession *ss, const int index)
+static bool sculpt_check_boundary_vertex_in_base_mesh(const SculptSession *ss, const int index)
+{
+ BLI_assert(ss->vertex_info.boundary);
+ return BLI_BITMAP_TEST(ss->vertex_info.boundary, index);
+}
+
+bool SCULPT_vertex_is_boundary(const SculptSession *ss, const int index)
{
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES: {
- const MeshElemMap *vert_map = &ss->pmap[index];
-
- if (vert_map->count <= 1) {
- return false;
- }
-
if (!SCULPT_vertex_all_face_sets_visible_get(ss, index)) {
- return false;
- }
-
- for (int i = 0; i < vert_map->count; i++) {
- const MPoly *p = &ss->mpoly[vert_map->indices[i]];
- unsigned f_adj_v[2];
- if (poly_get_adj_loops_from_vert(p, ss->mloop, index, f_adj_v) != -1) {
- int j;
- for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
- if (!(vert_map->count != 2 || ss->pmap[f_adj_v[j]].count <= 2)) {
- return false;
- }
- }
- }
+ return true;
}
- return true;
+ return sculpt_check_boundary_vertex_in_base_mesh(ss, index);
}
case PBVH_BMESH: {
BMVert *v = BM_vert_at_index(ss->bm, index);
return BM_vert_is_boundary(v);
}
- case PBVH_GRIDS:
- return true;
+ case PBVH_GRIDS: {
+ const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
+ const int grid_index = index / key->grid_area;
+ const int vertex_index = index - grid_index * key->grid_area;
+ const SubdivCCGCoord coord = {.grid_index = grid_index,
+ .x = vertex_index % key->grid_size,
+ .y = vertex_index / key->grid_size};
+ int v1, v2;
+ const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
+ ss->subdiv_ccg, &coord, ss->mloop, ss->mpoly, &v1, &v2);
+ switch (adjacency) {
+ case SUBDIV_CCG_ADJACENT_VERTEX:
+ return sculpt_check_boundary_vertex_in_base_mesh(ss, v1);
+ case SUBDIV_CCG_ADJACENT_EDGE:
+ return sculpt_check_boundary_vertex_in_base_mesh(ss, v1) &&
+ sculpt_check_boundary_vertex_in_base_mesh(ss, v2);
+ case SUBDIV_CCG_ADJACENT_NONE:
+ return false;
+ }
+ }
}
- return true;
+ return false;
}
/* Utilities */
@@ -1520,9 +1577,7 @@ bool SCULPT_brush_test_sphere(SculptBrushTest *test, const float co[3])
test->dist = sqrtf(distsq);
return true;
}
- else {
- return false;
- }
+ return false;
}
bool SCULPT_brush_test_sphere_sq(SculptBrushTest *test, const float co[3])
@@ -1536,9 +1591,7 @@ bool SCULPT_brush_test_sphere_sq(SculptBrushTest *test, const float co[3])
test->dist = distsq;
return true;
}
- else {
- return false;
- }
+ return false;
}
bool SCULPT_brush_test_sphere_fast(const SculptBrushTest *test, const float co[3])
@@ -1562,9 +1615,7 @@ bool SCULPT_brush_test_circle_sq(SculptBrushTest *test, const float co[3])
test->dist = distsq;
return true;
}
- else {
- return false;
- }
+ return false;
}
bool SCULPT_brush_test_cube(SculptBrushTest *test,
@@ -1612,10 +1663,8 @@ bool SCULPT_brush_test_cube(SculptBrushTest *test,
test->dist = 0.0f;
return true;
}
- else {
- /* Outside the square. */
- return false;
- }
+ /* Outside the square. */
+ return false;
}
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss,
@@ -1641,10 +1690,8 @@ const float *SCULPT_brush_frontface_normal_from_falloff_shape(SculptSession *ss,
if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
return ss->cache->sculpt_normal_symm;
}
- else {
- /* PAINT_FALLOFF_SHAPE_TUBE */
- return ss->cache->view_normal;
- }
+ /* PAINT_FALLOFF_SHAPE_TUBE */
+ return ss->cache->view_normal;
}
static float frontface(const Brush *br,
@@ -1666,9 +1713,7 @@ static float frontface(const Brush *br,
}
return dot > 0.0f ? dot : 0.0f;
}
- else {
- return 1.0f;
- }
+ return 1.0f;
}
#if 0
@@ -1728,9 +1773,7 @@ static float calc_overlap(StrokeCache *cache, const char symm, const char axis,
if (distsq <= 4.0f * (cache->radius_squared)) {
return (2.0f * (cache->radius) - sqrtf(distsq)) / (2.0f * (cache->radius));
}
- else {
- return 0.0f;
- }
+ return 0.0f;
}
static float calc_radial_symmetry_feather(Sculpt *sd,
@@ -1768,9 +1811,7 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache)
return 1.0f / overlap;
}
- else {
- return 1.0f;
- }
+ return 1.0f;
}
/** \name Calculate Normal and Center
@@ -2378,7 +2419,7 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
/* Hardness. */
float final_len = len;
- const float hardness = br->hardness;
+ const float hardness = cache->paint_brush.hardness;
float p = len / cache->radius;
if (p < hardness) {
final_len = 0.0f;
@@ -2418,7 +2459,10 @@ bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v)
}
float t[3], bb_min[3], bb_max[3];
- if (data->ignore_fully_masked) {
+ if (data->ignore_fully_ineffective) {
+ if (BKE_pbvh_node_fully_hidden_get(node)) {
+ return false;
+ }
if (BKE_pbvh_node_fully_masked_get(node)) {
return false;
}
@@ -2454,7 +2498,7 @@ bool SCULPT_search_circle_cb(PBVHNode *node, void *data_v)
SculptSearchCircleData *data = data_v;
float bb_min[3], bb_max[3];
- if (data->ignore_fully_masked) {
+ if (data->ignore_fully_ineffective) {
if (BKE_pbvh_node_fully_masked_get(node)) {
return false;
}
@@ -2507,7 +2551,7 @@ static PBVHNode **sculpt_pbvh_gather_cursor_update(Object *ob,
.sd = sd,
.radius_squared = ss->cursor_radius,
.original = use_original,
- .ignore_fully_masked = false,
+ .ignore_fully_ineffective = false,
.center = NULL,
};
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
@@ -2532,7 +2576,7 @@ static PBVHNode **sculpt_pbvh_gather_generic(Object *ob,
.sd = sd,
.radius_squared = square_f(ss->cache->radius * radius_scale),
.original = use_original,
- .ignore_fully_masked = brush->sculpt_tool != SCULPT_TOOL_MASK,
+ .ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK,
.center = NULL,
};
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
@@ -2548,7 +2592,7 @@ static PBVHNode **sculpt_pbvh_gather_generic(Object *ob,
ss->cursor_radius,
.original = use_original,
.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc,
- .ignore_fully_masked = brush->sculpt_tool != SCULPT_TOOL_MASK,
+ .ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK,
};
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode);
}
@@ -2923,7 +2967,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
/* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
* initialize before threads so they can do curve mapping. */
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
/* Threaded loop over nodes. */
SculptThreadedTaskData data = {
@@ -3000,7 +3044,7 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
/* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
* initialize before threads so they can do curve mapping. */
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
/* Threaded loop over nodes. */
SculptThreadedTaskData data = {
@@ -3057,11 +3101,23 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata,
thread_id);
float current_disp[3];
float current_disp_norm[3];
- float final_disp[3];
- zero_v3(final_disp);
- sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ float final_disp[3] = {0.0f, 0.0f, 0.0f};
+
+ switch (brush->slide_deform_type) {
+ case BRUSH_SLIDE_DEFORM_DRAG:
+ sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ break;
+ case BRUSH_SLIDE_DEFORM_PINCH:
+ sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
+ break;
+ case BRUSH_SLIDE_DEFORM_EXPAND:
+ sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
+ break;
+ }
+
normalize_v3_v3(current_disp_norm, current_disp);
mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
+
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
float vertex_disp[3];
@@ -3092,21 +3148,49 @@ void SCULPT_relax_vertex(SculptSession *ss,
{
float smooth_pos[3];
float final_disp[3];
- int count = 0;
+ float boundary_normal[3];
+ int avg_count = 0;
+ int neighbor_count = 0;
zero_v3(smooth_pos);
+ zero_v3(boundary_normal);
+ const bool is_boundary = SCULPT_vertex_is_boundary(ss, vd->index);
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->index, ni) {
+ neighbor_count++;
if (!filter_boundary_face_sets ||
(filter_boundary_face_sets && !SCULPT_vertex_has_unique_face_set(ss, ni.index))) {
- add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
- count++;
+
+ /* When the vertex to relax is boundary, use only connected boundary vertices for the average
+ * position. */
+ if (is_boundary) {
+ if (SCULPT_vertex_is_boundary(ss, ni.index)) {
+ add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
+ avg_count++;
+
+ /* Calculate a normal for the constraint plane using the edges of the boundary. */
+ float to_neighbor[3];
+ sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co);
+ normalize_v3(to_neighbor);
+ add_v3_v3(boundary_normal, to_neighbor);
+ }
+ }
+ else {
+ add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
+ avg_count++;
+ }
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
- if (count > 0) {
- mul_v3_fl(smooth_pos, 1.0f / (float)count);
+ /* Don't modify corner vertices. */
+ if (neighbor_count <= 2) {
+ copy_v3_v3(r_final_pos, vd->co);
+ return;
+ }
+
+ if (avg_count > 0) {
+ mul_v3_fl(smooth_pos, 1.0f / (float)avg_count);
}
else {
copy_v3_v3(r_final_pos, vd->co);
@@ -3116,11 +3200,12 @@ void SCULPT_relax_vertex(SculptSession *ss,
float plane[4];
float smooth_closest_plane[3];
float vno[3];
- if (vd->no) {
- normal_short_to_float_v3(vno, vd->no);
+
+ if (is_boundary && avg_count == 2) {
+ normalize_v3_v3(vno, boundary_normal);
}
else {
- copy_v3_v3(vno, vd->fno);
+ SCULPT_vertex_normal_get(ss, vd->index, vno);
}
if (is_zero_v3(vno)) {
@@ -3189,7 +3274,7 @@ static void do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
return;
}
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
SculptThreadedTaskData data = {
.sd = sd,
@@ -3201,6 +3286,7 @@ static void do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
if (ss->cache->alt_smooth) {
+ SCULPT_boundary_info_ensure(ob);
for (int i = 0; i < 4; i++) {
BLI_task_parallel_range(0, totnode, &data, do_topology_relax_task_cb_ex, &settings);
}
@@ -4256,9 +4342,9 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
float normal[3];
if (use_persistent_base) {
- sculpt_vertex_persistent_normal_get(ss, vi, normal);
+ SCULPT_vertex_persistent_normal_get(ss, vi, normal);
mul_v3_fl(normal, brush->height);
- madd_v3_v3v3fl(final_co, sculpt_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
+ madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
}
else {
normal_short_to_float_v3(normal, orig_data.no);
@@ -5405,11 +5491,15 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
/* Check for unsupported features. */
PBVHType type = BKE_pbvh_type(ss->pbvh);
if (brush->sculpt_tool == SCULPT_TOOL_PAINT && type != PBVH_FACES) {
- return;
+ if (!U.experimental.use_sculpt_vertex_colors) {
+ return;
+ }
}
if (brush->sculpt_tool == SCULPT_TOOL_SMEAR && type != PBVH_FACES) {
- return;
+ if (!U.experimental.use_sculpt_vertex_colors) {
+ return;
+ }
}
/* Build a list of all nodes that are potentially within the brush's area of influence */
@@ -5424,15 +5514,21 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
}
else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
- SculptSearchSphereData data = {
- .ss = ss,
- .sd = sd,
- .radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit)),
- .original = false,
- .ignore_fully_masked = false,
- .center = ss->cache->initial_location,
- };
- BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
+ if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
+ SculptSearchSphereData data = {
+ .ss = ss,
+ .sd = sd,
+ .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)),
+ .original = false,
+ .ignore_fully_ineffective = false,
+ .center = ss->cache->initial_location,
+ };
+ BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
+ }
+ else {
+ /* Gobal simulation, get all nodes. */
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ }
}
else {
const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true :
@@ -6064,6 +6160,14 @@ bool SCULPT_mode_poll(bContext *C)
return ob && ob->mode & OB_MODE_SCULPT;
}
+bool SCULPT_vertex_colors_poll(bContext *C)
+{
+ if (!U.experimental.use_sculpt_vertex_colors) {
+ return false;
+ }
+ return SCULPT_mode_poll(C);
+}
+
bool SCULPT_mode_poll_view3d(bContext *C)
{
return (SCULPT_mode_poll(C) && CTX_wm_region_view3d(C));
@@ -6293,7 +6397,7 @@ static void sculpt_update_cache_invariants(
brush = br;
cache->saved_smooth_size = BKE_brush_size_get(scene, brush);
BKE_brush_size_set(scene, brush, size);
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
}
}
}
@@ -6361,7 +6465,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);
+ cache->dial = BLI_dial_init(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD);
}
#undef PIXEL_INPUT_THRESHHOLD
@@ -6563,6 +6667,50 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
}
}
+static void sculpt_update_cache_paint_variants(StrokeCache *cache, const Brush *brush)
+{
+ cache->paint_brush.hardness = brush->hardness;
+ if (brush->paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE) {
+ cache->paint_brush.hardness *= brush->paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE_INVERT ?
+ 1.0f - cache->pressure :
+ cache->pressure;
+ }
+
+ cache->paint_brush.flow = brush->flow;
+ if (brush->paint_flags & BRUSH_PAINT_FLOW_PRESSURE) {
+ cache->paint_brush.flow *= brush->paint_flags & BRUSH_PAINT_FLOW_PRESSURE_INVERT ?
+ 1.0f - cache->pressure :
+ cache->pressure;
+ }
+
+ cache->paint_brush.wet_mix = brush->wet_mix;
+ if (brush->paint_flags & BRUSH_PAINT_WET_MIX_PRESSURE) {
+ cache->paint_brush.wet_mix *= brush->paint_flags & BRUSH_PAINT_WET_MIX_PRESSURE_INVERT ?
+ 1.0f - cache->pressure :
+ cache->pressure;
+
+ /* This makes wet mix more sensible in higher values, which allows to create brushes that have
+ * a wider pressure range were they only blend colors without applying too much of the brush
+ * color. */
+ cache->paint_brush.wet_mix = 1.0f - pow2f(1.0f - cache->paint_brush.wet_mix);
+ }
+
+ cache->paint_brush.wet_persistence = brush->wet_persistence;
+ if (brush->paint_flags & BRUSH_PAINT_WET_PERSISTENCE_PRESSURE) {
+ cache->paint_brush.wet_persistence = brush->paint_flags &
+ BRUSH_PAINT_WET_PERSISTENCE_PRESSURE_INVERT ?
+ 1.0f - cache->pressure :
+ cache->pressure;
+ }
+
+ cache->paint_brush.density = brush->density;
+ if (brush->paint_flags & BRUSH_PAINT_DENSITY_PRESSURE) {
+ cache->paint_brush.density = brush->paint_flags & BRUSH_PAINT_DENSITY_PRESSURE_INVERT ?
+ 1.0f - cache->pressure :
+ cache->pressure;
+ }
+}
+
/* Initialize the stroke cache variants from operator properties. */
static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, PointerRNA *ptr)
{
@@ -6629,6 +6777,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
cache->dyntopo_pixel_radius = ups->initial_pixel_radius;
}
+ sculpt_update_cache_paint_variants(cache, brush);
+
cache->radius_squared = cache->radius * cache->radius;
if (brush->flag & BRUSH_ANCHORED) {
@@ -7027,7 +7177,6 @@ static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession
static void sculpt_brush_stroke_init(bContext *C, wmOperator *op)
{
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
@@ -7050,6 +7199,14 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op)
is_smooth = sculpt_needs_connectivity_info(sd, brush, ss, mode);
needs_colors = ELEM(brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR);
+
+ if (needs_colors) {
+ BKE_sculpt_color_layer_create_if_needed(ob);
+ }
+
+ /* CTX_data_ensure_evaluated_depsgraph should be used at the end to include the updates of
+ * earlier steps modifying the data. */
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
BKE_sculpt_update_object_for_edit(depsgraph, ob, is_smooth, need_mask, needs_colors);
}
@@ -7058,11 +7215,16 @@ static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
+ /* For the cloth brush it makes more sense to not restore the mesh state to keep running the
+ * simulation from the previous state. */
+ if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
+ return;
+ }
+
/* Restore the mesh before continuing with anchored stroke. */
if ((brush->flag & BRUSH_ANCHORED) ||
((brush->sculpt_tool == SCULPT_TOOL_GRAB ||
- brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM ||
- brush->sculpt_tool == SCULPT_TOOL_CLOTH) &&
+ brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) &&
BKE_brush_use_size_pressure(brush)) ||
(brush->flag & BRUSH_DRAG_DOT)) {
@@ -7254,9 +7416,7 @@ static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const f
return true;
}
- else {
- return false;
- }
+ return false;
}
static void sculpt_stroke_update_step(bContext *C,
@@ -8007,6 +8167,14 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
return;
}
+ if (!ss->deform_modifiers_active) {
+ return;
+ }
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
+ return;
+ }
+
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
if (!ss->pmap) {
@@ -8116,7 +8284,7 @@ static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot)
ot->idname = "SCULPT_OT_vertex_to_loop_colors";
/* api callbacks */
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->exec = vertex_to_loop_colors_exec;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8179,7 +8347,7 @@ static void SCULPT_OT_loop_to_vertex_colors(wmOperatorType *ot)
ot->idname = "SCULPT_OT_loop_to_vertex_colors";
/* api callbacks */
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->exec = loop_to_vertex_colors_exec;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8204,7 +8372,6 @@ static int sculpt_sample_color_invoke(bContext *C,
copy_v3_v3(color_srgb, active_vertex_color);
IMB_colormanagement_scene_linear_to_srgb_v3(color_srgb);
BKE_brush_color_set(scene, brush, color_srgb);
- BKE_brush_alpha_set(scene, brush, active_vertex_color[3]);
WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
@@ -8220,7 +8387,7 @@ static void SCULPT_OT_sample_color(wmOperatorType *ot)
/* api callbacks */
ot->invoke = sculpt_sample_color_invoke;
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->flag = OPTYPE_REGISTER;
}
@@ -8229,7 +8396,7 @@ static void SCULPT_OT_sample_color(wmOperatorType *ot)
/* This allows the sculpt tools to work on meshes with multiple connected components as they had
* only one connected component. When initialized and enabled, the sculpt API will return extra
* connectivity neighbors that are not in the real mesh. These neighbors are calculated for each
- * vertex using the minimun distance to a vertex that is in a different connected component. */
+ * vertex using the minimum distance to a vertex that is in a different connected component. */
/* The fake neighbors first need to be ensured to be initialized.
* After that tools which needs fake neighbors functionality need to
@@ -8244,7 +8411,7 @@ static void SCULPT_OT_sample_color(wmOperatorType *ot)
* }
*
* Such approach allows to keep all the connectivity information ready for reuse
- * (withouy having lag prior to every stroke), but also makes it so the affect
+ * (without having lag prior to every stroke), but also makes it so the affect
* is localized to a specific brushes and tools only. */
enum {
@@ -8421,6 +8588,37 @@ static void sculpt_connected_components_ensure(Object *ob)
}
}
+void SCULPT_boundary_info_ensure(Object *object)
+{
+ SculptSession *ss = object->sculpt;
+ if (ss->vertex_info.boundary) {
+ return;
+ }
+
+ Mesh *base_mesh = BKE_mesh_from_object(object);
+ ss->vertex_info.boundary = BLI_BITMAP_NEW(base_mesh->totvert, "Boundary info");
+ int *adjacent_faces_edge_count = MEM_calloc_arrayN(
+ base_mesh->totedge, sizeof(int), "Adjacent face edge count");
+
+ for (int p = 0; p < base_mesh->totpoly; p++) {
+ MPoly *poly = &base_mesh->mpoly[p];
+ for (int l = 0; l < poly->totloop; l++) {
+ MLoop *loop = &base_mesh->mloop[l + poly->loopstart];
+ adjacent_faces_edge_count[loop->e]++;
+ }
+ }
+
+ for (int e = 0; e < base_mesh->totedge; e++) {
+ if (adjacent_faces_edge_count[e] < 2) {
+ MEdge *edge = &base_mesh->medge[e];
+ BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v1, true);
+ BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v2, true);
+ }
+ }
+
+ MEM_freeN(adjacent_faces_edge_count);
+}
+
void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist)
{
SculptSession *ss = ob->sculpt;
@@ -8701,6 +8899,11 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
+ /* Color data is not available in Multires. */
+ if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
+ return OPERATOR_CANCELLED;
+ }
+
if (!ss->vcol) {
return OPERATOR_CANCELLED;
}
@@ -8746,12 +8949,12 @@ static void SCULPT_OT_mask_by_color(wmOperatorType *ot)
/* api callbacks */
ot->invoke = sculpt_mask_by_color_invoke;
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->flag = OPTYPE_REGISTER;
ot->prop = RNA_def_boolean(
- ot->srna, "contiguous", false, "Contiguous", "Mask only contiguos color areas");
+ ot->srna, "contiguous", false, "Contiguous", "Mask only contiguous color areas");
ot->prop = RNA_def_boolean(ot->srna, "invert", false, "Invert", "Invert the generated mask");
ot->prop = RNA_def_boolean(
@@ -8759,7 +8962,7 @@ static void SCULPT_OT_mask_by_color(wmOperatorType *ot)
"preserve_previous_mask",
false,
"Preserve Previous Mask",
- "Preserve the previous mask and add or substract the new one generated by the colors");
+ "Preserve the previous mask and add or subtract the new one generated by the colors");
RNA_def_float(ot->srna,
"threshold",
@@ -8794,6 +8997,7 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_face_sets_init);
WM_operatortype_append(SCULPT_OT_cloth_filter);
WM_operatortype_append(SCULPT_OT_face_sets_edit);
+
WM_operatortype_append(SCULPT_OT_sample_color);
WM_operatortype_append(SCULPT_OT_loop_to_vertex_colors);
WM_operatortype_append(SCULPT_OT_vertex_to_loop_colors);
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.c b/source/blender/editors/sculpt_paint/sculpt_automasking.c
index bfa657147fd..c475259623a 100644
--- a/source/blender/editors/sculpt_paint/sculpt_automasking.c
+++ b/source/blender/editors/sculpt_paint/sculpt_automasking.c
@@ -89,21 +89,65 @@ bool SCULPT_is_automasking_enabled(const Sculpt *sd, const SculptSession *ss, co
return false;
}
-float SCULPT_automasking_factor_get(SculptSession *ss, int vert)
+static int sculpt_automasking_mode_effective_bits(const Sculpt *sculpt, const Brush *brush)
{
- if (ss->cache && ss->cache->automask) {
- return ss->cache->automask[vert];
+ return sculpt->automasking_flags | brush->automasking_flags;
+}
+
+static bool SCULPT_automasking_needs_cache(const Sculpt *sd, const Brush *brush)
+{
+
+ const int automasking_flags = sculpt_automasking_mode_effective_bits(sd, brush);
+ if (automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY) {
+ return true;
+ }
+ if (automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) {
+ return brush->automasking_boundary_edges_propagation_steps != 1;
}
- else {
+ if (automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS) {
+ return brush->automasking_boundary_edges_propagation_steps != 1;
+ }
+ return false;
+}
+
+float SCULPT_automasking_factor_get(SculptSession *ss, int vert)
+{
+ if (!ss->cache) {
return 1.0f;
}
+ /* If the cache is initialized with valid info, use the cache. This is used when the
+ * automasking information can't be computed in real time per vertex and needs to be
+ * initialized for the whole mesh when the stroke starts. */
+ if (ss->cache->automask_factor) {
+ return ss->cache->automask_factor[vert];
+ }
+
+ if (ss->cache->automask_settings.flags & BRUSH_AUTOMASKING_FACE_SETS) {
+ if (!SCULPT_vertex_has_face_set(ss, vert, ss->cache->automask_settings.initial_face_set)) {
+ return 0.0f;
+ }
+ }
+
+ if (ss->cache->automask_settings.flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) {
+ if (SCULPT_vertex_is_boundary(ss, vert)) {
+ return 0.0f;
+ }
+ }
+
+ if (ss->cache->automask_settings.flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS) {
+ if (!SCULPT_vertex_has_unique_face_set(ss, vert)) {
+ return 0.0f;
+ }
+ }
+
+ return 1.0f;
}
void SCULPT_automasking_end(Object *ob)
{
SculptSession *ss = ob->sculpt;
- if (ss->cache && ss->cache->automask) {
- MEM_freeN(ss->cache->automask);
+ if (ss->cache && ss->cache->automask_factor) {
+ MEM_freeN(ss->cache->automask_factor);
}
}
@@ -129,11 +173,12 @@ typedef struct AutomaskFloodFillData {
} AutomaskFloodFillData;
static bool automask_floodfill_cb(
- SculptSession *ss, int UNUSED(from_v), int to_v, bool UNUSED(is_duplicate), void *userdata)
+ SculptSession *ss, int from_v, int to_v, bool UNUSED(is_duplicate), void *userdata)
{
AutomaskFloodFillData *data = userdata;
data->automask_factor[to_v] = 1.0f;
+ data->automask_factor[from_v] = 1.0f;
return (!data->use_radius ||
SCULPT_is_vertex_inside_brush_radius_symm(
SCULPT_vertex_co_get(ss, to_v), data->location, data->radius, data->symm));
@@ -155,7 +200,7 @@ static float *SCULPT_topology_automasking_init(Sculpt *sd, Object *ob, float *au
const int totvert = SCULPT_vertex_count_get(ss);
for (int i = 0; i < totvert; i++) {
- ss->cache->automask[i] = 0.0f;
+ ss->cache->automask_factor[i] = 0.0f;
}
/* Flood fill automask to connected vertices. Limited to vertices inside
@@ -211,7 +256,7 @@ float *SCULPT_boundary_automasking_init(Object *ob,
{
SculptSession *ss = ob->sculpt;
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) {
+ if (!ss->pmap) {
BLI_assert(!"Boundary Edges masking: pmap missing");
return NULL;
}
@@ -223,7 +268,7 @@ float *SCULPT_boundary_automasking_init(Object *ob,
edge_distance[i] = EDGE_DISTANCE_INF;
switch (mode) {
case AUTOMASK_INIT_BOUNDARY_EDGES:
- if (!SCULPT_vertex_is_boundary(ss, i)) {
+ if (SCULPT_vertex_is_boundary(ss, i)) {
edge_distance[i] = 0;
}
break;
@@ -261,6 +306,14 @@ float *SCULPT_boundary_automasking_init(Object *ob,
return automask_factor;
}
+static void SCULPT_stroke_automasking_settings_update(SculptSession *ss, Sculpt *sd, Brush *brush)
+{
+ BLI_assert(ss->cache);
+
+ ss->cache->automask_settings.flags = sculpt_automasking_mode_effective_bits(sd, brush);
+ ss->cache->automask_settings.initial_face_set = SCULPT_active_face_set_get(ss);
+}
+
void SCULPT_automasking_init(Sculpt *sd, Object *ob)
{
SculptSession *ss = ob->sculpt;
@@ -271,20 +324,26 @@ void SCULPT_automasking_init(Sculpt *sd, Object *ob)
return;
}
- ss->cache->automask = MEM_callocN(sizeof(float) * SCULPT_vertex_count_get(ss),
- "automask_factor");
+ SCULPT_stroke_automasking_settings_update(ss, sd, brush);
+ SCULPT_boundary_info_ensure(ob);
+
+ if (!SCULPT_automasking_needs_cache(sd, brush)) {
+ return;
+ }
+
+ ss->cache->automask_factor = MEM_malloc_arrayN(totvert, sizeof(float), "automask_factor");
for (int i = 0; i < totvert; i++) {
- ss->cache->automask[i] = 1.0f;
+ ss->cache->automask_factor[i] = 1.0f;
}
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_TOPOLOGY)) {
SCULPT_vertex_random_access_init(ss);
- SCULPT_topology_automasking_init(sd, ob, ss->cache->automask);
+ SCULPT_topology_automasking_init(sd, ob, ss->cache->automask_factor);
}
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_FACE_SETS)) {
SCULPT_vertex_random_access_init(ss);
- sculpt_face_sets_automasking_init(sd, ob, ss->cache->automask);
+ sculpt_face_sets_automasking_init(sd, ob, ss->cache->automask_factor);
}
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_EDGES)) {
@@ -292,13 +351,13 @@ void SCULPT_automasking_init(Sculpt *sd, Object *ob)
SCULPT_boundary_automasking_init(ob,
AUTOMASK_INIT_BOUNDARY_EDGES,
brush->automasking_boundary_edges_propagation_steps,
- ss->cache->automask);
+ ss->cache->automask_factor);
}
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS)) {
SCULPT_vertex_random_access_init(ss);
SCULPT_boundary_automasking_init(ob,
AUTOMASK_INIT_BOUNDARY_FACE_SETS,
brush->automasking_boundary_edges_propagation_steps,
- ss->cache->automask);
+ ss->cache->automask_factor);
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 58f9cdbc867..c0862795594 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -43,7 +43,9 @@
#include "DNA_scene_types.h"
#include "BKE_brush.h"
+#include "BKE_bvhutils.h"
#include "BKE_ccg.h"
+#include "BKE_collision.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_image.h"
@@ -69,6 +71,7 @@
#include "BKE_subsurf.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "WM_api.h"
#include "WM_message.h"
@@ -85,7 +88,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -101,6 +103,33 @@
#include <stdlib.h>
#include <string.h>
+static float cloth_brush_simulation_falloff_get(const Brush *brush,
+ const float radius,
+ const float location[3],
+ const float co[3])
+{
+ /* Global simulation does not have any falloff as the entire mesh is being simulated. */
+ if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_GLOBAL) {
+ return 1.0f;
+ }
+
+ const float distance = len_v3v3(location, co);
+ const float limit = radius + (radius * brush->cloth_sim_limit);
+ const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff);
+
+ if (distance > limit) {
+ /* Outiside the limits. */
+ return 0.0f;
+ }
+ if (distance < falloff) {
+ /* Before the falloff area. */
+ return 1.0f;
+ }
+ /* Do a smoothstep transition inside the falloff area. */
+ float p = 1.0f - ((distance - falloff) / (limit - falloff));
+ return 3.0f * p * p - 2.0f * p * p * p;
+}
+
#define CLOTH_LENGTH_CONSTRAINTS_BLOCK 100000
#define CLOTH_SIMULATION_ITERATIONS 5
#define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024
@@ -113,19 +142,8 @@ static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_s
return BLI_edgeset_haskey(cloth_sim->created_length_constraints, v1, v2);
}
-static void cloth_brush_add_length_constraint(SculptSession *ss,
- SculptClothSimulation *cloth_sim,
- const int v1,
- const int v2)
+static void cloth_brush_reallocate_constraints(SculptClothSimulation *cloth_sim)
{
- cloth_sim->length_constraints[cloth_sim->tot_length_constraints].v1 = v1;
- cloth_sim->length_constraints[cloth_sim->tot_length_constraints].v2 = v2;
- cloth_sim->length_constraints[cloth_sim->tot_length_constraints].length = len_v3v3(
- SCULPT_vertex_co_get(ss, v1), SCULPT_vertex_co_get(ss, v2));
-
- cloth_sim->tot_length_constraints++;
-
- /* Reallocation if the array capacity is exceeded. */
if (cloth_sim->tot_length_constraints >= cloth_sim->capacity_length_constraints) {
cloth_sim->capacity_length_constraints += CLOTH_LENGTH_CONSTRAINTS_BLOCK;
cloth_sim->length_constraints = MEM_reallocN_id(cloth_sim->length_constraints,
@@ -133,23 +151,119 @@ static void cloth_brush_add_length_constraint(SculptSession *ss,
sizeof(SculptClothLengthConstraint),
"length constraints");
}
+}
+
+static void cloth_brush_add_length_constraint(SculptSession *ss,
+ SculptClothSimulation *cloth_sim,
+ const int v1,
+ const int v2,
+ const bool use_persistent)
+{
+ SculptClothLengthConstraint *length_constraint =
+ &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
+
+ length_constraint->elem_index_a = v1;
+ length_constraint->elem_index_b = v2;
+
+ length_constraint->elem_position_a = cloth_sim->pos[v1];
+ length_constraint->elem_position_b = cloth_sim->pos[v2];
+
+ if (use_persistent) {
+ length_constraint->length = len_v3v3(SCULPT_vertex_persistent_co_get(ss, v1),
+ SCULPT_vertex_persistent_co_get(ss, v2));
+ }
+ else {
+ length_constraint->length = len_v3v3(SCULPT_vertex_co_get(ss, v1),
+ SCULPT_vertex_co_get(ss, v2));
+ }
+ length_constraint->strength = 1.0f;
+
+ cloth_sim->tot_length_constraints++;
+
+ /* Reallocation if the array capacity is exceeded. */
+ cloth_brush_reallocate_constraints(cloth_sim);
/* Add the constraint to the GSet to avoid creating it again. */
BLI_edgeset_add(cloth_sim->created_length_constraints, v1, v2);
}
+static void cloth_brush_add_softbody_constraint(SculptClothSimulation *cloth_sim,
+ const int v,
+ const float strength)
+{
+ SculptClothLengthConstraint *length_constraint =
+ &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
+
+ length_constraint->elem_index_a = v;
+ length_constraint->elem_index_b = v;
+
+ length_constraint->elem_position_a = cloth_sim->pos[v];
+ length_constraint->elem_position_b = cloth_sim->init_pos[v];
+
+ length_constraint->length = 0.0f;
+ length_constraint->strength = strength;
+
+ cloth_sim->tot_length_constraints++;
+
+ /* Reallocation if the array capacity is exceeded. */
+ cloth_brush_reallocate_constraints(cloth_sim);
+}
+
+static void cloth_brush_add_deformation_constraint(SculptClothSimulation *cloth_sim,
+ const int v,
+ const float strength)
+{
+ SculptClothLengthConstraint *length_constraint =
+ &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
+
+ length_constraint->elem_index_a = v;
+ length_constraint->elem_index_b = v;
+
+ length_constraint->elem_position_a = cloth_sim->pos[v];
+ length_constraint->elem_position_b = cloth_sim->deformation_pos[v];
+
+ length_constraint->length = 0.0f;
+ length_constraint->strength = strength;
+
+ cloth_sim->tot_length_constraints++;
+
+ /* Reallocation if the array capacity is exceeded. */
+ cloth_brush_reallocate_constraints(cloth_sim);
+}
+
static void do_cloth_brush_build_constraints_task_cb_ex(
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
PBVHVertexIter vd;
+ const bool pin_simulation_boundary = ss->cache != NULL && brush != NULL &&
+ brush->flag2 & BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY;
+
+ const bool use_persistent = brush != NULL && brush->flag & BRUSH_PERSISTENT;
+
+ /* Brush can be NULL in tools that use the solver without relying of constraints with deformation
+ * positions. */
+ const bool cloth_is_deform_brush = ss->cache != NULL && brush != NULL &&
+ SCULPT_is_cloth_deform_brush(brush);
+ float radius_squared = 0.0f;
+ if (cloth_is_deform_brush) {
+ radius_squared = ss->cache->initial_radius * ss->cache->initial_radius;
+ }
+
+ /* Only limit the contraint creation to a radius when the simulation is local. */
+ const float cloth_sim_radius_squared = brush->cloth_simulation_area_type ==
+ BRUSH_CLOTH_SIMULATION_AREA_LOCAL ?
+ data->cloth_sim_radius * data->cloth_sim_radius :
+ FLT_MAX;
+
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (len_squared_v3v3(vd.co, data->cloth_sim_initial_location) <
- data->cloth_sim_radius * data->cloth_sim_radius) {
+ const float len_squared = len_squared_v3v3(vd.co, data->cloth_sim_initial_location);
+ if (len_squared < cloth_sim_radius_squared) {
SculptVertexNeighborIter ni;
int build_indices[CLOTH_MAX_CONSTRAINTS_PER_VERTEX];
@@ -162,6 +276,11 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ if (brush->cloth_constraint_softbody_strength > 0.0f) {
+ cloth_brush_add_softbody_constraint(
+ data->cloth_sim, vd.index, brush->cloth_constraint_softbody_strength);
+ }
+
/* As we don't know the order of the neighbor vertices, we create all possible combinations
* between the neighbor and the original vertex as length constraints. */
/* This results on a pattern that contains structural, shear and bending constraints for all
@@ -172,37 +291,29 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
if (c_i != c_j && !cloth_brush_sim_has_length_constraint(
data->cloth_sim, build_indices[c_i], build_indices[c_j])) {
cloth_brush_add_length_constraint(
- ss, data->cloth_sim, build_indices[c_i], build_indices[c_j]);
+ ss, data->cloth_sim, build_indices[c_i], build_indices[c_j], use_persistent);
}
}
}
}
- }
- BKE_pbvh_vertex_iter_end;
-}
-static float cloth_brush_simulation_falloff_get(const Brush *brush,
- const float radius,
- const float location[3],
- const float co[3])
-{
- const float distance = len_v3v3(location, co);
- const float limit = radius + (radius * brush->cloth_sim_limit);
- const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff);
+ if (cloth_is_deform_brush && len_squared < radius_squared) {
+ const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius);
+ cloth_brush_add_deformation_constraint(data->cloth_sim, vd.index, fade);
+ }
- if (distance > limit) {
- /* Outiside the limits. */
- return 0.0f;
- }
- else if (distance < falloff) {
- /* Before the falloff area. */
- return 1.0f;
- }
- else {
- /* Do a smoothstep transition inside the falloff area. */
- float p = 1.0f - ((distance - falloff) / (limit - falloff));
- return 3.0f * p * p - 2.0f * p * p * p;
+ if (pin_simulation_boundary) {
+ const float sim_falloff = cloth_brush_simulation_falloff_get(
+ brush, ss->cache->initial_radius, ss->cache->location, vd.co);
+ /* Vertex is inside the area of the simulation without any falloff aplied. */
+ if (sim_falloff < 1.0f) {
+ /* Create constraints with more strength the closer the vertex is to the simulation
+ * boundary. */
+ cloth_brush_add_softbody_constraint(data->cloth_sim, vd.index, 1.0f - sim_falloff);
+ }
+ }
}
+ BKE_pbvh_vertex_iter_end;
}
static void cloth_brush_apply_force_to_vertex(SculptSession *UNUSED(ss),
@@ -256,8 +367,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
/* Gravity */
float gravity[3] = {0.0f};
if (ss->cache->supports_gravity) {
- madd_v3_v3fl(
- gravity, ss->cache->gravity_direction, -ss->cache->radius * data->sd->gravity_factor);
+ madd_v3_v3fl(gravity, ss->cache->gravity_direction, -data->sd->gravity_factor);
}
/* Original data for deform brushes. */
@@ -281,6 +391,11 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
copy_v3_v3(current_vertex_location, vd.co);
}
+ /* Apply gravity in the entire simulation area. */
+ float vertex_gravity[3];
+ mul_v3_v3fl(vertex_gravity, gravity, sim_factor);
+ cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, vertex_gravity, vd.index);
+
/* When using the plane falloff mode the falloff is not constrained by the brush radius. */
if (sculpt_brush_test_sq_fn(&test, current_vertex_location) || use_falloff_plane) {
@@ -321,9 +436,10 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
mul_v3_v3fl(force, offset, -fade);
break;
case BRUSH_CLOTH_DEFORM_GRAB:
- /* Grab writes the positions in the simulation directly without applying forces. */
- madd_v3_v3v3fl(
- cloth_sim->pos[vd.index], orig_data.co, ss->cache->grab_delta_symmetry, fade);
+ madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
+ orig_data.co,
+ ss->cache->grab_delta_symmetry,
+ fade);
zero_v3(force);
break;
case BRUSH_CLOTH_DEFORM_PINCH_POINT:
@@ -358,17 +474,42 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
break;
}
- madd_v3_v3fl(force, gravity, fade);
-
cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, force, vd.index);
}
}
BKE_pbvh_vertex_iter_end;
}
+static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph)
+{
+ ListBase *cache = NULL;
+ DEG_OBJECT_ITER_BEGIN (depsgraph,
+ ob,
+ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI) {
+ CollisionModifierData *cmd = (CollisionModifierData *)BKE_modifiers_findby_type(
+ ob, eModifierType_Collision);
+ if (cmd && cmd->bvhtree) {
+ if (cache == NULL) {
+ cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
+ }
+
+ ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
+ col->ob = ob;
+ col->collmd = cmd;
+ collision_move_object(cmd, 1.0, 0.0, true);
+ BLI_addtail(cache, col);
+ }
+ }
+ DEG_OBJECT_ITER_END;
+ return cache;
+}
+
static SculptClothSimulation *cloth_brush_simulation_create(SculptSession *ss,
+ Brush *brush,
const float cloth_mass,
- const float cloth_damping)
+ const float cloth_damping,
+ const bool use_collisions)
{
const int totverts = SCULPT_vertex_count_get(ss);
SculptClothSimulation *cloth_sim;
@@ -380,19 +521,130 @@ static SculptClothSimulation *cloth_brush_simulation_create(SculptSession *ss,
"cloth length constraints");
cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK;
- cloth_sim->acceleration = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim acceleration");
- cloth_sim->pos = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim pos");
- cloth_sim->prev_pos = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim prev pos");
- cloth_sim->init_pos = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim init pos");
- cloth_sim->length_constraint_tweak = MEM_callocN(sizeof(float) * totverts,
- "cloth sim length tweak");
+ cloth_sim->acceleration = MEM_calloc_arrayN(
+ totverts, 3 * sizeof(float), "cloth sim acceleration");
+ cloth_sim->pos = MEM_calloc_arrayN(totverts, 3 * sizeof(float), "cloth sim pos");
+ cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, 3 * sizeof(float), "cloth sim prev pos");
+ cloth_sim->last_iteration_pos = MEM_calloc_arrayN(
+ totverts, sizeof(float) * 3, "cloth sim last iteration pos");
+ cloth_sim->init_pos = MEM_calloc_arrayN(totverts, 3 * sizeof(float), "cloth sim init pos");
+ cloth_sim->length_constraint_tweak = MEM_calloc_arrayN(
+ totverts, sizeof(float), "cloth sim length tweak");
+
+ /* Brush can be NULL for tools that need the solver but don't rely on constraint to deformation
+ * positions. */
+ if (brush && SCULPT_is_cloth_deform_brush(brush)) {
+ cloth_sim->deformation_pos = MEM_calloc_arrayN(
+ totverts, 3 * sizeof(float), "cloth sim deformation positions");
+ }
cloth_sim->mass = cloth_mass;
cloth_sim->damping = cloth_damping;
+ if (use_collisions) {
+ cloth_sim->collider_list = cloth_brush_collider_cache_create(ss->depsgraph);
+ }
+
return cloth_sim;
}
+typedef struct ClothBrushCollision {
+ CollisionModifierData *col_data;
+ struct IsectRayPrecalc isect_precalc;
+} ClothBrushCollision;
+
+static void cloth_brush_collision_cb(void *userdata,
+ int index,
+ const BVHTreeRay *ray,
+ BVHTreeRayHit *hit)
+{
+ ClothBrushCollision *col = (ClothBrushCollision *)userdata;
+ CollisionModifierData *col_data = col->col_data;
+ MVertTri *verttri = &col_data->tri[index];
+ MVert *mverts = col_data->x;
+ float *tri[3], no[3], co[3];
+
+ tri[0] = mverts[verttri->tri[0]].co;
+ tri[1] = mverts[verttri->tri[1]].co;
+ tri[2] = mverts[verttri->tri[2]].co;
+ float dist = 0.0f;
+
+ bool tri_hit = isect_ray_tri_watertight_v3(
+ ray->origin, &col->isect_precalc, UNPACK3(tri), &dist, NULL);
+ normal_tri_v3(no, UNPACK3(tri));
+ madd_v3_v3v3fl(co, ray->origin, ray->direction, dist);
+
+ if (tri_hit && dist < hit->dist) {
+ hit->index = index;
+ hit->dist = dist;
+
+ copy_v3_v3(hit->co, co);
+ copy_v3_v3(hit->no, no);
+ }
+}
+
+static void cloth_brush_solve_collision(Object *object,
+ SculptClothSimulation *cloth_sim,
+ const int i)
+{
+ const int raycast_flag = BVH_RAYCAST_DEFAULT & ~(BVH_RAYCAST_WATERTIGHT);
+
+ ColliderCache *collider_cache;
+ BVHTreeRayHit hit;
+
+ float obmat_inv[4][4];
+ invert_m4_m4(obmat_inv, object->obmat);
+
+ for (collider_cache = cloth_sim->collider_list->first; collider_cache;
+ collider_cache = collider_cache->next) {
+ float ray_start[3], ray_normal[3];
+ float pos_world_space[3], prev_pos_world_space[3];
+
+ mul_v3_m4v3(pos_world_space, object->obmat, cloth_sim->pos[i]);
+ mul_v3_m4v3(prev_pos_world_space, object->obmat, cloth_sim->last_iteration_pos[i]);
+ sub_v3_v3v3(ray_normal, pos_world_space, prev_pos_world_space);
+ copy_v3_v3(ray_start, prev_pos_world_space);
+ hit.index = -1;
+ hit.dist = len_v3(ray_normal);
+ normalize_v3(ray_normal);
+
+ ClothBrushCollision col;
+ CollisionModifierData *collmd = collider_cache->collmd;
+ col.col_data = collmd;
+ isect_ray_tri_watertight_v3_precalc(&col.isect_precalc, ray_normal);
+
+ BLI_bvhtree_ray_cast_ex(collmd->bvhtree,
+ ray_start,
+ ray_normal,
+ 0.3f,
+ &hit,
+ cloth_brush_collision_cb,
+ &col,
+ raycast_flag);
+
+ if (hit.index != -1) {
+
+ float collision_disp[3];
+ float movement_disp[3];
+ mul_v3_v3fl(collision_disp, hit.no, 0.005f);
+ sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
+ float friction_plane[4];
+ float pos_on_friction_plane[3];
+ plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
+ closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
+ sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
+
+ /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
+ mul_v3_fl(movement_disp, 0.35f);
+
+ copy_v3_v3(cloth_sim->pos[i], hit.co);
+ add_v3_v3(cloth_sim->pos[i], movement_disp);
+ add_v3_v3(cloth_sim->pos[i], collision_disp);
+ mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
+ }
+ }
+}
+
static void do_cloth_brush_solve_simulation_task_cb_ex(
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
{
@@ -423,14 +675,22 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
SCULPT_automasking_factor_get(ss, vd.index);
+
madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
- copy_v3_v3(cloth_sim->prev_pos[i], temp);
+ if (cloth_sim->collider_list != NULL) {
+ cloth_brush_solve_collision(data->ob, cloth_sim, i);
+ }
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
+
+ copy_v3_v3(cloth_sim->prev_pos[i], temp);
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -439,13 +699,16 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
BKE_pbvh_vertex_iter_end;
}
-static void cloth_brush_build_nodes_constraints(Sculpt *sd,
- Object *ob,
- PBVHNode **nodes,
- int totnode,
- SculptClothSimulation *cloth_sim,
- float initial_location[3],
- const float radius)
+static void cloth_brush_build_nodes_constraints(
+ Sculpt *sd,
+ Object *ob,
+ PBVHNode **nodes,
+ int totnode,
+ SculptClothSimulation *cloth_sim,
+ /* Cannot be const, because it is assigned to a non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ float initial_location[3],
+ const float radius)
{
Brush *brush = BKE_paint_brush(&sd->paint);
@@ -481,11 +744,11 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
for (int i = 0; i < cloth_sim->tot_length_constraints; i++) {
const SculptClothLengthConstraint *constraint = &cloth_sim->length_constraints[i];
- const int v1 = constraint->v1;
- const int v2 = constraint->v2;
+ const int v1 = constraint->elem_index_a;
+ const int v2 = constraint->elem_index_b;
float v1_to_v2[3];
- sub_v3_v3v3(v1_to_v2, cloth_sim->pos[v2], cloth_sim->pos[v1]);
+ sub_v3_v3v3(v1_to_v2, constraint->elem_position_b, constraint->elem_position_a);
const float current_distance = len_v3(v1_to_v2);
float correction_vector[3];
float correction_vector_half[3];
@@ -521,8 +784,14 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
cloth_sim->init_pos[v2]) :
1.0f;
- madd_v3_v3fl(cloth_sim->pos[v1], correction_vector_half, 1.0f * mask_v1 * sim_factor_v1);
- madd_v3_v3fl(cloth_sim->pos[v2], correction_vector_half, -1.0f * mask_v2 * sim_factor_v2);
+ madd_v3_v3fl(cloth_sim->pos[v1],
+ correction_vector_half,
+ 1.0f * mask_v1 * sim_factor_v1 * constraint->strength);
+ if (v1 != v2) {
+ madd_v3_v3fl(cloth_sim->pos[v2],
+ correction_vector_half,
+ -1.0f * mask_v2 * sim_factor_v2 * constraint->strength);
+ }
}
}
}
@@ -574,7 +843,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
.mat = imat,
};
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
/* Init the grab delta. */
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
@@ -638,17 +907,27 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
/* In the first brush step of each symmetry pass, build the constraints for the vertices in all
* nodes inside the simulation's limits. */
- /* Brush stroke types that restore the mesh on each brush step also need the cloth sim data to be
- * created on each step. */
+ /* Brushes that use anchored strokes and restore the mesh can't rely on symmetry passes and steps
+ * count as it is always the first step, so the simulation needs to be created when it does not
+ * exist for this stroke. */
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) || !ss->cache->cloth_sim) {
/* The simulation structure only needs to be created on the first symmetry pass. */
- if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
+ if (SCULPT_stroke_is_first_brush_step(ss->cache) || !ss->cache->cloth_sim) {
+ const bool is_cloth_deform_brush = SCULPT_is_cloth_deform_brush(brush);
ss->cache->cloth_sim = cloth_brush_simulation_create(
- ss, brush->cloth_mass, brush->cloth_damping);
+ ss,
+ brush,
+ brush->cloth_mass,
+ brush->cloth_damping,
+ (brush->flag2 & BRUSH_CLOTH_USE_COLLISION));
for (int i = 0; i < totverts; i++) {
- copy_v3_v3(ss->cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
+ copy_v3_v3(ss->cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i));
copy_v3_v3(ss->cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i));
+ copy_v3_v3(ss->cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
+ if (is_cloth_deform_brush) {
+ copy_v3_v3(ss->cache->cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i));
+ }
}
}
@@ -671,25 +950,27 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
/* Update and write the simulation to the nodes. */
cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
-
- return;
}
void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim)
{
MEM_SAFE_FREE(cloth_sim->pos);
+ MEM_SAFE_FREE(cloth_sim->last_iteration_pos);
MEM_SAFE_FREE(cloth_sim->prev_pos);
MEM_SAFE_FREE(cloth_sim->acceleration);
MEM_SAFE_FREE(cloth_sim->length_constraints);
MEM_SAFE_FREE(cloth_sim->length_constraint_tweak);
+ MEM_SAFE_FREE(cloth_sim->deformation_pos);
MEM_SAFE_FREE(cloth_sim->init_pos);
+ if (cloth_sim->collider_list) {
+ BKE_collider_cache_free(&cloth_sim->collider_list);
+ }
MEM_SAFE_FREE(cloth_sim);
}
/* Cursor drawing function. */
void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
const Brush *brush,
- const float obmat[4][4],
const float location[3],
const float normal[3],
const float rds,
@@ -700,10 +981,11 @@ void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
float cursor_trans[4][4], cursor_rot[4][4];
float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
float quat[4];
- copy_m4_m4(cursor_trans, obmat);
+ unit_m4(cursor_trans);
translate_m4(cursor_trans, location[0], location[1], location[2]);
rotation_between_vecs_to_quat(quat, z_axis, normal);
quat_to_mat4(cursor_rot, quat);
+ GPU_matrix_push();
GPU_matrix_mul(cursor_trans);
GPU_matrix_mul(cursor_rot);
@@ -713,6 +995,7 @@ void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
gpuattr, 0, 0, rds + (rds * brush->cloth_sim_limit * brush->cloth_sim_falloff), 320);
immUniformColor3fvAlpha(outline_col, alpha * 0.7f);
imm_draw_circle_wire_3d(gpuattr, 0, 0, rds + rds * brush->cloth_sim_limit, 80);
+ GPU_matrix_pop();
}
void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr,
@@ -859,6 +1142,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
const int totverts = SCULPT_vertex_count_get(ss);
+
for (int i = 0; i < totverts; i++) {
copy_v3_v3(ss->filter_cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i));
}
@@ -890,7 +1174,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = CTX_data_active_object(C);
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
SculptSession *ss = ob->sculpt;
@@ -911,11 +1195,15 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass");
const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping");
- ss->filter_cache->cloth_sim = cloth_brush_simulation_create(ss, cloth_mass, cloth_damping);
+ const bool use_collisions = RNA_boolean_get(op->ptr, "use_collisions");
+ ss->filter_cache->cloth_sim = cloth_brush_simulation_create(
+ ss, NULL, cloth_mass, cloth_damping, use_collisions);
+
copy_v3_v3(ss->filter_cache->cloth_sim_pinch_point, SCULPT_active_vertex_co_get(ss));
const int totverts = SCULPT_vertex_count_get(ss);
for (int i = 0; i < totverts; i++) {
+ copy_v3_v3(ss->filter_cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i));
copy_v3_v3(ss->filter_cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
copy_v3_v3(ss->filter_cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i));
}
@@ -987,4 +1275,9 @@ void SCULPT_OT_cloth_filter(struct wmOperatorType *ot)
false,
"Use Face Sets",
"Apply the filter only to the Face Set under the cursor");
+ ot->prop = RNA_def_boolean(ot->srna,
+ "use_collisions",
+ false,
+ "Use Collisions",
+ "Collide with other collider objects in the scene");
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 031b4f8731d..5cc32be331e 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -192,7 +192,7 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
/* Threaded loop over nodes. */
SculptThreadedTaskData data = {
@@ -205,6 +205,7 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
if (ss->cache->alt_smooth) {
+ SCULPT_boundary_info_ensure(ob);
for (int i = 0; i < 4; i++) {
BLI_task_parallel_range(0, totnode, &data, do_relax_face_sets_brush_task_cb_ex, &settings);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
index 5f7805af347..912dfd808b0 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
@@ -80,7 +80,7 @@ typedef enum eSculptColorFilterTypes {
COLOR_FILTER_SMOOTH,
} eSculptColorFilterTypes;
-EnumPropertyItem prop_color_filter_types[] = {
+static EnumPropertyItem prop_color_filter_types[] = {
{COLOR_FILTER_FILL, "FILL", 0, "Fill", "Fill with a specific color"},
{COLOR_FILTER_HUE, "HUE", 0, "Hue", "Change hue"},
{COLOR_FILTER_SATURATION, "SATURATION", 0, "Saturation", "Change saturation"},
@@ -265,7 +265,6 @@ static int sculpt_color_filter_modal(bContext *C, wmOperator *op, const wmEvent
static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = CTX_data_active_object(C);
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
SculptSession *ss = ob->sculpt;
int mode = RNA_enum_get(op->ptr, "type");
@@ -285,6 +284,11 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_undo_push_begin("color filter");
+ BKE_sculpt_color_layer_create_if_needed(ob);
+
+ /* CTX_data_ensure_evaluated_depsgraph should be used at the end to include the updates of
+ * earlier steps modifying the data. */
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
bool needs_pmap = mode == COLOR_FILTER_SMOOTH;
BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, true);
@@ -308,7 +312,7 @@ void SCULPT_OT_color_filter(struct wmOperatorType *ot)
/* api callbacks */
ot->invoke = sculpt_color_filter_invoke;
ot->modal = sculpt_color_filter_modal;
- ot->poll = SCULPT_mode_poll;
+ ot->poll = SCULPT_vertex_colors_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -318,6 +322,6 @@ void SCULPT_OT_color_filter(struct wmOperatorType *ot)
ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter Strength", -10.0f, 10.0f);
PropertyRNA *prop = RNA_def_float_color(
- ot->srna, "fill_color", 3, NULL, 0.0f, FLT_MAX, "Fill Color", "fill color", 0.0f, 1.0f);
+ ot->srna, "fill_color", 3, NULL, 0.0f, FLT_MAX, "Fill Color", "", 0.0f, 1.0f);
RNA_def_property_subtype(prop, PROP_COLOR_GAMMA);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index 494588d0996..ba11988156c 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -87,7 +87,7 @@ void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type)
.original = true,
.center = center,
.radius_squared = FLT_MAX,
- .ignore_fully_masked = true,
+ .ignore_fully_ineffective = true,
};
BKE_pbvh_search_gather(pbvh,
@@ -132,6 +132,7 @@ void SCULPT_filter_cache_free(SculptSession *ss)
MEM_SAFE_FREE(ss->filter_cache->automask);
MEM_SAFE_FREE(ss->filter_cache->surface_smooth_laplacian_disp);
MEM_SAFE_FREE(ss->filter_cache->sharpen_factor);
+ MEM_SAFE_FREE(ss->filter_cache->sharpen_detail_directions);
MEM_SAFE_FREE(ss->filter_cache);
}
@@ -261,17 +262,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
switch (filter_type) {
case MESH_FILTER_SMOOTH:
CLAMP(fade, -1.0f, 1.0f);
- switch (BKE_pbvh_type(ss->pbvh)) {
- case PBVH_FACES:
- SCULPT_neighbor_average(ss, avg, vd.index);
- break;
- case PBVH_BMESH:
- SCULPT_bmesh_neighbor_average(avg, vd.bm_vert);
- break;
- case PBVH_GRIDS:
- SCULPT_neighbor_coords_average(ss, avg, vd.index);
- break;
- }
+ SCULPT_neighbor_coords_average_interior(ss, avg, vd.index);
sub_v3_v3v3(val, avg, orig_co);
madd_v3_v3v3fl(val, orig_co, val, fade);
sub_v3_v3v3(disp, val, orig_co);
@@ -320,8 +311,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
break;
}
case MESH_FILTER_RELAX: {
- SCULPT_relax_vertex(
- ss, &vd, clamp_f(fade * ss->filter_cache->automask[vd.index], 0.0f, 1.0f), false, val);
+ SCULPT_relax_vertex(ss, &vd, clamp_f(fade, 0.0f, 1.0f), false, val);
sub_v3_v3v3(disp, val, vd.co);
break;
}
@@ -367,6 +357,17 @@ static void mesh_filter_task_cb(void *__restrict userdata,
mul_v3_v3fl(
disp_avg, disp_avg, smooth_ratio * pow2f(ss->filter_cache->sharpen_factor[vd.index]));
add_v3_v3v3(disp, disp_avg, disp_sharpen);
+
+ /* Intensify details. */
+ if (ss->filter_cache->sharpen_intensify_detail_strength > 0.0f) {
+ float detail_strength[3];
+ normal_short_to_float_v3(detail_strength, orig_data.no);
+ copy_v3_v3(detail_strength, ss->filter_cache->sharpen_detail_directions[vd.index]);
+ madd_v3_v3fl(disp,
+ detail_strength,
+ -ss->filter_cache->sharpen_intensify_detail_strength *
+ ss->filter_cache->sharpen_factor[vd.index]);
+ }
break;
}
}
@@ -399,8 +400,10 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss)
for (int i = 0; i < totvert; i++) {
float avg[3];
SCULPT_neighbor_coords_average(ss, avg, i);
- ss->filter_cache->sharpen_factor[i] = len_v3v3(avg, SCULPT_vertex_co_get(ss, i));
+ sub_v3_v3v3(ss->filter_cache->sharpen_detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
+ ss->filter_cache->sharpen_factor[i] = len_v3(ss->filter_cache->sharpen_detail_directions[i]);
}
+
float max_factor = 0.0f;
for (int i = 0; i < totvert; i++) {
if (ss->filter_cache->sharpen_factor[i] > max_factor) {
@@ -413,6 +416,31 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss)
ss->filter_cache->sharpen_factor[i] *= max_factor;
ss->filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - ss->filter_cache->sharpen_factor[i]);
}
+
+ /* Smooth the calculated factors and directions to remove high frecuency detail. */
+ for (int smooth_iterations = 0;
+ smooth_iterations < ss->filter_cache->sharpen_curvature_smooth_iterations;
+ smooth_iterations++) {
+ for (int i = 0; i < totvert; i++) {
+ float direction_avg[3] = {0.0f, 0.0f, 0.0f};
+ float sharpen_avg = 0;
+ int total = 0;
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
+ add_v3_v3(direction_avg, ss->filter_cache->sharpen_detail_directions[ni.index]);
+ sharpen_avg += ss->filter_cache->sharpen_factor[ni.index];
+ total++;
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ if (total > 0) {
+ mul_v3_v3fl(
+ ss->filter_cache->sharpen_detail_directions[i], direction_avg, 1.0f / (float)total);
+ ss->filter_cache->sharpen_factor[i] = sharpen_avg / (float)total;
+ }
+ }
+ }
}
static void mesh_filter_surface_smooth_displace_task_cb(
@@ -540,16 +568,23 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_vertex_random_access_init(ss);
- bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, false);
+ const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_topology_info, false, false);
+ if (needs_topology_info) {
+ SCULPT_boundary_info_ensure(ob);
+ }
const int totvert = SCULPT_vertex_count_get(ss);
- if (BKE_pbvh_type(pbvh) == PBVH_FACES && needs_pmap && !ob->sculpt->pmap) {
+ if (BKE_pbvh_type(pbvh) == PBVH_FACES && needs_topology_info && !ob->sculpt->pmap) {
return OPERATOR_CANCELLED;
}
SCULPT_undo_push_begin("Mesh filter");
+ if (ELEM(filter_type, MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS)) {
+ SCULPT_boundary_info_ensure(ob);
+ }
+
SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS);
if (use_face_sets) {
@@ -570,7 +605,14 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SHARPEN) {
ss->filter_cache->sharpen_smooth_ratio = RNA_float_get(op->ptr, "sharpen_smooth_ratio");
+ ss->filter_cache->sharpen_intensify_detail_strength = RNA_float_get(
+ op->ptr, "sharpen_intensify_detail_strength");
+ ss->filter_cache->sharpen_curvature_smooth_iterations = RNA_int_get(
+ op->ptr, "sharpen_curvature_smooth_iterations");
+
ss->filter_cache->sharpen_factor = MEM_mallocN(sizeof(float) * totvert, "sharpen factor");
+ ss->filter_cache->sharpen_detail_directions = MEM_malloc_arrayN(
+ totvert, 3 * sizeof(float), "sharpen detail direction");
mesh_filter_sharpen_init_factors(ss);
}
@@ -579,16 +621,6 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y;
ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z;
- if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_RELAX) {
- ss->filter_cache->automask = MEM_mallocN(totvert * sizeof(float),
- "Relax filter edge automask");
- for (int i = 0; i < totvert; i++) {
- ss->filter_cache->automask[i] = 1.0f;
- }
- SCULPT_boundary_automasking_init(
- ob, AUTOMASK_INIT_BOUNDARY_EDGES, 1, ss->filter_cache->automask);
- }
-
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -656,4 +688,24 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
"How much smoothing is applied to polished surfaces",
0.0f,
1.0f);
+
+ RNA_def_float(ot->srna,
+ "sharpen_intensify_detail_strength",
+ 0.0f,
+ 0.0f,
+ 10.0f,
+ "Intensify Details",
+ "How much creases and valleys are intensified",
+ 0.0f,
+ 1.0f);
+
+ RNA_def_int(ot->srna,
+ "sharpen_curvature_smooth_iterations",
+ 0,
+ 0,
+ 10,
+ "Curvature Smooth Iterations",
+ "How much smooth the resulting shape is, ignoring high frequency details",
+ 0,
+ 10);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index c7e07721eb7..74feaa8ca00 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -21,8 +21,7 @@
* \ingroup edsculpt
*/
-#ifndef __SCULPT_INTERN_H__
-#define __SCULPT_INTERN_H__
+#pragma once
#include "DNA_brush_types.h"
#include "DNA_key_types.h"
@@ -51,6 +50,8 @@ bool SCULPT_mode_poll_view3d(struct bContext *C);
bool SCULPT_poll(struct bContext *C);
bool SCULPT_poll_view3d(struct bContext *C);
+bool SCULPT_vertex_colors_poll(struct bContext *C);
+
/* Updates */
typedef enum SculptUpdateType {
@@ -96,6 +97,9 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]);
float SCULPT_vertex_mask_get(struct SculptSession *ss, int index);
const float *SCULPT_vertex_color_get(SculptSession *ss, int index);
+const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index);
+void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]);
+
#define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256
typedef struct SculptVertexNeighborIter {
/* Storage */
@@ -146,8 +150,6 @@ int SCULPT_active_vertex_get(SculptSession *ss);
const float *SCULPT_active_vertex_co_get(SculptSession *ss);
void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3]);
-bool SCULPT_vertex_is_boundary(SculptSession *ss, const int index);
-
/* Fake Neighbors */
#define FAKE_NEIGHBOR_NONE -1
@@ -157,6 +159,11 @@ void SCULPT_fake_neighbors_enable(Object *ob);
void SCULPT_fake_neighbors_disable(Object *ob);
void SCULPT_fake_neighbors_free(struct Object *ob);
+/* Vertex Info. */
+void SCULPT_boundary_info_ensure(Object *object);
+/* Boundary Info needs to be initialized in order to use this function. */
+bool SCULPT_vertex_is_boundary(const SculptSession *ss, const int index);
+
/* Sculpt Visibility API */
void SCULPT_vertex_visible_set(SculptSession *ss, int index, bool visible);
@@ -177,7 +184,7 @@ bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index);
int SCULPT_face_set_next_available_get(SculptSession *ss);
void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visible);
-bool SCULPT_vertex_all_face_sets_visible_get(SculptSession *ss, int index);
+bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, int index);
bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, int index);
void SCULPT_face_sets_visibility_invert(SculptSession *ss);
@@ -343,7 +350,6 @@ void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim);
void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
const struct Brush *brush,
- const float obmat[4][4],
const float location[3],
const float normal[3],
const float rds,
@@ -389,6 +395,7 @@ void SCULPT_pose_ik_chain_free(struct SculptPoseIKChain *ik_chain);
/* Multiplane Scrape Brush. */
void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,
+ Brush *brush,
SculptSession *ss,
const float outline_col[3],
const float outline_alpha);
@@ -402,16 +409,15 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
/* Smooth Brush. */
-
-void SCULPT_neighbor_average(SculptSession *ss, float avg[3], uint vert);
-void SCULPT_bmesh_neighbor_average(float avg[3], struct BMVert *v);
-
void SCULPT_bmesh_four_neighbor_average(float avg[3], float direction[3], struct BMVert *v);
void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], int index);
float SCULPT_neighbor_mask_average(SculptSession *ss, int index);
void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index);
+/* Mask the mesh boundaries smoothing only the mesh surface without using automasking. */
+void SCULPT_neighbor_coords_average_interior(SculptSession *ss, float result[3], int index);
+
void SCULPT_smooth(Sculpt *sd,
Object *ob,
PBVHNode **nodes,
@@ -676,7 +682,8 @@ typedef struct {
float radius_squared;
const float *center;
bool original;
- bool ignore_fully_masked;
+ /* This ignores fully masked and fully hidden nodes. */
+ bool ignore_fully_ineffective;
} SculptSearchSphereData;
typedef struct {
@@ -684,7 +691,7 @@ typedef struct {
struct SculptSession *ss;
float radius_squared;
bool original;
- bool ignore_fully_masked;
+ bool ignore_fully_ineffective;
struct DistRayAABB_Precalc *dist_ray_to_aabb_precalc;
} SculptSearchCircleData;
@@ -732,6 +739,12 @@ bool SCULPT_pbvh_calc_area_normal(const struct Brush *brush,
#define SCULPT_CLAY_STABILIZER_LEN 10
+typedef struct AutomaskingSettings {
+ /* Flags from eAutomasking_flag. */
+ int flags;
+ int initial_face_set;
+} AutomaskingSettings;
+
typedef struct StrokeCache {
/* Invariants */
float initial_radius;
@@ -816,6 +829,15 @@ typedef struct StrokeCache {
bool original;
float anchored_location[3];
+ /* Paint Brush. */
+ struct {
+ float hardness;
+ float flow;
+ float wet_mix;
+ float wet_persistence;
+ float density;
+ } paint_brush;
+
/* Pose brush */
struct SculptPoseIKChain *pose_ik_chain;
@@ -854,7 +876,11 @@ typedef struct StrokeCache {
float true_gravity_direction[3];
float gravity_direction[3];
- float *automask;
+ /* Automasking. */
+ AutomaskingSettings automask_settings;
+ /* Precomputed automask factor indexed by vertex, owned by the automasking system and initialized
+ * in SCULPT_automasking_init when needed. */
+ float *automask_factor;
float stroke_local_mat[4][4];
float multiplane_scrape_angle;
@@ -882,7 +908,10 @@ typedef struct FilterCache {
/* Sharpen mesh filter. */
float sharpen_smooth_ratio;
+ float sharpen_intensify_detail_strength;
+ int sharpen_curvature_smooth_iterations;
float *sharpen_factor;
+ float (*sharpen_detail_directions)[3];
/* unmasked nodes */
PBVHNode **nodes;
@@ -967,5 +996,3 @@ void SCULPT_OT_set_detail_size(struct wmOperatorType *ot);
/* Dyntopo. */
void SCULPT_OT_dynamic_topology_toggle(struct wmOperatorType *ot);
-
-#endif
diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
index b52036d753c..35f916c8f90 100644
--- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
+++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
@@ -47,7 +47,6 @@
#include "paint_intern.h"
#include "sculpt_intern.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -400,10 +399,15 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
}
void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,
+ Brush *brush,
SculptSession *ss,
const float outline_col[3],
const float outline_alpha)
{
+ if (!(brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW)) {
+ return;
+ }
+
float local_mat_inv[4][4];
invert_m4_m4(local_mat_inv, ss->cache->stroke_local_mat);
GPU_matrix_mul(local_mat_inv);
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index 5cf6a053382..00a59949130 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -164,7 +164,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
/* Density. */
float noise = 1.0f;
- const float density = brush->density;
+ const float density = ss->cache->paint_brush.density;
if (density < 1.0f) {
const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
if (hash_noise > density) {
@@ -178,11 +178,12 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata,
float wet_mix_color[4];
float buffer_color[4];
- mul_v4_v4fl(paint_color, brush_color, fade * brush->flow);
- mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * brush->flow);
+ mul_v4_v4fl(paint_color, brush_color, fade * ss->cache->paint_brush.flow);
+ mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * ss->cache->paint_brush.flow);
/* Interpolate with the wet_mix color for wet paint mixing. */
- blend_color_interpolate_float(paint_color, paint_color, wet_mix_color, brush->wet_mix);
+ blend_color_interpolate_float(
+ paint_color, paint_color, wet_mix_color, ss->cache->paint_brush.wet_mix);
blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
/* Final mix over the original color using brush alpha. */
@@ -254,7 +255,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
return;
}
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
float area_no[3];
float mat[4][4];
@@ -305,7 +306,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
/* Wet paint color sampling. */
float wet_color[4] = {0.0f};
- if (brush->wet_mix > 0.0f) {
+ if (ss->cache->paint_brush.wet_mix > 0.0f) {
SculptThreadedTaskData task_data = {
.sd = sd,
.ob = ob,
@@ -332,8 +333,10 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
if (ss->cache->first_time) {
copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
}
- blend_color_interpolate_float(
- wet_color, wet_color, ss->cache->wet_mix_prev_color, brush->wet_persistence);
+ blend_color_interpolate_float(wet_color,
+ wet_color,
+ ss->cache->wet_mix_prev_color,
+ ss->cache->paint_brush.wet_persistence);
copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
CLAMP4(ss->cache->wet_mix_prev_color, 0.0f, 1.0f);
}
@@ -388,7 +391,17 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata,
float interp_color[4];
copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
- sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ switch (brush->smear_deform_type) {
+ case BRUSH_SMEAR_DEFORM_DRAG:
+ sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ break;
+ case BRUSH_SMEAR_DEFORM_PINCH:
+ sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
+ break;
+ case BRUSH_SMEAR_DEFORM_EXPAND:
+ sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
+ break;
+ }
normalize_v3_v3(current_disp_norm, current_disp);
mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
@@ -455,7 +468,7 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
}
}
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
SculptThreadedTaskData data = {
.sd = sd,
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index c9e2b7318d6..8a288877d43 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -430,7 +430,7 @@ static bool pose_topology_floodfill_cb(
co, data->pose_initial_co, data->radius, data->symm)) {
return true;
}
- else if (SCULPT_check_vertex_pivot_symmetry(co, data->pose_initial_co, data->symm)) {
+ if (SCULPT_check_vertex_pivot_symmetry(co, data->pose_initial_co, data->symm)) {
if (!is_duplicate) {
add_v3_v3(data->pose_origin, co);
data->tot_co++;
@@ -830,17 +830,21 @@ static bool pose_face_sets_fk_find_masked_floodfill_cb(
}
const int to_face_set = SCULPT_vertex_face_set_get(ss, to_v);
- if (SCULPT_vertex_has_unique_face_set(ss, to_v) &&
- !SCULPT_vertex_has_unique_face_set(ss, from_v) &&
- SCULPT_vertex_has_face_set(ss, from_v, to_face_set)) {
+ if (!BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(to_face_set))) {
+ if (SCULPT_vertex_has_unique_face_set(ss, to_v) &&
+ !SCULPT_vertex_has_unique_face_set(ss, from_v) &&
+ SCULPT_vertex_has_face_set(ss, from_v, to_face_set)) {
- if (data->floodfill_it[to_v] > data->masked_face_set_it) {
- data->masked_face_set = to_face_set;
- data->masked_face_set_it = data->floodfill_it[to_v];
- }
+ BLI_gset_add(data->visited_face_sets, POINTER_FROM_INT(to_face_set));
+
+ if (data->floodfill_it[to_v] >= data->masked_face_set_it) {
+ data->masked_face_set = to_face_set;
+ data->masked_face_set_it = data->floodfill_it[to_v];
+ }
- if (data->target_face_set == SCULPT_FACE_SET_NONE) {
- data->target_face_set = to_face_set;
+ if (data->target_face_set == SCULPT_FACE_SET_NONE) {
+ data->target_face_set = to_face_set;
+ }
}
}
@@ -875,8 +879,10 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk(
fdata.masked_face_set = SCULPT_FACE_SET_NONE;
fdata.target_face_set = SCULPT_FACE_SET_NONE;
fdata.masked_face_set_it = 0;
+ fdata.visited_face_sets = BLI_gset_int_new_ex("visited_face_sets", 3);
SCULPT_floodfill_execute(ss, &flood, pose_face_sets_fk_find_masked_floodfill_cb, &fdata);
SCULPT_floodfill_free(&flood);
+ BLI_gset_free(fdata.visited_face_sets, NULL);
int origin_count = 0;
float origin_acc[3] = {0.0f};
@@ -954,7 +960,7 @@ SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd,
ik_chain = pose_ik_chain_init_face_sets(sd, ob, ss, br, radius);
break;
case BRUSH_POSE_ORIGIN_FACE_SETS_FK:
- return pose_ik_chain_init_face_sets_fk(sd, ob, ss, radius, initial_location);
+ ik_chain = pose_ik_chain_init_face_sets_fk(sd, ob, ss, radius, initial_location);
break;
}
@@ -1000,7 +1006,7 @@ void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br
static void sculpt_pose_do_translate_deform(SculptSession *ss, Brush *brush)
{
SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain;
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
pose_solve_translate_chain(ik_chain, ss->cache->grab_delta);
}
@@ -1025,8 +1031,10 @@ static void sculpt_pose_do_scale_deform(SculptSession *ss, Brush *brush)
copy_v3_v3(ik_target, ss->cache->true_location);
add_v3_v3(ik_target, ss->cache->grab_delta);
- /* Solve the IK for the first segment to include rotation as part of scale. */
- pose_solve_ik_chain(ik_chain, ik_target, brush->flag2 & BRUSH_POSE_IK_ANCHORED);
+ /* Solve the IK for the first segment to include rotation as part of scale if enabled. */
+ if (!(brush->flag2 & BRUSH_POSE_USE_LOCK_ROTATION)) {
+ pose_solve_ik_chain(ik_chain, ik_target, brush->flag2 & BRUSH_POSE_IK_ANCHORED);
+ }
float scale[3];
copy_v3_fl(scale, sculpt_pose_get_scale_from_grab_delta(ss, ik_target));
@@ -1041,7 +1049,7 @@ static void sculpt_pose_do_twist_deform(SculptSession *ss, Brush *brush)
/* Calculate the maximum roll. 0.02 radians per pixel works fine. */
float roll = (ss->cache->initial_mouse[0] - ss->cache->mouse[0]) * ss->cache->bstrength * 0.02f;
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
pose_solve_roll_chain(ik_chain, brush, roll);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index be03978aa5e..7fbbcd1c896 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -62,78 +62,29 @@
#include <math.h>
#include <stdlib.h>
-/* For the smooth brush, uses the neighboring vertices around vert to calculate
- * a smoothed location for vert. Skips corner vertices (used by only one
- * polygon). */
-void SCULPT_neighbor_average(SculptSession *ss, float avg[3], uint vert)
+void SCULPT_neighbor_coords_average_interior(SculptSession *ss, float result[3], int index)
{
- const MeshElemMap *vert_map = &ss->pmap[vert];
- const MVert *mvert = ss->mvert;
- float(*deform_co)[3] = ss->deform_cos;
-
- /* Don't modify corner vertices. */
- if (vert_map->count > 1) {
- int total = 0;
-
- zero_v3(avg);
-
- for (int i = 0; i < vert_map->count; i++) {
- const MPoly *p = &ss->mpoly[vert_map->indices[i]];
- uint f_adj_v[2];
-
- if (poly_get_adj_loops_from_vert(p, ss->mloop, vert, f_adj_v) != -1) {
- for (int j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
- if (vert_map->count != 2 || ss->pmap[f_adj_v[j]].count <= 2) {
- add_v3_v3(avg, deform_co ? deform_co[f_adj_v[j]] : mvert[f_adj_v[j]].co);
-
- total++;
- }
- }
- }
- }
+ float avg[3] = {0.0f, 0.0f, 0.0f};
+ int total = 0;
- if (total > 0) {
- mul_v3_fl(avg, 1.0f / total);
- return;
- }
+ if (SCULPT_vertex_is_boundary(ss, index)) {
+ copy_v3_v3(result, SCULPT_vertex_co_get(ss, index));
+ return;
}
- copy_v3_v3(avg, deform_co ? deform_co[vert] : mvert[vert].co);
-}
-
-/* Same logic as neighbor_average(), but for bmesh rather than mesh. */
-void SCULPT_bmesh_neighbor_average(float avg[3], BMVert *v)
-{
- /* logic for 3 or more is identical. */
- const int vfcount = BM_vert_face_count_at_most(v, 3);
-
- /* Don't modify corner vertices. */
- if (vfcount > 1) {
- BMIter liter;
- BMLoop *l;
- int total = 0;
-
- zero_v3(avg);
-
- BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
- const BMVert *adj_v[2] = {l->prev->v, l->next->v};
-
- for (int i = 0; i < ARRAY_SIZE(adj_v); i++) {
- const BMVert *v_other = adj_v[i];
- if (vfcount != 2 || BM_vert_face_count_at_most(v_other, 2) <= 2) {
- add_v3_v3(avg, v_other->co);
- total++;
- }
- }
- }
-
- if (total > 0) {
- mul_v3_fl(avg, 1.0f / total);
- return;
- }
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
+ add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.index));
+ total++;
}
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
- copy_v3_v3(avg, v->co);
+ if (total > 0) {
+ mul_v3_v3fl(result, avg, 1.0f / total);
+ }
+ else {
+ copy_v3_v3(result, SCULPT_vertex_co_get(ss, index));
+ }
}
/* For bmesh: Average surrounding verts based on an orthogonality measure.
@@ -221,9 +172,7 @@ float SCULPT_neighbor_mask_average(SculptSession *ss, int index)
if (total > 0) {
return avg / (float)total;
}
- else {
- return SCULPT_vertex_mask_get(ss, index);
- }
+ return SCULPT_vertex_mask_get(ss, index);
}
void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index)
@@ -246,9 +195,9 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index
}
}
-static void do_smooth_brush_mesh_task_cb_ex(void *__restrict userdata,
- const int n,
- const TaskParallelTLS *__restrict tls)
+static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@@ -281,63 +230,6 @@ static void do_smooth_brush_mesh_task_cb_ex(void *__restrict userdata,
vd.index,
thread_id);
if (smooth_mask) {
- float val = SCULPT_neighbor_mask_average(ss, vd.vert_indices[vd.i]) - *vd.mask;
- val *= fade * bstrength;
- *vd.mask += val;
- CLAMP(*vd.mask, 0.0f, 1.0f);
- }
- else {
- float avg[3], val[3];
-
- SCULPT_neighbor_average(ss, avg, vd.vert_indices[vd.i]);
- sub_v3_v3v3(val, avg, vd.co);
-
- madd_v3_v3v3fl(val, vd.co, val, fade);
-
- SCULPT_clip(sd, ss, vd.co, val);
- }
-
- if (vd.mvert) {
- vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
- }
- }
- }
- BKE_pbvh_vertex_iter_end;
-}
-
-static void do_smooth_brush_bmesh_task_cb_ex(void *__restrict userdata,
- const int n,
- const TaskParallelTLS *__restrict tls)
-{
- SculptThreadedTaskData *data = userdata;
- SculptSession *ss = data->ob->sculpt;
- Sculpt *sd = data->sd;
- const Brush *brush = data->brush;
- const bool smooth_mask = data->smooth_mask;
- float bstrength = data->strength;
-
- PBVHVertexIter vd;
-
- CLAMP(bstrength, 0.0f, 1.0f);
-
- SculptBrushTest test;
- SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
- ss, &test, data->brush->falloff_shape);
- const int thread_id = BLI_task_parallel_thread_id(tls);
-
- BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
- {
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- smooth_mask ? 0.0f : *vd.mask,
- vd.index,
- thread_id);
- if (smooth_mask) {
float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
val *= fade * bstrength;
*vd.mask += val;
@@ -345,15 +237,11 @@ static void do_smooth_brush_bmesh_task_cb_ex(void *__restrict userdata,
}
else {
float avg[3], val[3];
-
- SCULPT_bmesh_neighbor_average(avg, vd.bm_vert);
+ SCULPT_neighbor_coords_average(ss, avg, vd.index);
sub_v3_v3v3(val, avg, vd.co);
-
madd_v3_v3v3fl(val, vd.co, val, fade);
-
SCULPT_clip(sd, ss, vd.co, val);
}
-
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -362,58 +250,6 @@ static void do_smooth_brush_bmesh_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_end;
}
-static void do_smooth_brush_multires_task_cb_ex(void *__restrict userdata,
- const int n,
- const TaskParallelTLS *__restrict tls)
-{
- SculptThreadedTaskData *data = userdata;
- SculptSession *ss = data->ob->sculpt;
- Sculpt *sd = data->sd;
- const Brush *brush = data->brush;
- const bool smooth_mask = data->smooth_mask;
- float bstrength = data->strength;
-
- PBVHVertexIter vd;
-
- CLAMP(bstrength, 0.0f, 1.0f);
-
- SculptBrushTest test;
- SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
- ss, &test, data->brush->falloff_shape);
-
- const int thread_id = BLI_task_parallel_thread_id(tls);
-
- BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
- {
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(
- ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
- vd.index,
- thread_id);
- if (smooth_mask) {
- float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask;
- val *= fade * bstrength;
- *vd.mask += val;
- CLAMP(*vd.mask, 0.0f, 1.0f);
- }
- else {
- float avg[3], val[3];
- SCULPT_neighbor_coords_average(ss, avg, vd.index);
- sub_v3_v3v3(val, avg, vd.co);
- madd_v3_v3v3fl(val, vd.co, val, fade);
- SCULPT_clip(sd, ss, vd.co, val);
- }
- }
- }
- BKE_pbvh_vertex_iter_end;
-}
-
void SCULPT_smooth(Sculpt *sd,
Object *ob,
PBVHNode **nodes,
@@ -440,6 +276,9 @@ void SCULPT_smooth(Sculpt *sd,
return;
}
+ SCULPT_vertex_random_access_init(ss);
+ SCULPT_boundary_info_ensure(ob);
+
for (iteration = 0; iteration <= count; iteration++) {
const float strength = (iteration != count) ? 1.0f : last;
@@ -454,18 +293,7 @@ void SCULPT_smooth(Sculpt *sd,
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
-
- switch (type) {
- case PBVH_GRIDS:
- BLI_task_parallel_range(0, totnode, &data, do_smooth_brush_multires_task_cb_ex, &settings);
- break;
- case PBVH_FACES:
- BLI_task_parallel_range(0, totnode, &data, do_smooth_brush_mesh_task_cb_ex, &settings);
- break;
- case PBVH_BMESH:
- BLI_task_parallel_range(0, totnode, &data, do_smooth_brush_bmesh_task_cb_ex, &settings);
- break;
- }
+ BLI_task_parallel_range(0, totnode, &data, do_smooth_brush_task_cb_ex, &settings);
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 6ede631eb11..fd800ca2c18 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -167,9 +167,7 @@ static bool test_swap_v3_v3(float a[3], float b[3])
swap_v3_v3(a, b);
return true;
}
- else {
- return false;
- }
+ return false;
}
static bool sculpt_undo_restore_deformed(
@@ -179,9 +177,7 @@ static bool sculpt_undo_restore_deformed(
copy_v3_v3(unode->co[uindex], ss->deform_cos[oindex]);
return true;
}
- else {
- return false;
- }
+ return false;
}
static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, SculptUndoNode *unode)
@@ -1270,17 +1266,17 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType
BLI_thread_unlock(LOCK_CUSTOM1);
return unode;
}
- else if (type == SCULPT_UNDO_GEOMETRY) {
+ if (type == SCULPT_UNDO_GEOMETRY) {
unode = sculpt_undo_geometry_push(ob, type);
BLI_thread_unlock(LOCK_CUSTOM1);
return unode;
}
- else if (type == SCULPT_UNDO_FACE_SETS) {
+ if (type == SCULPT_UNDO_FACE_SETS) {
unode = sculpt_undo_face_sets_push(ob, type);
BLI_thread_unlock(LOCK_CUSTOM1);
return unode;
}
- else if ((unode = SCULPT_undo_get_node(node))) {
+ if ((unode = SCULPT_undo_get_node(node))) {
BLI_thread_unlock(LOCK_CUSTOM1);
return unode;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index d6b259c9ac0..be509f4aed6 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -228,8 +228,6 @@ static void HC_relaxation_iteration_uv(BMEditMesh *em,
}
MEM_freeN(tmp_uvdata);
-
- return;
}
static void laplacian_relaxation_iteration_uv(BMEditMesh *em,
@@ -302,8 +300,6 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em,
}
MEM_freeN(tmp_uvdata);
-
- return;
}
static void uv_sculpt_stroke_apply(bContext *C,
@@ -492,7 +488,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
op->customdata = data;
- BKE_curvemapping_initialize(ts->uvsculpt->paint.brush->curve);
+ BKE_curvemapping_init(ts->uvsculpt->paint.brush->curve);
if (data) {
int counter = 0, i;
diff --git a/source/blender/editors/sound/sound_intern.h b/source/blender/editors/sound/sound_intern.h
index 40cdb9ccf02..f4797838be0 100644
--- a/source/blender/editors/sound/sound_intern.h
+++ b/source/blender/editors/sound/sound_intern.h
@@ -21,7 +21,4 @@
* \ingroup edsnd
*/
-#ifndef __SOUND_INTERN_H__
-#define __SOUND_INTERN_H__
-
-#endif /* __SOUND_INTERN_H__ */
+#pragma once
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 2e52f3aa8a8..050dca07c34 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -564,6 +564,9 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op)
PropertyRNA *prop_codec;
PropertyRNA *prop_bitrate;
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
AUD_Container container = RNA_enum_get(op->ptr, "container");
AUD_Codec codec = RNA_enum_get(op->ptr, "codec");
diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c
index b5a0c4a9e22..bffd6cc421d 100644
--- a/source/blender/editors/space_action/action_data.c
+++ b/source/blender/editors/space_action/action_data.c
@@ -337,10 +337,9 @@ static int action_pushdown_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
return OPERATOR_CANCELLED;
}
- else {
- /* action can be safely added */
- BKE_nla_action_pushdown(adt);
- }
+
+ /* 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...
@@ -383,24 +382,23 @@ static int action_stash_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
return OPERATOR_CANCELLED;
}
- else {
- /* stash the action */
- if (BKE_nla_action_stash(adt)) {
- /* The stash operation will remove the user already,
- * so the flushing step later shouldn't double up
- * the user-count fixes. Hence, we must unset this ref
- * first before setting the new action.
- */
- saction->action = NULL;
- }
- else {
- /* 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);
+ /* stash the action */
+ if (BKE_nla_action_stash(adt)) {
+ /* The stash operation will remove the user already,
+ * so the flushing step later shouldn't double up
+ * the user-count fixes. Hence, we must unset this ref
+ * first before setting the new action.
+ */
+ saction->action = NULL;
+ }
+ else {
+ /* 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 */
@@ -486,28 +484,27 @@ static int action_stash_create_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
return OPERATOR_CANCELLED;
}
- else {
- /* 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);
+ /* stash the action */
+ if (BKE_nla_action_stash(adt)) {
+ bAction *new_action = NULL;
- /* The stash operation will remove the user already,
- * so the flushing step later shouldn't double up
- * the user-count fixes. Hence, we must unset this ref
- * first before setting the new action.
- */
- saction->action = NULL;
- actedit_change_action(C, new_action);
- }
- else {
- /* action has already been added - simply warn about this, and clear */
- BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
- actedit_change_action(C, 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 user-count fixes. Hence, we must unset this ref
+ * first before setting the new action.
+ */
+ saction->action = NULL;
+ actedit_change_action(C, new_action);
+ }
+ else {
+ /* action has already been added - simply warn about this, and clear */
+ BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
+ actedit_change_action(C, NULL);
}
}
@@ -709,11 +706,11 @@ static NlaStrip *action_layer_get_nlastrip(ListBase *strips, float ctime)
/* in range - use this one */
return strip;
}
- else if ((ctime < strip->start) && (strip->prev == NULL)) {
+ if ((ctime < strip->start) && (strip->prev == NULL)) {
/* before first - use this one */
return strip;
}
- else if ((ctime > strip->end) && (strip->next == NULL)) {
+ if ((ctime > strip->end) && (strip->next == NULL)) {
/* after last - use this one */
return strip;
}
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index aa784800be0..af8e0e9d9de 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -272,9 +272,8 @@ static int actkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
if (ac.scene == NULL) {
return OPERATOR_CANCELLED;
}
- else {
- scene = ac.scene;
- }
+
+ scene = ac.scene;
/* set the range directly */
get_keyframe_extents(&ac, &min, &max, false);
@@ -725,9 +724,10 @@ static void insert_action_keys(bAnimContext *ac, short mode)
flag = ANIM_get_keyframing_flags(scene, true);
/* insert keyframes */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(ac->depsgraph,
+ (float)CFRA);
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
- float cfra = (float)CFRA;
/* Read value from property the F-Curve represents, or from the curve only?
* - ale->id != NULL:
@@ -746,7 +746,7 @@ static void insert_action_keys(bAnimContext *ac, short mode)
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path,
fcu->array_index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
&nla_cache,
flag);
@@ -755,8 +755,9 @@ static void insert_action_keys(bAnimContext *ac, short mode)
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
/* adjust current frame for NLA-scaling */
+ float cfra = anim_eval_context.eval_time;
if (adt) {
- cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
}
const float curval = evaluate_fcurve(fcu, cfra);
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index bf1b90bbe98..ffe0606c98f 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -21,8 +21,7 @@
* \ingroup spaction
*/
-#ifndef __ACTION_INTERN_H__
-#define __ACTION_INTERN_H__
+#pragma once
struct ARegion;
struct ARegionType;
@@ -142,5 +141,3 @@ enum eActKeys_Mirror_Mode {
/* action_ops.c */
void action_operatortypes(void);
void action_keymap(struct wmKeyConfig *keyconf);
-
-#endif /* __ACTION_INTERN_H__ */
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 079cee290ae..db55eff8284 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -60,7 +60,7 @@
/* ******************** default callbacks for action space ***************** */
-static SpaceLink *action_new(const ScrArea *area, const Scene *scene)
+static SpaceLink *action_create(const ScrArea *area, const Scene *scene)
{
SpaceAction *saction;
ARegion *region;
@@ -863,7 +863,7 @@ void ED_spacetype_action(void)
st->spaceid = SPACE_ACTION;
strncpy(st->name, "Action", BKE_ST_MAXNAME);
- st->new = action_new;
+ st->create = action_create;
st->free = action_free;
st->init = action_init;
st->duplicate = action_duplicate;
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index e084d5fcdf2..1656a76e2d4 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -44,7 +44,6 @@
#include "ED_gizmo_library.h"
#include "ED_gpencil.h"
#include "ED_lattice.h"
-#include "ED_logic.h"
#include "ED_markers.h"
#include "ED_mask.h"
#include "ED_mball.h"
@@ -159,6 +158,7 @@ void ED_spacemacros_init(void)
* We need to have them go after python operators too */
ED_operatormacros_armature();
ED_operatormacros_mesh();
+ ED_operatormacros_uvedit();
ED_operatormacros_metaball();
ED_operatormacros_node();
ED_operatormacros_object();
@@ -280,7 +280,7 @@ void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
void ED_spacetype_xxx(void);
/* allocate and init some vars */
-static SpaceLink *xxx_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *xxx_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
return NULL;
}
@@ -324,7 +324,7 @@ void ED_spacetype_xxx(void)
st.spaceid = SPACE_VIEW3D;
- st.new = xxx_new;
+ st.create = xxx_create;
st.free = xxx_free;
st.init = xxx_init;
st.duplicate = xxx_duplicate;
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index ba618083620..5885d3dcbb0 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -56,7 +56,6 @@
#include "RNA_access.h"
#include "ED_armature.h"
-#include "ED_buttons.h"
#include "ED_physics.h"
#include "ED_screen.h"
@@ -102,7 +101,7 @@ static PointerRNA *get_pointer_type(ButsContextPath *path, StructRNA *type)
/************************* Creating the Path ************************/
-static int buttons_context_path_scene(ButsContextPath *path)
+static bool buttons_context_path_scene(ButsContextPath *path)
{
PointerRNA *ptr = &path->ptr[path->len - 1];
@@ -146,7 +145,7 @@ static int buttons_context_path_world(ButsContextPath *path)
return 1;
}
/* if we have a scene, use the scene's world */
- else if (buttons_context_path_scene(path)) {
+ if (buttons_context_path_scene(path)) {
scene = path->ptr[path->len - 1].data;
world = scene->world;
@@ -155,49 +154,48 @@ static int buttons_context_path_world(ButsContextPath *path)
path->len++;
return 1;
}
- else {
- return 1;
- }
+
+ return 1;
}
/* no path to a world possible */
return 0;
}
-static int buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window)
+static bool buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window)
{
FreestyleLineStyle *linestyle;
PointerRNA *ptr = &path->ptr[path->len - 1];
/* if we already have a (pinned) linestyle, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_FreestyleLineStyle)) {
- return 1;
+ return true;
}
/* if we have a view layer, use the lineset's linestyle */
- else if (buttons_context_path_view_layer(path, window)) {
+ if (buttons_context_path_view_layer(path, window)) {
ViewLayer *view_layer = path->ptr[path->len - 1].data;
linestyle = BKE_linestyle_active_from_view_layer(view_layer);
if (linestyle) {
RNA_id_pointer_create(&linestyle->id, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to a linestyle possible */
- return 0;
+ return false;
}
-static int buttons_context_path_object(ButsContextPath *path)
+static bool buttons_context_path_object(ButsContextPath *path)
{
PointerRNA *ptr = &path->ptr[path->len - 1];
/* if we already have a (pinned) object, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Object)) {
- return 1;
+ return true;
}
if (!RNA_struct_is_a(ptr->type, &RNA_ViewLayer)) {
- return 0;
+ return false;
}
ViewLayer *view_layer = ptr->data;
@@ -207,76 +205,76 @@ static int buttons_context_path_object(ButsContextPath *path)
RNA_id_pointer_create(&ob->id, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
/* no path to a object possible */
- return 0;
+ return false;
}
-static int buttons_context_path_data(ButsContextPath *path, int type)
+static bool buttons_context_path_data(ButsContextPath *path, int type)
{
Object *ob;
PointerRNA *ptr = &path->ptr[path->len - 1];
/* if we already have a data, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Mesh) && (type == -1 || type == OB_MESH)) {
- return 1;
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_Curve) &&
- (type == -1 || ELEM(type, OB_CURVE, OB_SURF, OB_FONT))) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_Curve) &&
+ (type == -1 || ELEM(type, OB_CURVE, OB_SURF, OB_FONT))) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_Armature) && (type == -1 || type == OB_ARMATURE)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_Armature) && (type == -1 || type == OB_ARMATURE)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_MetaBall) && (type == -1 || type == OB_MBALL)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_MetaBall) && (type == -1 || type == OB_MBALL)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_Lattice) && (type == -1 || type == OB_LATTICE)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_Lattice) && (type == -1 || type == OB_LATTICE)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_Camera) && (type == -1 || type == OB_CAMERA)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_Camera) && (type == -1 || type == OB_CAMERA)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_Light) && (type == -1 || type == OB_LAMP)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_Light) && (type == -1 || type == OB_LAMP)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && (type == -1 || type == OB_LIGHTPROBE)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && (type == -1 || type == OB_LIGHTPROBE)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) {
+ return true;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) {
- return 1;
+ if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) {
+ return true;
}
/* try to get an object in the path, no pinning supported here */
- else if (buttons_context_path_object(path)) {
+ if (buttons_context_path_object(path)) {
ob = path->ptr[path->len - 1].data;
if (ob && (type == -1 || type == ob->type)) {
RNA_id_pointer_create(ob->data, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to data possible */
- return 0;
+ return false;
}
-static int buttons_context_path_modifier(ButsContextPath *path)
+static bool buttons_context_path_modifier(ButsContextPath *path)
{
Object *ob;
@@ -293,14 +291,14 @@ static int buttons_context_path_modifier(ButsContextPath *path)
OB_HAIR,
OB_POINTCLOUD,
OB_VOLUME)) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-static int buttons_context_path_shaderfx(ButsContextPath *path)
+static bool buttons_context_path_shaderfx(ButsContextPath *path)
{
Object *ob;
@@ -308,14 +306,14 @@ static int buttons_context_path_shaderfx(ButsContextPath *path)
ob = path->ptr[path->len - 1].data;
if (ob && ELEM(ob->type, OB_GPENCIL)) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-static int buttons_context_path_material(ButsContextPath *path)
+static bool buttons_context_path_material(ButsContextPath *path)
{
Object *ob;
PointerRNA *ptr = &path->ptr[path->len - 1];
@@ -323,25 +321,25 @@ static int buttons_context_path_material(ButsContextPath *path)
/* if we already have a (pinned) material, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Material)) {
- return 1;
+ return true;
}
/* if we have an object, use the object material slot */
- else if (buttons_context_path_object(path)) {
+ if (buttons_context_path_object(path)) {
ob = path->ptr[path->len - 1].data;
if (ob && OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
ma = BKE_object_material_get(ob, ob->actcol);
RNA_id_pointer_create(&ma->id, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to a material possible */
- return 0;
+ return false;
}
-static int buttons_context_path_bone(ButsContextPath *path)
+static bool buttons_context_path_bone(ButsContextPath *path)
{
bArmature *arm;
EditBone *edbo;
@@ -355,29 +353,29 @@ static int buttons_context_path_bone(ButsContextPath *path)
edbo = arm->act_edbone;
RNA_pointer_create(&arm->id, &RNA_EditBone, edbo, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
else {
if (arm->act_bone) {
RNA_pointer_create(&arm->id, &RNA_Bone, arm->act_bone, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
}
/* no path to a bone possible */
- return 0;
+ return false;
}
-static int buttons_context_path_pose_bone(ButsContextPath *path)
+static bool buttons_context_path_pose_bone(ButsContextPath *path)
{
PointerRNA *ptr = &path->ptr[path->len - 1];
/* if we already have a (pinned) PoseBone, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) {
- return 1;
+ return true;
}
/* if we have an armature, get the active bone */
@@ -386,25 +384,24 @@ static int buttons_context_path_pose_bone(ButsContextPath *path)
bArmature *arm = ob->data; /* path->ptr[path->len-1].data - works too */
if (ob->type != OB_ARMATURE || arm->edbo) {
- return 0;
+ return false;
}
- else {
- if (arm->act_bone) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, arm->act_bone->name);
- if (pchan) {
- RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &path->ptr[path->len]);
- path->len++;
- return 1;
- }
+
+ if (arm->act_bone) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, arm->act_bone->name);
+ if (pchan) {
+ RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &path->ptr[path->len]);
+ path->len++;
+ return true;
}
}
}
/* no path to a bone possible */
- return 0;
+ return false;
}
-static int buttons_context_path_particle(ButsContextPath *path)
+static bool buttons_context_path_particle(ButsContextPath *path)
{
Object *ob;
ParticleSystem *psys;
@@ -412,7 +409,7 @@ static int buttons_context_path_particle(ButsContextPath *path)
/* if we already have (pinned) particle settings, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_ParticleSettings)) {
- return 1;
+ return true;
}
/* if we have an object, get the active particle system */
if (buttons_context_path_object(path)) {
@@ -423,15 +420,15 @@ static int buttons_context_path_particle(ButsContextPath *path)
RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to a particle system possible */
- return 0;
+ return false;
}
-static int buttons_context_path_brush(const bContext *C, ButsContextPath *path)
+static bool buttons_context_path_brush(const bContext *C, ButsContextPath *path)
{
Scene *scene;
Brush *br = NULL;
@@ -439,10 +436,10 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path)
/* if we already have a (pinned) brush, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Brush)) {
- return 1;
+ return true;
}
/* if we have a scene, use the toolsettings brushes */
- else if (buttons_context_path_scene(path)) {
+ if (buttons_context_path_scene(path)) {
scene = path->ptr[path->len - 1].data;
if (scene) {
@@ -455,32 +452,32 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path)
RNA_id_pointer_create((ID *)br, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to a brush possible */
- return 0;
+ return false;
}
-static int buttons_context_path_texture(const bContext *C,
- ButsContextPath *path,
- ButsContextTexture *ct)
+static bool buttons_context_path_texture(const bContext *C,
+ ButsContextPath *path,
+ ButsContextTexture *ct)
{
PointerRNA *ptr = &path->ptr[path->len - 1];
ID *id;
if (!ct) {
- return 0;
+ return false;
}
/* if we already have a (pinned) texture, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Texture)) {
- return 1;
+ return true;
}
if (!ct->user) {
- return 0;
+ return false;
}
id = ct->user->id;
@@ -505,7 +502,7 @@ static int buttons_context_path_texture(const bContext *C,
path->len++;
}
- return 1;
+ return true;
}
#ifdef WITH_FREESTYLE
@@ -534,7 +531,7 @@ static bool buttons_context_linestyle_pinnable(const bContext *C, ViewLayer *vie
}
#endif
-static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
+static bool buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
{
/* Note we don't use CTX_data here, instead we get it from the window.
* Otherwise there is a loop reading the context that we are setting. */
@@ -629,27 +626,27 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
found = buttons_context_path_pose_bone(path);
break;
default:
- found = 0;
+ found = false;
break;
}
return found;
}
-static int buttons_shading_context(const bContext *C, int mainb)
+static bool buttons_shading_context(const bContext *C, int mainb)
{
wmWindow *window = CTX_wm_window(C);
ViewLayer *view_layer = WM_window_get_active_view_layer(window);
Object *ob = OBACT(view_layer);
if (ELEM(mainb, BCONTEXT_MATERIAL, BCONTEXT_WORLD, BCONTEXT_TEXTURE)) {
- return 1;
+ return true;
}
if (mainb == BCONTEXT_DATA && ob && ELEM(ob->type, OB_LAMP, OB_CAMERA)) {
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static int buttons_shading_new_context(const bContext *C, int flag)
@@ -661,10 +658,10 @@ static int buttons_shading_new_context(const bContext *C, int flag)
if (flag & (1 << BCONTEXT_MATERIAL)) {
return BCONTEXT_MATERIAL;
}
- else if (ob && ELEM(ob->type, OB_LAMP, OB_CAMERA) && (flag & (1 << BCONTEXT_DATA))) {
+ if (ob && ELEM(ob->type, OB_LAMP, OB_CAMERA) && (flag & (1 << BCONTEXT_DATA))) {
return BCONTEXT_DATA;
}
- else if (flag & (1 << BCONTEXT_WORLD)) {
+ if (flag & (1 << BCONTEXT_WORLD)) {
return BCONTEXT_WORLD;
}
@@ -825,72 +822,72 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
}
return 1;
}
- else if (CTX_data_equals(member, "scene")) {
+ if (CTX_data_equals(member, "scene")) {
/* Do not return one here if scene not found in path,
* in this case we want to get default context scene! */
return set_pointer_type(path, result, &RNA_Scene);
}
- else if (CTX_data_equals(member, "world")) {
+ if (CTX_data_equals(member, "world")) {
set_pointer_type(path, result, &RNA_World);
return 1;
}
- else if (CTX_data_equals(member, "object")) {
+ if (CTX_data_equals(member, "object")) {
set_pointer_type(path, result, &RNA_Object);
return 1;
}
- else if (CTX_data_equals(member, "mesh")) {
+ if (CTX_data_equals(member, "mesh")) {
set_pointer_type(path, result, &RNA_Mesh);
return 1;
}
- else if (CTX_data_equals(member, "armature")) {
+ if (CTX_data_equals(member, "armature")) {
set_pointer_type(path, result, &RNA_Armature);
return 1;
}
- else if (CTX_data_equals(member, "lattice")) {
+ if (CTX_data_equals(member, "lattice")) {
set_pointer_type(path, result, &RNA_Lattice);
return 1;
}
- else if (CTX_data_equals(member, "curve")) {
+ if (CTX_data_equals(member, "curve")) {
set_pointer_type(path, result, &RNA_Curve);
return 1;
}
- else if (CTX_data_equals(member, "meta_ball")) {
+ if (CTX_data_equals(member, "meta_ball")) {
set_pointer_type(path, result, &RNA_MetaBall);
return 1;
}
- else if (CTX_data_equals(member, "light")) {
+ if (CTX_data_equals(member, "light")) {
set_pointer_type(path, result, &RNA_Light);
return 1;
}
- else if (CTX_data_equals(member, "camera")) {
+ if (CTX_data_equals(member, "camera")) {
set_pointer_type(path, result, &RNA_Camera);
return 1;
}
- else if (CTX_data_equals(member, "speaker")) {
+ if (CTX_data_equals(member, "speaker")) {
set_pointer_type(path, result, &RNA_Speaker);
return 1;
}
- else if (CTX_data_equals(member, "lightprobe")) {
+ if (CTX_data_equals(member, "lightprobe")) {
set_pointer_type(path, result, &RNA_LightProbe);
return 1;
}
- else if (CTX_data_equals(member, "hair")) {
+ if (CTX_data_equals(member, "hair")) {
set_pointer_type(path, result, &RNA_Hair);
return 1;
}
- else if (CTX_data_equals(member, "pointcloud")) {
+ if (CTX_data_equals(member, "pointcloud")) {
set_pointer_type(path, result, &RNA_PointCloud);
return 1;
}
- else if (CTX_data_equals(member, "volume")) {
+ if (CTX_data_equals(member, "volume")) {
set_pointer_type(path, result, &RNA_Volume);
return 1;
}
- else if (CTX_data_equals(member, "material")) {
+ if (CTX_data_equals(member, "material")) {
set_pointer_type(path, result, &RNA_Material);
return 1;
}
- else if (CTX_data_equals(member, "texture")) {
+ if (CTX_data_equals(member, "texture")) {
ButsContextTexture *ct = sbuts->texuser;
if (ct) {
@@ -899,7 +896,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
- else if (CTX_data_equals(member, "material_slot")) {
+ if (CTX_data_equals(member, "material_slot")) {
PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
if (ptr) {
@@ -917,7 +914,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
- else if (CTX_data_equals(member, "texture_user")) {
+ if (CTX_data_equals(member, "texture_user")) {
ButsContextTexture *ct = sbuts->texuser;
if (!ct) {
@@ -931,7 +928,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
- else if (CTX_data_equals(member, "texture_user_property")) {
+ if (CTX_data_equals(member, "texture_user_property")) {
ButsContextTexture *ct = sbuts->texuser;
if (!ct) {
@@ -945,7 +942,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
- else if (CTX_data_equals(member, "texture_node")) {
+ if (CTX_data_equals(member, "texture_node")) {
ButsContextTexture *ct = sbuts->texuser;
if (ct) {
@@ -956,8 +953,9 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "texture_slot")) {
+ if (CTX_data_equals(member, "texture_slot")) {
ButsContextTexture *ct = sbuts->texuser;
PointerRNA *ptr;
@@ -984,23 +982,23 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
- else if (CTX_data_equals(member, "bone")) {
+ if (CTX_data_equals(member, "bone")) {
set_pointer_type(path, result, &RNA_Bone);
return 1;
}
- else if (CTX_data_equals(member, "edit_bone")) {
+ if (CTX_data_equals(member, "edit_bone")) {
set_pointer_type(path, result, &RNA_EditBone);
return 1;
}
- else if (CTX_data_equals(member, "pose_bone")) {
+ if (CTX_data_equals(member, "pose_bone")) {
set_pointer_type(path, result, &RNA_PoseBone);
return 1;
}
- else if (CTX_data_equals(member, "particle_system")) {
+ if (CTX_data_equals(member, "particle_system")) {
set_pointer_type(path, result, &RNA_ParticleSystem);
return 1;
}
- else if (CTX_data_equals(member, "particle_system_editable")) {
+ if (CTX_data_equals(member, "particle_system_editable")) {
if (PE_poll((bContext *)C)) {
set_pointer_type(path, result, &RNA_ParticleSystem);
}
@@ -1009,7 +1007,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
}
return 1;
}
- else if (CTX_data_equals(member, "particle_settings")) {
+ if (CTX_data_equals(member, "particle_settings")) {
/* only available when pinned */
PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSettings);
@@ -1017,20 +1015,20 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
CTX_data_pointer_set(result, ptr->owner_id, &RNA_ParticleSettings, ptr->data);
return 1;
}
- 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->owner_id, &RNA_ParticleSettings, part);
- return 1;
- }
+ /* 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->owner_id, &RNA_ParticleSettings, part);
+ return 1;
}
+
set_pointer_type(path, result, &RNA_ParticleSettings);
return 1;
}
- else if (CTX_data_equals(member, "cloth")) {
+ if (CTX_data_equals(member, "cloth")) {
PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
if (ptr && ptr->data) {
@@ -1039,8 +1037,9 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
CTX_data_pointer_set(result, &ob->id, &RNA_ClothModifier, md);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "soft_body")) {
+ if (CTX_data_equals(member, "soft_body")) {
PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
if (ptr && ptr->data) {
@@ -1049,9 +1048,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
CTX_data_pointer_set(result, &ob->id, &RNA_SoftBodyModifier, md);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "fluid")) {
+ if (CTX_data_equals(member, "fluid")) {
PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
if (ptr && ptr->data) {
@@ -1060,8 +1060,9 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
CTX_data_pointer_set(result, &ob->id, &RNA_FluidModifier, md);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "collision")) {
+ if (CTX_data_equals(member, "collision")) {
PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
if (ptr && ptr->data) {
@@ -1070,12 +1071,13 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
CTX_data_pointer_set(result, &ob->id, &RNA_CollisionModifier, md);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "brush")) {
+ if (CTX_data_equals(member, "brush")) {
set_pointer_type(path, result, &RNA_Brush);
return 1;
}
- else if (CTX_data_equals(member, "dynamic_paint")) {
+ if (CTX_data_equals(member, "dynamic_paint")) {
PointerRNA *ptr = get_pointer_type(path, &RNA_Object);
if (ptr && ptr->data) {
@@ -1084,20 +1086,17 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
CTX_data_pointer_set(result, &ob->id, &RNA_DynamicPaintModifier, md);
return 1;
}
+ return -1; /* found but not available */
}
- else if (CTX_data_equals(member, "line_style")) {
+ if (CTX_data_equals(member, "line_style")) {
set_pointer_type(path, result, &RNA_FreestyleLineStyle);
return 1;
}
- else if (CTX_data_equals(member, "gpencil")) {
+ if (CTX_data_equals(member, "gpencil")) {
set_pointer_type(path, result, &RNA_GreasePencil);
return 1;
}
- else {
- return 0; /* not found */
- }
-
- return -1; /* found but not available */
+ return 0; /* not found */
}
/************************* Drawing the Path ************************/
@@ -1148,13 +1147,13 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
ptr->type == &RNA_Scene)) {
continue;
}
- else if ((!ELEM(sbuts->mainb,
- BCONTEXT_RENDER,
- BCONTEXT_OUTPUT,
- BCONTEXT_SCENE,
- BCONTEXT_VIEW_LAYER,
- BCONTEXT_WORLD) &&
- ptr->type == &RNA_ViewLayer)) {
+ if ((!ELEM(sbuts->mainb,
+ BCONTEXT_RENDER,
+ BCONTEXT_OUTPUT,
+ BCONTEXT_SCENE,
+ BCONTEXT_VIEW_LAYER,
+ BCONTEXT_WORLD) &&
+ ptr->type == &RNA_ViewLayer)) {
continue;
}
diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index 64166f15ea3..911cf4526bb 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -21,8 +21,7 @@
* \ingroup spbuttons
*/
-#ifndef __BUTTONS_INTERN_H__
-#define __BUTTONS_INTERN_H__
+#pragma once
#include "DNA_listBase.h"
#include "RNA_types.h"
@@ -97,5 +96,3 @@ void buttons_texture_context_compute(const struct bContext *C, struct SpacePrope
void BUTTONS_OT_file_browse(struct wmOperatorType *ot);
void BUTTONS_OT_directory_browse(struct wmOperatorType *ot);
void BUTTONS_OT_context_menu(struct wmOperatorType *ot);
-
-#endif /* __BUTTONS_INTERN_H__ */
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 53a904438eb..a062b178fc8 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -52,7 +52,9 @@
#include "buttons_intern.h" /* own include */
-/********************** context_menu operator *********************/
+/* -------------------------------------------------------------------- */
+/** \name Context Menu Operator
+ * \{ */
static int context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
@@ -67,17 +69,21 @@ static int context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven
void BUTTONS_OT_context_menu(wmOperatorType *ot)
{
- /* identifiers */
+ /* Identifiers. */
ot->name = "Context Menu";
ot->description = "Display properties editor context_menu";
ot->idname = "BUTTONS_OT_context_menu";
- /* api callbacks */
+ /* Callbacks. */
ot->invoke = context_menu_invoke;
ot->poll = ED_operator_buttons_active;
}
-/********************** filebrowse operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name File Browse Operator
+ * \{ */
typedef struct FileBrowseOp {
PointerRNA ptr;
@@ -101,7 +107,7 @@ static int file_browse_exec(bContext *C, wmOperator *op)
str = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0);
- /* add slash for directories, important for some properties */
+ /* Add slash for directories, important for some properties. */
if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) {
const bool is_relative = RNA_boolean_get(op->ptr, "relative_path");
id = fbo->ptr.owner_id;
@@ -110,7 +116,7 @@ static int file_browse_exec(bContext *C, wmOperator *op)
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 */
+ /* Do this first so '//' isnt converted to '//\' on windows. */
BLI_path_slash_ensure(path);
if (is_relative) {
BLI_strncpy(path, str, FILE_MAX);
@@ -139,7 +145,7 @@ static int file_browse_exec(bContext *C, wmOperator *op)
ED_undo_push(C, undostr);
}
- /* special, annoying exception, filesel on redo panel [#26618] */
+ /* Special annoying exception, filesel on redo panel [#26618]. */
{
wmOperator *redo_op = WM_operator_last_redo(C);
if (redo_op) {
@@ -187,8 +193,8 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
str = RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL);
- /* useful yet irritating feature, Shift+Click to open the file
- * Alt+Click to browse a folder in the OS's browser */
+ /* Useful yet irritating feature, Shift+Click to open the file
+ * Alt+Click to browse a folder in the OS's browser. */
if (event->shift || event->alt) {
wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
PointerRNA props_ptr;
@@ -208,64 +214,63 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
MEM_freeN(str);
return OPERATOR_CANCELLED;
}
- else {
- PropertyRNA *prop_relpath;
- const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" :
- "filepath";
- fbo = MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp");
- fbo->ptr = ptr;
- fbo->prop = prop;
- fbo->is_undo = is_undo;
- fbo->is_userdef = is_userdef;
- op->customdata = fbo;
-
- /* normally ED_fileselect_get_params would handle this but we need to because of stupid
- * user-prefs exception - campbell */
- if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) {
- if (!RNA_property_is_set(op->ptr, prop_relpath)) {
- bool is_relative = (U.flag & USER_RELPATHS) != 0;
-
- /* while we want to follow the defaults,
- * we better not switch existing paths relative/absolute state. */
- if (str[0]) {
- is_relative = BLI_path_is_rel(str);
- }
-
- if (UNLIKELY(ptr.data == &U)) {
- is_relative = false;
- }
-
- /* annoying exception!, if we're dealing with the user prefs, default relative to be off */
- RNA_property_boolean_set(op->ptr, prop_relpath, is_relative);
+
+ PropertyRNA *prop_relpath;
+ const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" :
+ "filepath";
+ fbo = MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp");
+ fbo->ptr = ptr;
+ fbo->prop = prop;
+ fbo->is_undo = is_undo;
+ fbo->is_userdef = is_userdef;
+ op->customdata = fbo;
+
+ /* Normally ED_fileselect_get_params would handle this but we need to because of stupid
+ * user-prefs exception. - campbell */
+ if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) {
+ if (!RNA_property_is_set(op->ptr, prop_relpath)) {
+ bool is_relative = (U.flag & USER_RELPATHS) != 0;
+
+ /* While we want to follow the defaults,
+ * we better not switch existing paths relative/absolute state. */
+ if (str[0]) {
+ is_relative = BLI_path_is_rel(str);
+ }
+
+ if (UNLIKELY(ptr.data == &U)) {
+ is_relative = false;
}
+
+ /* Annoying exception!, if we're dealing with the user prefs, default relative to be off. */
+ RNA_property_boolean_set(op->ptr, prop_relpath, is_relative);
}
+ }
- RNA_string_set(op->ptr, path_prop, str);
- MEM_freeN(str);
+ RNA_string_set(op->ptr, path_prop, str);
+ MEM_freeN(str);
- WM_event_add_fileselect(C, op);
+ WM_event_add_fileselect(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ return OPERATOR_RUNNING_MODAL;
}
void BUTTONS_OT_file_browse(wmOperatorType *ot)
{
- /* identifiers */
+ /* Identifiers. */
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 */
+ /* Callbacks. */
ot->invoke = file_browse_invoke;
ot->exec = file_browse_exec;
ot->cancel = file_browse_cancel;
- /* conditional undo based on button flag */
+ /* Conditional undo based on button flag. */
ot->flag = 0;
- /* properties */
+ /* Properties. */
WM_operator_properties_filesel(ot,
0,
FILE_SPECIAL,
@@ -275,7 +280,7 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot)
FILE_SORT_ALPHA);
}
-/* second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY */
+/* Second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY. */
void BUTTONS_OT_directory_browse(wmOperatorType *ot)
{
/* identifiers */
@@ -301,3 +306,5 @@ void BUTTONS_OT_directory_browse(wmOperatorType *ot)
FILE_DEFAULTDISPLAY,
FILE_SORT_ALPHA);
}
+
+/** \} */
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 3dc5eca8a8b..8e5aa00115b 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -63,7 +63,6 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "ED_buttons.h"
#include "ED_node.h"
#include "ED_screen.h"
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 71b86996989..dc34e56dc92 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -35,6 +35,7 @@
#include "BKE_screen.h"
#include "BKE_shader_fx.h"
+#include "ED_buttons.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_view3d.h" /* To draw toolbar UI. */
@@ -49,13 +50,11 @@
#include "UI_resources.h"
-#include "GPU_glew.h"
-
#include "buttons_intern.h" /* own include */
/* ******************** default callbacks for buttons space ***************** */
-static SpaceLink *buttons_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *buttons_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceProperties *sbuts;
@@ -139,6 +138,98 @@ static void buttons_main_region_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler(&region->handlers, keymap);
}
+/**
+ * Fills an array with the tab context values for the properties editor. -1 signals a separator.
+ *
+ * \return The total number of items in the array returned.
+ */
+int ED_buttons_tabs_list(SpaceProperties *sbuts, int *context_tabs_array)
+{
+ int length = 0;
+ if (sbuts->pathflag & (1 << BCONTEXT_TOOL)) {
+ context_tabs_array[length] = BCONTEXT_TOOL;
+ length++;
+ }
+ if (length != 0) {
+ context_tabs_array[length] = -1;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
+ context_tabs_array[length] = BCONTEXT_RENDER;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_OUTPUT)) {
+ context_tabs_array[length] = BCONTEXT_OUTPUT;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) {
+ context_tabs_array[length] = BCONTEXT_VIEW_LAYER;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
+ context_tabs_array[length] = BCONTEXT_SCENE;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
+ context_tabs_array[length] = BCONTEXT_WORLD;
+ length++;
+ }
+ if (length != 0) {
+ context_tabs_array[length] = -1;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
+ context_tabs_array[length] = BCONTEXT_OBJECT;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) {
+ context_tabs_array[length] = BCONTEXT_MODIFIER;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) {
+ context_tabs_array[length] = BCONTEXT_SHADERFX;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) {
+ context_tabs_array[length] = BCONTEXT_PARTICLE;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) {
+ context_tabs_array[length] = BCONTEXT_PHYSICS;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) {
+ context_tabs_array[length] = BCONTEXT_CONSTRAINT;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_DATA)) {
+ context_tabs_array[length] = BCONTEXT_DATA;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_BONE)) {
+ context_tabs_array[length] = BCONTEXT_BONE;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) {
+ context_tabs_array[length] = BCONTEXT_BONE_CONSTRAINT;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) {
+ context_tabs_array[length] = BCONTEXT_MATERIAL;
+ length++;
+ }
+ if (length != 0) {
+ context_tabs_array[length] = -1;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) {
+ context_tabs_array[length] = BCONTEXT_TEXTURE;
+ length++;
+ }
+
+ return length;
+}
+
static void buttons_main_region_layout_properties(const bContext *C,
SpaceProperties *sbuts,
ARegion *region)
@@ -422,6 +513,9 @@ static void buttons_area_listener(wmWindow *UNUSED(win),
buttons_area_redraw(area, BCONTEXT_CONSTRAINT);
buttons_area_redraw(area, BCONTEXT_BONE_CONSTRAINT);
break;
+ case ND_SHADERFX:
+ buttons_area_redraw(area, BCONTEXT_SHADERFX);
+ break;
case ND_PARTICLE:
if (wmn->action == NA_EDITED) {
buttons_area_redraw(area, BCONTEXT_PARTICLE);
@@ -435,13 +529,6 @@ static void buttons_area_listener(wmWindow *UNUSED(win),
/* Needed to refresh context path when changing active particle system index. */
buttons_area_redraw(area, BCONTEXT_PARTICLE);
break;
- case ND_SHADING:
- case ND_SHADING_DRAW:
- case ND_SHADING_LINKS:
- case ND_SHADING_PREVIEW:
- /* currently works by redraws... if preview is set, it (re)starts job */
- sbuts->preview = 1;
- break;
default:
/* Not all object RNA props have a ND_ notifier (yet) */
ED_area_tag_redraw(area);
@@ -497,6 +584,10 @@ static void buttons_area_listener(wmWindow *UNUSED(win),
if (wmn->data == ND_SPACE_PROPERTIES) {
ED_area_tag_redraw(area);
}
+ else if (wmn->data == ND_SPACE_CHANGED) {
+ ED_area_tag_redraw(area);
+ sbuts->preview = 1;
+ }
break;
case NC_ID:
if (wmn->action == NA_RENAME) {
@@ -537,6 +628,12 @@ static void buttons_area_listener(wmWindow *UNUSED(win),
sbuts->preview = 1;
}
break;
+ case NC_SCREEN:
+ if (wmn->data == ND_LAYOUTSET) {
+ ED_area_tag_redraw(area);
+ sbuts->preview = 1;
+ }
+ break;
#ifdef WITH_FREESTYLE
case NC_LINESTYLE:
ED_area_tag_redraw(area);
@@ -612,7 +709,7 @@ void ED_spacetype_buttons(void)
st->spaceid = SPACE_PROPERTIES;
strncpy(st->name, "Buttons", BKE_ST_MAXNAME);
- st->new = buttons_new;
+ st->create = buttons_create;
st->free = buttons_free;
st->init = buttons_init;
st->duplicate = buttons_duplicate;
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 3b1cc6fcab0..71f75d96cb1 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -259,6 +259,8 @@ typedef struct {
MovieTrackingTrack *track;
MovieTrackingMarker *marker;
+ /** current frame number */
+ int framenr;
/** position of marker in pixel coords */
float marker_pos[2];
/** position and dimensions of marker pattern in pixel coords */
@@ -286,7 +288,8 @@ static void marker_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
return;
}
- MovieTrackingMarker *marker = cb->marker;
+ int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(cb->clip, cb->framenr);
+ MovieTrackingMarker *marker = BKE_tracking_marker_ensure(cb->track, clip_framenr);
marker->flag = cb->marker_flag;
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL);
@@ -300,7 +303,9 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event)
BKE_movieclip_get_size(cb->clip, cb->user, &width, &height);
- MovieTrackingMarker *marker = cb->marker;
+ int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(cb->clip, cb->framenr);
+ MovieTrackingMarker *marker = BKE_tracking_marker_ensure(cb->track, clip_framenr);
+
if (event == B_MARKER_POS) {
marker->pos[0] = cb->marker_pos[0] / width;
marker->pos[1] = cb->marker_pos[1] / height;
@@ -456,6 +461,7 @@ void uiTemplateMarker(uiLayout *layout,
cb->track = track;
cb->marker = marker;
cb->marker_flag = marker->flag;
+ cb->framenr = user->framenr;
if (compact) {
block = uiLayoutGetBlock(layout);
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index fe7ae7096a0..1d510d2989c 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -88,7 +88,7 @@ static int generic_track_get_markersnr(MovieTrackingTrack *track,
if (track) {
return track->markersnr;
}
- else if (plane_track) {
+ if (plane_track) {
return plane_track->markersnr;
}
@@ -103,7 +103,7 @@ static int generic_track_get_marker_framenr(MovieTrackingTrack *track,
BLI_assert(marker_index < track->markersnr);
return track->markers[marker_index].framenr;
}
- else if (plane_track) {
+ if (plane_track) {
BLI_assert(marker_index < plane_track->markersnr);
return plane_track->markers[marker_index].framenr;
}
@@ -119,7 +119,7 @@ static bool generic_track_is_marker_enabled(MovieTrackingTrack *track,
BLI_assert(marker_index < track->markersnr);
return (track->markers[marker_index].flag & MARKER_DISABLED) == 0;
}
- else if (plane_track) {
+ if (plane_track) {
return true;
}
@@ -134,7 +134,7 @@ static bool generic_track_is_marker_keyframed(MovieTrackingTrack *track,
BLI_assert(marker_index < track->markersnr);
return (track->markers[marker_index].flag & MARKER_TRACKED) == 0;
}
- else if (plane_track) {
+ if (plane_track) {
BLI_assert(marker_index < plane_track->markersnr);
return (plane_track->markers[marker_index].flag & PLANE_MARKER_TRACKED) == 0;
}
@@ -228,7 +228,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *region, MovieClip *clip
ok = true;
break;
}
- else if (cameras[a].framenr > i) {
+ if (cameras[a].framenr > i) {
break;
}
@@ -322,7 +322,7 @@ static void draw_movieclip_buffer(const bContext *C,
float zoomy)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
- int filter = GL_LINEAR;
+ bool use_filter = true;
int x, y;
/* find window pixel coordinates of origin */
@@ -340,10 +340,10 @@ static void draw_movieclip_buffer(const bContext *C,
/* non-scaled proxy shouldn't use filtering */
if ((clip->flag & MCLIP_USE_PROXY) == 0 ||
ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100)) {
- filter = GL_NEAREST;
+ use_filter = false;
}
- ED_draw_imbuf_ctx(C, ibuf, x, y, filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y);
+ ED_draw_imbuf_ctx(C, ibuf, x, y, use_filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y);
if (ibuf->planes == 32) {
GPU_blend(false);
@@ -373,8 +373,7 @@ static void draw_stabilization_border(
/* Exclusive OR allows to get orig value when second operand is 0,
* and negative of orig value when second operand is 1. */
- glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(GL_XOR);
+ GPU_logic_op_xor_set(true);
GPU_matrix_push();
GPU_matrix_translate_2f(x, y);
@@ -399,7 +398,7 @@ static void draw_stabilization_border(
GPU_matrix_pop();
- glDisable(GL_COLOR_LOGIC_OP);
+ GPU_logic_op_xor_set(false);
}
}
@@ -790,15 +789,14 @@ static void draw_marker_areas(SpaceClip *sc,
immUniform1f("dash_width", 6.0f);
immUniform1f("dash_factor", 0.5f);
- glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(GL_XOR);
+ GPU_logic_op_xor_set(true);
immBegin(GPU_PRIM_LINES, 2);
immVertex2fv(shdr_pos, pos);
immVertex2fv(shdr_pos, marker_pos);
immEnd();
- glDisable(GL_COLOR_LOGIC_OP);
+ GPU_logic_op_xor_set(false);
}
}
@@ -1111,7 +1109,7 @@ static void draw_marker_texts(SpaceClip *sc,
pos[1] -= fontsize;
if (track->flag & TRACK_HAS_BUNDLE) {
- BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
+ BLI_snprintf(str, sizeof(str), "Average error: %.2f px", track->error);
BLF_position(fontid, pos[0], pos[1], 0.0f);
BLF_draw(fontid, str, sizeof(str));
pos[1] -= fontsize;
@@ -1203,7 +1201,6 @@ static void draw_plane_marker_image(Scene *scene,
}
if (display_buffer) {
- GLuint texid;
float frame_corners[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
float perspective_matrix[3][3];
float gl_matrix[4][4];
@@ -1220,23 +1217,17 @@ static void draw_plane_marker_image(Scene *scene,
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
- glGenTextures(1, (GLuint *)&texid);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texid);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA8,
- ibuf->x,
- ibuf->y,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- display_buffer);
+ GPUTexture *texture = GPU_texture_create_nD(ibuf->x,
+ ibuf->y,
+ 0,
+ 2,
+ display_buffer,
+ GPU_RGBA8,
+ GPU_DATA_UNSIGNED_BYTE,
+ 0,
+ false,
+ NULL);
+ GPU_texture_filter_mode(texture, false);
GPU_matrix_push();
GPU_matrix_mul(gl_matrix);
@@ -1246,10 +1237,10 @@ static void draw_plane_marker_image(Scene *scene,
uint texCoord = GPU_vertformat_attr_add(
imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
- immUniform1f("alpha", plane_track->image_opacity);
- immUniform1i("image", 0);
+ immBindTexture("image", texture);
+ immUniformColor4f(1.0f, 1.0f, 1.0f, plane_track->image_opacity);
immBegin(GPU_PRIM_TRI_FAN, 4);
@@ -1271,7 +1262,8 @@ static void draw_plane_marker_image(Scene *scene,
GPU_matrix_pop();
- glBindTexture(GL_TEXTURE_2D, 0);
+ GPU_texture_unbind(texture);
+ GPU_texture_free(texture);
if (transparent) {
GPU_blend(false);
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 5be4b2d5df0..83096b4eded 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -381,21 +381,20 @@ static bool selected_boundbox(const bContext *C, float min[2], float max[2])
if (sc->mode == SC_MODE_TRACKING) {
return selected_tracking_boundbox(sc, min, max);
}
- else {
- if (ED_mask_selected_minmax(C, min, max)) {
- MovieClip *clip = ED_space_clip_get_clip(sc);
- int width, height;
- ED_space_clip_get_size(sc, &width, &height);
- BKE_mask_coord_to_movieclip(clip, &sc->user, min, min);
- BKE_mask_coord_to_movieclip(clip, &sc->user, max, max);
- min[0] *= width;
- min[1] *= height;
- max[0] *= width;
- max[1] *= height;
- return true;
- }
- return false;
+
+ if (ED_mask_selected_minmax(C, min, max)) {
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ int width, height;
+ ED_space_clip_get_size(sc, &width, &height);
+ BKE_mask_coord_to_movieclip(clip, &sc->user, min, min);
+ BKE_mask_coord_to_movieclip(clip, &sc->user, max, max);
+ min[0] *= width;
+ min[1] *= height;
+ max[0] *= width;
+ max[1] *= height;
+ return true;
}
+ return false;
}
bool ED_clip_view_selection(const bContext *C, ARegion *region, bool fit)
@@ -726,7 +725,7 @@ typedef struct PrefetchQueue {
int initial_frame, current_frame, start_frame, end_frame;
short render_size, render_flag;
- /* If true prefecthing goes forward in time,
+ /* If true pre-fetching goes forward in time,
* otherwise it goes backwards in time (starting from current frame).
*/
bool forward;
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 27493bb5ccd..4848ec72f79 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -21,8 +21,7 @@
* \ingroup spclip
*/
-#ifndef __CLIP_INTERN_H__
-#define __CLIP_INTERN_H__
+#pragma once
struct ARegion;
struct MovieClip;
@@ -245,5 +244,3 @@ void CLIP_OT_select_box(struct wmOperatorType *ot);
void CLIP_OT_select_lasso(struct wmOperatorType *ot);
void CLIP_OT_select_circle(struct wmOperatorType *ot);
void CLIP_OT_select_grouped(struct wmOperatorType *ot);
-
-#endif /* __CLIP_INTERN_H__ */
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 22707b97afa..8532d8420f9 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -463,11 +463,10 @@ static int view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
- else {
- view_pan_init(C, op, event);
- return OPERATOR_RUNNING_MODAL;
- }
+ view_pan_init(C, op, event);
+
+ return OPERATOR_RUNNING_MODAL;
}
static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
@@ -633,11 +632,10 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
- else {
- view_zoom_init(C, op, event);
- return OPERATOR_RUNNING_MODAL;
- }
+ view_zoom_init(C, op, event);
+
+ return OPERATOR_RUNNING_MODAL;
}
static void view_zoom_apply(
@@ -1253,10 +1251,9 @@ static void do_movie_proxy(void *pjv,
return;
}
- else {
- sfra = 1;
- efra = clip->len;
- }
+
+ sfra = 1;
+ efra = clip->len;
if (build_undistort_count) {
int threads = BLI_system_thread_count();
@@ -1406,6 +1403,8 @@ static void do_sequence_proxy(void *pjv,
int build_count,
int *build_undistort_sizes,
int build_undistort_count,
+ /* Cannot be const, because it is assigned to a non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
short *stop,
short *do_update,
float *progress)
@@ -1516,7 +1515,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. */
+ /* Time-code might have changed, so do a full reload to deal with this. */
DEG_id_tag_update(&pj->clip->id, ID_RECALC_SOURCE);
}
else {
@@ -1646,27 +1645,26 @@ static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
}
- else {
- SpaceClip *sc = CTX_wm_space_clip(C);
- ARegion *region = CTX_wm_region(C);
- float pan_vec[3];
- const wmNDOFMotionData *ndof = event->customdata;
- const float speed = NDOF_PIXELS_PER_SECOND;
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ ARegion *region = CTX_wm_region(C);
+ float pan_vec[3];
+
+ const wmNDOFMotionData *ndof = event->customdata;
+ const float speed = NDOF_PIXELS_PER_SECOND;
- WM_event_ndof_pan_get(ndof, pan_vec, true);
+ WM_event_ndof_pan_get(ndof, pan_vec, true);
- mul_v2_fl(pan_vec, (speed * ndof->dt) / sc->zoom);
- pan_vec[2] *= -ndof->dt;
+ mul_v2_fl(pan_vec, (speed * ndof->dt) / sc->zoom);
+ pan_vec[2] *= -ndof->dt;
- sclip_zoom_set_factor(C, 1.0f + pan_vec[2], NULL, false);
- sc->xof += pan_vec[0];
- sc->yof += pan_vec[1];
+ sclip_zoom_set_factor(C, 1.0f + pan_vec[2], NULL, false);
+ sc->xof += pan_vec[0];
+ sc->yof += pan_vec[1];
- ED_region_tag_redraw(region);
+ ED_region_tag_redraw(region);
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
void CLIP_OT_view_ndof(wmOperatorType *ot)
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 54da00a132d..d27b80efd40 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -56,7 +56,6 @@
#include "IMB_imbuf.h"
#include "GPU_framebuffer.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "WM_api.h"
@@ -238,7 +237,7 @@ static void clip_area_sync_frame_from_scene(ScrArea *area, Scene *scene)
/* ******************** default callbacks for clip space ***************** */
-static SpaceLink *clip_new(const ScrArea *area, const Scene *scene)
+static SpaceLink *clip_create(const ScrArea *area, const Scene *scene)
{
ARegion *region;
SpaceClip *sc;
@@ -585,13 +584,13 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
return true;
}
- else if (CTX_data_equals(member, "edit_movieclip")) {
+ if (CTX_data_equals(member, "edit_movieclip")) {
if (sc->clip) {
CTX_data_id_pointer_set(result, &sc->clip->id);
}
return true;
}
- else if (CTX_data_equals(member, "edit_mask")) {
+ if (CTX_data_equals(member, "edit_mask")) {
if (sc->mask_info.mask) {
CTX_data_id_pointer_set(result, &sc->mask_info.mask->id);
}
@@ -685,7 +684,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (main_visible) {
if (region_main && (region_main->flag & RGN_FLAG_HIDDEN)) {
region_main->flag &= ~RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
@@ -697,7 +696,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_main && !(region_main->flag & RGN_FLAG_HIDDEN)) {
region_main->flag |= RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_main->handlers);
view_changed = true;
}
@@ -710,7 +709,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (properties_visible) {
if (region_properties && (region_properties->flag & RGN_FLAG_HIDDEN)) {
region_properties->flag &= ~RGN_FLAG_HIDDEN;
- region_properties->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_properties->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
if (region_properties && region_properties->alignment != RGN_ALIGN_RIGHT) {
@@ -721,7 +720,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_properties && !(region_properties->flag & RGN_FLAG_HIDDEN)) {
region_properties->flag |= RGN_FLAG_HIDDEN;
- region_properties->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_properties->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_properties->handlers);
view_changed = true;
}
@@ -734,7 +733,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (tools_visible) {
if (region_tools && (region_tools->flag & RGN_FLAG_HIDDEN)) {
region_tools->flag &= ~RGN_FLAG_HIDDEN;
- region_tools->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_tools->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
if (region_tools && region_tools->alignment != RGN_ALIGN_LEFT) {
@@ -745,7 +744,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_tools && !(region_tools->flag & RGN_FLAG_HIDDEN)) {
region_tools->flag |= RGN_FLAG_HIDDEN;
- region_tools->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_tools->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_tools->handlers);
view_changed = true;
}
@@ -758,7 +757,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (preview_visible) {
if (region_preview && (region_preview->flag & RGN_FLAG_HIDDEN)) {
region_preview->flag &= ~RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
region_preview->v2d.cur = region_preview->v2d.tot;
view_changed = true;
}
@@ -770,7 +769,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_preview && !(region_preview->flag & RGN_FLAG_HIDDEN)) {
region_preview->flag |= RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_preview->handlers);
view_changed = true;
}
@@ -783,7 +782,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (channels_visible) {
if (region_channels && (region_channels->flag & RGN_FLAG_HIDDEN)) {
region_channels->flag &= ~RGN_FLAG_HIDDEN;
- region_channels->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_channels->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
if (region_channels && region_channels->alignment != RGN_ALIGN_LEFT) {
@@ -794,7 +793,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_channels && !(region_channels->flag & RGN_FLAG_HIDDEN)) {
region_channels->flag |= RGN_FLAG_HIDDEN;
- region_channels->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_channels->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_channels->handlers);
view_changed = true;
}
@@ -805,7 +804,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
}
if (view_changed) {
- ED_area_initialize(wm, window, area);
+ ED_area_init(wm, window, area);
ED_area_tag_redraw(area);
}
@@ -1352,7 +1351,7 @@ void ED_spacetype_clip(void)
st->spaceid = SPACE_CLIP;
strncpy(st->name, "Clip", BKE_ST_MAXNAME);
- st->new = clip_new;
+ st->create = clip_create;
st->free = clip_free;
st->init = clip_init;
st->duplicate = clip_duplicate;
diff --git a/source/blender/editors/space_clip/tracking_ops_intern.h b/source/blender/editors/space_clip/tracking_ops_intern.h
index c29a485e234..5a9a84a235b 100644
--- a/source/blender/editors/space_clip/tracking_ops_intern.h
+++ b/source/blender/editors/space_clip/tracking_ops_intern.h
@@ -21,8 +21,7 @@
* \ingroup spclip
*/
-#ifndef __TRACKING_OPS_INTERN_H__
-#define __TRACKING_OPS_INTERN_H__
+#pragma once
struct ListBase;
struct MovieClip;
@@ -40,5 +39,3 @@ void clip_tracking_hide_cursor(struct bContext *C);
void ed_tracking_deselect_all_tracks(struct ListBase *tracks_base);
void ed_tracking_deselect_all_plane_tracks(struct ListBase *plane_tracks_base);
-
-#endif /* __TRACKING_OPS_INTERN_H__ */
diff --git a/source/blender/editors/space_clip/tracking_ops_orient.c b/source/blender/editors/space_clip/tracking_ops_orient.c
index 25e30c116c5..04c335cdf5e 100644
--- a/source/blender/editors/space_clip/tracking_ops_orient.c
+++ b/source/blender/editors/space_clip/tracking_ops_orient.c
@@ -110,9 +110,7 @@ static bool set_orientation_poll(bContext *C)
if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
return true;
}
- else {
- return OBACT(view_layer) != NULL;
- }
+ return OBACT(view_layer) != NULL;
}
}
return false;
diff --git a/source/blender/editors/space_clip/tracking_ops_plane.c b/source/blender/editors/space_clip/tracking_ops_plane.c
index 3c5646911a3..964b59babee 100644
--- a/source/blender/editors/space_clip/tracking_ops_plane.c
+++ b/source/blender/editors/space_clip/tracking_ops_plane.c
@@ -61,18 +61,17 @@ static int create_plane_track_tracks_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Need at least 4 selected point tracks to create a plane");
return OPERATOR_CANCELLED;
}
- else {
- BKE_tracking_tracks_deselect_all(tracks_base);
- plane_track->flag |= SELECT;
- clip->tracking.act_track = NULL;
- clip->tracking.act_plane_track = plane_track;
+ BKE_tracking_tracks_deselect_all(tracks_base);
- /* Compute homoraphies and apply them on marker's corner, so we've got
- * quite nice motion from the very beginning.
- */
- BKE_tracking_track_plane_from_existing_motion(plane_track, framenr);
- }
+ plane_track->flag |= SELECT;
+ clip->tracking.act_track = NULL;
+ clip->tracking.act_plane_track = plane_track;
+
+ /* Compute homoraphies and apply them on marker's corner, so we've got
+ * quite nice motion from the very beginning.
+ */
+ BKE_tracking_track_plane_from_existing_motion(plane_track, framenr);
DEG_id_tag_update(&clip->id, ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
diff --git a/source/blender/editors/space_clip/tracking_ops_solve.c b/source/blender/editors/space_clip/tracking_ops_solve.c
index c18207d7045..1ed965c30d2 100644
--- a/source/blender/editors/space_clip/tracking_ops_solve.c
+++ b/source/blender/editors/space_clip/tracking_ops_solve.c
@@ -144,7 +144,7 @@ static void solve_camera_freejob(void *scv)
else {
BKE_reportf(scj->reports,
RPT_INFO,
- "Average re-projection error: %.3f",
+ "Average re-projection error: %.2f px",
tracking->reconstruction.error);
}
diff --git a/source/blender/editors/space_clip/tracking_ops_track.c b/source/blender/editors/space_clip/tracking_ops_track.c
index 05623347366..afbca48bd45 100644
--- a/source/blender/editors/space_clip/tracking_ops_track.c
+++ b/source/blender/editors/space_clip/tracking_ops_track.c
@@ -214,7 +214,13 @@ static bool track_markers_initjob(bContext *C, TrackMarkersJob *tmj, bool backwa
return true;
}
-static void track_markers_startjob(void *tmv, short *stop, short *do_update, float *progress)
+static void track_markers_startjob(
+ void *tmv,
+ /* Cannot be const, this function implements wm_jobs_start_callback.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ short *stop,
+ short *do_update,
+ float *progress)
{
TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
int framenr = tmj->sfra;
@@ -358,14 +364,13 @@ static int track_markers(bContext *C, wmOperator *op, bool use_job)
return OPERATOR_RUNNING_MODAL;
}
- else {
- short stop = 0, do_update = 0;
- float progress = 0.0f;
- track_markers_startjob(tmj, &stop, &do_update, &progress);
- track_markers_endjob(tmj);
- track_markers_freejob(tmj);
- return OPERATOR_FINISHED;
- }
+
+ short stop = 0, do_update = 0;
+ float progress = 0.0f;
+ track_markers_startjob(tmj, &stop, &do_update, &progress);
+ track_markers_endjob(tmj);
+ track_markers_freejob(tmj);
+ return OPERATOR_FINISHED;
}
static int track_markers_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 81cc858c69f..b6f9ca9589f 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -731,7 +731,9 @@ void CLIP_OT_select_lasso(wmOperatorType *ot)
/********************** circle select operator *********************/
-static int point_inside_ellipse(float point[2], float offset[2], float ellipse[2])
+static int point_inside_ellipse(const float point[2],
+ const float offset[2],
+ const float ellipse[2])
{
/* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
float x, y;
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 805e9608fec..7e3dbcfefa4 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -139,7 +139,6 @@ static void console_cursor_wrap_offset(
*column += col;
}
- return;
}
static void console_textview_draw_cursor(TextViewContext *tvc, int cwidth, int columns)
diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h
index d051e351f3e..d4cb8363266 100644
--- a/source/blender/editors/space_console/console_intern.h
+++ b/source/blender/editors/space_console/console_intern.h
@@ -18,8 +18,7 @@
* \ingroup spconsole
*/
-#ifndef __CONSOLE_INTERN_H__
-#define __CONSOLE_INTERN_H__
+#pragma once
/* internal exports only */
@@ -75,5 +74,3 @@ enum {
DEL_NEXT_SEL,
DEL_PREV_SEL
};
-
-#endif /* __CONSOLE_INTERN_H__ */
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 981e056fa63..f0d4a45a3dd 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -287,12 +287,11 @@ static bool console_line_column_from_index(
*r_col = offset - pos;
return true;
}
- else {
- *r_cl = NULL;
- *r_cl_offset = -1;
- *r_col = -1;
- return false;
- }
+
+ *r_cl = NULL;
+ *r_cl_offset = -1;
+ *r_col = -1;
+ return false;
}
/* static funcs for text editing */
@@ -403,9 +402,8 @@ static int console_insert_exec(bContext *C, wmOperator *op)
if (len == 0) {
return OPERATOR_CANCELLED;
}
- else {
- console_select_offset(sc, len);
- }
+
+ console_select_offset(sc, len);
console_textview_update_rect(sc, region);
ED_area_tag_redraw(CTX_wm_area(C));
@@ -426,21 +424,20 @@ static int console_insert_invoke(bContext *C, wmOperator *op, const wmEvent *eve
if ((event->ctrl || event->oskey) && !event->utf8_buf[0]) {
return OPERATOR_PASS_THROUGH;
}
- 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);
- }
- else {
- /* in theory, ghost can set value to extended ascii here */
- len = BLI_str_utf8_from_unicode(event->ascii, str);
- }
- str[len] = '\0';
- RNA_string_set(op->ptr, "text", str);
+ 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);
+ }
+ else {
+ /* in theory, ghost can set value to extended ascii here */
+ len = BLI_str_utf8_from_unicode(event->ascii, str);
}
+ str[len] = '\0';
+ RNA_string_set(op->ptr, "text", str);
}
return console_insert_exec(C, op);
}
@@ -674,9 +671,8 @@ static int console_delete_exec(bContext *C, wmOperator *op)
if (!done) {
return OPERATOR_CANCELLED;
}
- else {
- console_select_offset(sc, -stride);
- }
+
+ console_select_offset(sc, -stride);
console_textview_update_rect(sc, region);
ED_area_tag_redraw(CTX_wm_area(C));
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 3c62aeb1759..3a0125356f7 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -46,7 +46,7 @@
/* ******************** default callbacks for console space ***************** */
-static SpaceLink *console_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *console_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceConsole *sconsole;
@@ -312,7 +312,7 @@ void ED_spacetype_console(void)
st->spaceid = SPACE_CONSOLE;
strncpy(st->name, "Console", BKE_ST_MAXNAME);
- st->new = console_new;
+ st->create = console_create;
st->free = console_free;
st->init = console_init;
st->duplicate = console_duplicate;
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 8d14664c0fa..083d41747b3 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -300,9 +300,8 @@ static void file_draw_preview(uiBlock *block,
(float)yco,
imb->x,
imb->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
imb->rect,
scale,
scale,
@@ -876,7 +875,9 @@ void file_draw_list(const bContext *C, ARegion *region)
sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL);
}
}
- else {
+
+ /* file_selflag might have been modified by branch above. */
+ if ((file_selflag & FILE_SEL_EDITING) == 0) {
const int txpos = (params->display == FILE_IMGDISPLAY) ? sx : sx + 1 + icon_ofs;
const int typos = (params->display == FILE_IMGDISPLAY) ?
sy - layout->tile_h + layout->textheight :
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index b7e8d35ffee..44131693628 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -21,8 +21,7 @@
* \ingroup spfile
*/
-#ifndef __FILE_INTERN_H__
-#define __FILE_INTERN_H__
+#pragma once
/* internal exports only */
@@ -116,5 +115,3 @@ void file_execute_region_panels_register(struct ARegionType *art);
/* file_utils.c */
void file_tile_boundbox(const ARegion *region, FileLayout *layout, const int file, rcti *r_bounds);
-
-#endif /* __FILE_INTERN_H__ */
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 6552dfc18f3..e9ffd4583d7 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -518,7 +518,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
rect.ymin = rect.ymax = event->mval[1];
if (!ED_fileselect_layout_is_inside_pt(sfile->layout, &region->v2d, rect.xmin, rect.ymin)) {
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
if (sfile && sfile->params) {
@@ -778,7 +778,7 @@ static bool file_walk_select_do(bContext *C,
}
/* if we don't extend, selecting '..' (index == 0) is allowed so
* using key selection to go to parent directory is possible */
- else if (active_new != 0) {
+ if (active_new != 0) {
/* select initial file */
active_new = active_old;
}
@@ -1697,6 +1697,19 @@ static int file_exec(bContext *C, wmOperator *exec_op)
return OPERATOR_FINISHED;
}
+static int file_exec_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion *region = CTX_wm_region(C);
+ SpaceFile *sfile = CTX_wm_space_file(C);
+
+ if (!ED_fileselect_layout_is_inside_pt(
+ sfile->layout, &region->v2d, event->mval[0], event->mval[1])) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
+
+ return file_exec(C, op);
+}
+
void FILE_OT_execute(struct wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -1707,6 +1720,7 @@ void FILE_OT_execute(struct wmOperatorType *ot)
ot->idname = "FILE_OT_execute";
/* api callbacks */
+ ot->invoke = file_exec_invoke;
ot->exec = file_exec;
ot->poll = file_operator_poll;
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index f60ef2b6aed..3ce80c11160 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -359,12 +359,24 @@ enum {
static ImBuf *gSpecialFileImages[SPECIAL_IMG_MAX];
-static void filelist_readjob_main(
- struct FileList *, const char *, short *, short *, float *, ThreadMutex *);
-static void filelist_readjob_lib(
- struct FileList *, const char *, short *, short *, float *, ThreadMutex *);
-static void filelist_readjob_dir(
- struct FileList *, const char *, short *, short *, float *, ThreadMutex *);
+static void filelist_readjob_main(FileList *filelist,
+ const char *main_name,
+ short *stop,
+ short *do_update,
+ float *progress,
+ ThreadMutex *lock);
+static void filelist_readjob_lib(FileList *filelist,
+ const char *main_name,
+ short *stop,
+ short *do_update,
+ float *progress,
+ ThreadMutex *lock);
+static void filelist_readjob_dir(FileList *filelist,
+ const char *main_name,
+ short *stop,
+ short *do_update,
+ float *progress,
+ ThreadMutex *lock);
/* helper, could probably go in BKE actually? */
static int groupname_to_code(const char *group);
@@ -625,11 +637,10 @@ static bool is_hidden_dot_filename(const char *filename, FileListInternEntry *fi
if (filename[0] == '.' && !ELEM(filename[1], '.', '\0')) {
return true; /* ignore .file */
}
- else {
- int len = strlen(filename);
- if ((len > 0) && (filename[len - 1] == '~')) {
- return true; /* ignore file~ */
- }
+
+ int len = strlen(filename);
+ if ((len > 0) && (filename[len - 1] == '~')) {
+ return true; /* ignore file~ */
}
/* filename might actually be a piece of path, in which case we have to check all its parts. */
@@ -999,43 +1010,41 @@ static int filelist_geticon_ex(FileDirEntry *file,
if (FILENAME_IS_PARENT(file->relpath)) {
return is_main ? ICON_FILE_PARENT : ICON_NONE;
}
- else if (typeflag & FILE_TYPE_APPLICATIONBUNDLE) {
+ if (typeflag & FILE_TYPE_APPLICATIONBUNDLE) {
return ICON_UGLYPACKAGE;
}
- else if (typeflag & FILE_TYPE_BLENDER) {
+ if (typeflag & FILE_TYPE_BLENDER) {
return ICON_FILE_BLEND;
}
- else if (is_main) {
+ if (is_main) {
/* Do not return icon for folders if icons are not 'main' draw type
* (e.g. when used over previews). */
return (file->attributes & FILE_ATTR_ANY_LINK) ? ICON_FOLDER_REDIRECT : ICON_FILE_FOLDER;
}
- else {
- /* If this path is in System list or path cache then use that icon. */
- struct FSMenu *fsmenu = ED_fsmenu_get();
- FSMenuCategory categories[] = {
- FS_CATEGORY_SYSTEM,
- FS_CATEGORY_SYSTEM_BOOKMARKS,
- FS_CATEGORY_OTHER,
- };
-
- for (int i = 0; i < ARRAY_SIZE(categories); i++) {
- FSMenuEntry *tfsm = ED_fsmenu_get_category(fsmenu, categories[i]);
- char fullpath[FILE_MAX_LIBEXTRA];
- char *target = fullpath;
- if (file->redirection_path) {
- target = file->redirection_path;
- }
- else {
- BLI_join_dirfile(fullpath, sizeof(fullpath), root, file->relpath);
- BLI_path_slash_ensure(fullpath);
- }
- for (; tfsm; tfsm = tfsm->next) {
- if (STREQ(tfsm->path, target)) {
- /* Never want a little folder inside a large one. */
- return (tfsm->icon == ICON_FILE_FOLDER) ? ICON_NONE : tfsm->icon;
- }
+ /* If this path is in System list or path cache then use that icon. */
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+ FSMenuCategory categories[] = {
+ FS_CATEGORY_SYSTEM,
+ FS_CATEGORY_SYSTEM_BOOKMARKS,
+ FS_CATEGORY_OTHER,
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(categories); i++) {
+ FSMenuEntry *tfsm = ED_fsmenu_get_category(fsmenu, categories[i]);
+ char fullpath[FILE_MAX_LIBEXTRA];
+ char *target = fullpath;
+ if (file->redirection_path) {
+ target = file->redirection_path;
+ }
+ else {
+ BLI_join_dirfile(fullpath, sizeof(fullpath), root, file->relpath);
+ BLI_path_slash_ensure(fullpath);
+ }
+ for (; tfsm; tfsm = tfsm->next) {
+ if (STREQ(tfsm->path, target)) {
+ /* Never want a little folder inside a large one. */
+ return (tfsm->icon == ICON_FILE_FOLDER) ? ICON_NONE : tfsm->icon;
}
}
}
@@ -1043,10 +1052,10 @@ static int filelist_geticon_ex(FileDirEntry *file,
if (file->attributes & FILE_ATTR_OFFLINE) {
return ICON_ERROR;
}
- else if (file->attributes & FILE_ATTR_TEMPORARY) {
+ if (file->attributes & FILE_ATTR_TEMPORARY) {
return ICON_FILE_CACHE;
}
- else if (file->attributes & FILE_ATTR_SYSTEM) {
+ if (file->attributes & FILE_ATTR_SYSTEM) {
return ICON_SYSTEM;
}
}
@@ -1054,49 +1063,49 @@ static int filelist_geticon_ex(FileDirEntry *file,
if (typeflag & FILE_TYPE_BLENDER) {
return ICON_FILE_BLEND;
}
- else if (typeflag & FILE_TYPE_BLENDER_BACKUP) {
+ if (typeflag & FILE_TYPE_BLENDER_BACKUP) {
return ICON_FILE_BACKUP;
}
- else if (typeflag & FILE_TYPE_IMAGE) {
+ if (typeflag & FILE_TYPE_IMAGE) {
return ICON_FILE_IMAGE;
}
- else if (typeflag & FILE_TYPE_MOVIE) {
+ if (typeflag & FILE_TYPE_MOVIE) {
return ICON_FILE_MOVIE;
}
- else if (typeflag & FILE_TYPE_PYSCRIPT) {
+ if (typeflag & FILE_TYPE_PYSCRIPT) {
return ICON_FILE_SCRIPT;
}
- else if (typeflag & FILE_TYPE_SOUND) {
+ if (typeflag & FILE_TYPE_SOUND) {
return ICON_FILE_SOUND;
}
- else if (typeflag & FILE_TYPE_FTFONT) {
+ if (typeflag & FILE_TYPE_FTFONT) {
return ICON_FILE_FONT;
}
- else if (typeflag & FILE_TYPE_BTX) {
+ if (typeflag & FILE_TYPE_BTX) {
return ICON_FILE_BLANK;
}
- else if (typeflag & FILE_TYPE_COLLADA) {
+ if (typeflag & FILE_TYPE_COLLADA) {
return ICON_FILE_3D;
}
- else if (typeflag & FILE_TYPE_ALEMBIC) {
+ if (typeflag & FILE_TYPE_ALEMBIC) {
return ICON_FILE_3D;
}
- else if (typeflag & FILE_TYPE_USD) {
+ if (typeflag & FILE_TYPE_USD) {
return ICON_FILE_3D;
}
- else if (typeflag & FILE_TYPE_VOLUME) {
+ if (typeflag & FILE_TYPE_VOLUME) {
return ICON_FILE_VOLUME;
}
- else if (typeflag & FILE_TYPE_OBJECT_IO) {
+ if (typeflag & FILE_TYPE_OBJECT_IO) {
return ICON_FILE_3D;
}
- else if (typeflag & FILE_TYPE_TEXT) {
+ if (typeflag & FILE_TYPE_TEXT) {
return ICON_FILE_TEXT;
}
- else if (typeflag & FILE_TYPE_ARCHIVE) {
+ if (typeflag & FILE_TYPE_ARCHIVE) {
return ICON_FILE_ARCHIVE;
}
- else if (typeflag & FILE_TYPE_BLENDERLIB) {
+ if (typeflag & FILE_TYPE_BLENDERLIB) {
const int ret = UI_idcode_icon_get(file->blentype);
if (ret != ICON_NONE) {
return ret;
@@ -1133,9 +1142,7 @@ static bool filelist_checkdir_dir(struct FileList *UNUSED(filelist),
parent_dir_until_exists_or_default_root(r_dir);
return true;
}
- else {
- return BLI_is_dir(r_dir);
- }
+ return BLI_is_dir(r_dir);
}
static bool filelist_checkdir_lib(struct FileList *UNUSED(filelist),
@@ -2106,7 +2113,7 @@ void filelist_cache_previews_set(FileList *filelist, const bool use_previews)
return;
}
/* Do not start preview work while listing, gives nasty flickering! */
- else if (use_previews && (filelist->flags & FL_IS_READY)) {
+ if (use_previews && (filelist->flags & FL_IS_READY)) {
cache->flags |= FLC_PREVIEWS_ACTIVE;
BLI_assert((cache->previews_pool == NULL) && (cache->previews_done == NULL));
@@ -2215,67 +2222,65 @@ int ED_path_extension_type(const char *path)
if (BLO_has_bfile_extension(path)) {
return FILE_TYPE_BLENDER;
}
- else if (file_is_blend_backup(path)) {
+ if (file_is_blend_backup(path)) {
return FILE_TYPE_BLENDER_BACKUP;
}
- else if (BLI_path_extension_check(path, ".app")) {
+ if (BLI_path_extension_check(path, ".app")) {
return FILE_TYPE_APPLICATIONBUNDLE;
}
- else if (BLI_path_extension_check(path, ".py")) {
+ if (BLI_path_extension_check(path, ".py")) {
return FILE_TYPE_PYSCRIPT;
}
- else if (BLI_path_extension_check_n(path,
- ".txt",
- ".glsl",
- ".osl",
- ".data",
- ".pov",
- ".ini",
- ".mcr",
- ".inc",
- ".fountain",
- NULL)) {
+ if (BLI_path_extension_check_n(path,
+ ".txt",
+ ".glsl",
+ ".osl",
+ ".data",
+ ".pov",
+ ".ini",
+ ".mcr",
+ ".inc",
+ ".fountain",
+ NULL)) {
return FILE_TYPE_TEXT;
}
- else if (BLI_path_extension_check_n(path, ".ttf", ".ttc", ".pfb", ".otf", ".otc", NULL)) {
+ if (BLI_path_extension_check_n(path, ".ttf", ".ttc", ".pfb", ".otf", ".otc", NULL)) {
return FILE_TYPE_FTFONT;
}
- else if (BLI_path_extension_check(path, ".btx")) {
+ if (BLI_path_extension_check(path, ".btx")) {
return FILE_TYPE_BTX;
}
- else if (BLI_path_extension_check(path, ".dae")) {
+ if (BLI_path_extension_check(path, ".dae")) {
return FILE_TYPE_COLLADA;
}
- else if (BLI_path_extension_check(path, ".abc")) {
+ if (BLI_path_extension_check(path, ".abc")) {
return FILE_TYPE_ALEMBIC;
}
- else if (BLI_path_extension_check_n(path, ".usd", ".usda", ".usdc", NULL)) {
+ if (BLI_path_extension_check_n(path, ".usd", ".usda", ".usdc", NULL)) {
return FILE_TYPE_USD;
}
- else if (BLI_path_extension_check(path, ".vdb")) {
+ if (BLI_path_extension_check(path, ".vdb")) {
return FILE_TYPE_VOLUME;
}
- else if (BLI_path_extension_check(path, ".zip")) {
+ if (BLI_path_extension_check(path, ".zip")) {
return FILE_TYPE_ARCHIVE;
}
- else if (BLI_path_extension_check_n(path, ".obj", ".3ds", ".fbx", ".glb", ".gltf", NULL)) {
+ if (BLI_path_extension_check_n(path, ".obj", ".3ds", ".fbx", ".glb", ".gltf", NULL)) {
return FILE_TYPE_OBJECT_IO;
}
- else if (BLI_path_extension_check_array(path, imb_ext_image)) {
+ if (BLI_path_extension_check_array(path, imb_ext_image)) {
return FILE_TYPE_IMAGE;
}
- else if (BLI_path_extension_check(path, ".ogg")) {
+ if (BLI_path_extension_check(path, ".ogg")) {
if (IMB_isanim(path)) {
return FILE_TYPE_MOVIE;
}
- else {
- return FILE_TYPE_SOUND;
- }
+ return FILE_TYPE_SOUND;
}
- else if (BLI_path_extension_check_array(path, imb_ext_movie)) {
+ if (BLI_path_extension_check_array(path, imb_ext_movie)) {
return FILE_TYPE_MOVIE;
}
- else if (BLI_path_extension_check_array(path, imb_ext_audio)) {
+ if (BLI_path_extension_check_array(path, imb_ext_audio)) {
return FILE_TYPE_SOUND;
}
return 0;
@@ -2655,9 +2660,9 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
if (filelist->dir[0] == 0) {
/* make directories */
# ifdef WITH_FREESTYLE
- filelist->filelist.nbr_entries = 27;
+ filelist->filelist.nbr_entries = 27;
# else
- filelist->filelist.nbr_entries = 26;
+ filelist->filelist.nbr_entries = 26;
# endif
filelist_resize(filelist, filelist->filelist.nbr_entries);
@@ -2688,11 +2693,11 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
filelist->filelist.entries[20].entry->relpath = BLI_strdup("Action");
filelist->filelist.entries[21].entry->relpath = BLI_strdup("NodeTree");
filelist->filelist.entries[22].entry->relpath = BLI_strdup("Speaker");
- filelist->filelist.entries[23].entry->relpath = BLI_strdup("Hair");
- filelist->filelist.entries[24].entry->relpath = BLI_strdup("Point Cloud");
- filelist->filelist.entries[25].entry->relpath = BLI_strdup("Volume");
+ filelist->filelist.entries[23].entry->relpath = BLI_strdup("Hair");
+ filelist->filelist.entries[24].entry->relpath = BLI_strdup("Point Cloud");
+ filelist->filelist.entries[25].entry->relpath = BLI_strdup("Volume");
# ifdef WITH_FREESTYLE
- filelist->filelist.entries[26].entry->relpath = BLI_strdup("FreestyleLineStyle");
+ filelist->filelist.entries[26].entry->relpath = BLI_strdup("FreestyleLineStyle");
# endif
}
else {
@@ -2804,7 +2809,7 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
static void filelist_readjob_do(const bool do_lib,
FileList *filelist,
const char *main_name,
- short *stop,
+ const short *stop,
short *do_update,
float *progress,
ThreadMutex *lock)
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index e90a8659417..53937e7a743 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -21,8 +21,7 @@
* \ingroup spfile
*/
-#ifndef __FILELIST_H__
-#define __FILELIST_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -139,5 +138,3 @@ bool filelist_cache_previews_running(struct FileList *filelist);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 3b62941af83..88c8c6b2939 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -374,7 +374,7 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile)
* pass its size here so we can store that in the preferences. Otherwise NULL.
*/
void ED_fileselect_params_to_userdef(SpaceFile *sfile,
- int temp_win_size[2],
+ const int temp_win_size[2],
const bool is_maximized)
{
UserDef_FileSpaceData *sfile_udata_new = &U.file_space_data;
@@ -438,13 +438,12 @@ int ED_fileselect_layout_numfiles(FileLayout *layout, ARegion *region)
numfiles = (int)((float)(x_view + x_over) / (float)(x_item));
return numfiles * layout->rows;
}
- else {
- const int y_item = layout->tile_h + (2 * layout->tile_border_y);
- const int y_view = (int)(BLI_rctf_size_y(&region->v2d.cur)) - layout->offset_top;
- const int y_over = y_item - (y_view % y_item);
- numfiles = (int)((float)(y_view + y_over) / (float)(y_item));
- return numfiles * layout->flow_columns;
- }
+
+ const int y_item = layout->tile_h + (2 * layout->tile_border_y);
+ const int y_view = (int)(BLI_rctf_size_y(&region->v2d.cur)) - layout->offset_top;
+ const int y_over = y_item - (y_view % y_item);
+ numfiles = (int)((float)(y_view + y_over) / (float)(y_item));
+ return numfiles * layout->flow_columns;
}
static bool is_inside(int x, int y, int cols, int rows)
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index b03df01a02b..b1c94c2668f 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -307,14 +307,13 @@ char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry)
if (fsentry->name[0]) {
return fsentry->name;
}
- else {
- /* Here we abuse fsm_iter->name, keeping first char NULL. */
- char *name = fsentry->name + 1;
- size_t name_size = sizeof(fsentry->name) - 1;
- fsmenu_entry_generate_name(fsentry, name, name_size);
- return name;
- }
+ /* Here we abuse fsm_iter->name, keeping first char NULL. */
+ char *name = fsentry->name + 1;
+ size_t name_size = sizeof(fsentry->name) - 1;
+
+ fsmenu_entry_generate_name(fsentry, name, name_size);
+ return name;
}
void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name)
@@ -411,7 +410,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu,
}
return;
}
- else if ((flag & FS_INSERT_SORTED) && cmp_ret < 0) {
+ if ((flag & FS_INSERT_SORTED) && cmp_ret < 0) {
break;
}
}
@@ -755,8 +754,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
fsmenu, FS_CATEGORY_OTHER, &FOLDERID_SkyDrive, NULL, ICON_URL, FS_INSERT_LAST);
}
}
-#else
-# ifdef __APPLE__
+#elif defined(__APPLE__)
{
/* We store some known macOS system paths and corresponding icons
* and names in the FS_CATEGORY_OTHER (not displayed directly) category. */
@@ -775,9 +773,9 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
const char *home = BLI_getenv("HOME");
-# define FS_MACOS_PATH(path, name, icon) \
- BLI_snprintf(line, sizeof(line), path, home); \
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_OTHER, line, name, icon, FS_INSERT_LAST);
+# define FS_MACOS_PATH(path, name, icon) \
+ BLI_snprintf(line, sizeof(line), path, home); \
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_OTHER, line, name, icon, FS_INSERT_LAST);
FS_MACOS_PATH("%s/", NULL, ICON_HOME)
FS_MACOS_PATH("%s/Desktop/", IFACE_("Desktop"), ICON_DESKTOP)
@@ -788,7 +786,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
FS_MACOS_PATH("%s/Pictures/", IFACE_("Pictures"), ICON_FILE_IMAGE)
FS_MACOS_PATH("%s/Library/Fonts/", IFACE_("Fonts"), ICON_FILE_FONT)
-# undef FS_MACOS_PATH
+# undef FS_MACOS_PATH
/* Get mounted volumes better method OSX 10.6 and higher, see:
* https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html
@@ -850,8 +848,8 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
/* kLSSharedFileListFavoriteItems is deprecated, but available till macOS 10.15.
* Will have to find a new method to sync the Finder Favorites with File Browser. */
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/* Finally get user favorite places */
if (read_bookmarks) {
UInt32 seed;
@@ -895,9 +893,9 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
CFRelease(pathesArray);
CFRelease(list);
}
-# pragma GCC diagnostic pop
+# pragma GCC diagnostic pop
}
-# else
+#else
/* unix */
{
const char *home = BLI_getenv("HOME");
@@ -933,14 +931,14 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
{
int found = 0;
-# ifdef __linux__
+# ifdef __linux__
/* loop over mount points */
struct mntent *mnt;
FILE *fp;
fp = setmntent(MOUNTED, "r");
if (fp == NULL) {
- fprintf(stderr, "could not get a list of mounted filesystems\n");
+ fprintf(stderr, "could not get a list of mounted file-systems\n");
}
else {
while ((mnt = getmntent(fp))) {
@@ -948,10 +946,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
/* Hide share not usable to the user. */
continue;
}
- else if (!STRPREFIX(mnt->mnt_fsname, "/dev")) {
+ if (!STRPREFIX(mnt->mnt_fsname, "/dev")) {
continue;
}
- else if (STRPREFIX(mnt->mnt_fsname, "/dev/loop")) {
+ if (STRPREFIX(mnt->mnt_fsname, "/dev/loop")) {
/* The dev/loop* entries are SNAPS used by desktop environment
* (Gnome) no need for them to show up in the list. */
continue;
@@ -995,7 +993,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
}
BLI_filelist_free(dir, dir_len);
}
-# endif
+# endif
/* fallback */
if (!found) {
@@ -1004,7 +1002,6 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
}
}
}
-# endif
#endif
#if defined(WIN32) || defined(__APPLE__)
@@ -1132,10 +1129,13 @@ int fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory categor
* before being defined as unreachable by the OS, we need to validate the bookmarks in an async
* job...
*/
-static void fsmenu_bookmark_validate_job_startjob(void *fsmenuv,
- short *stop,
- short *do_update,
- float *UNUSED(progress))
+static void fsmenu_bookmark_validate_job_startjob(
+ void *fsmenuv,
+ /* Cannot be const, this function implements wm_jobs_start_callback.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ short *stop,
+ short *do_update,
+ float *UNUSED(progress))
{
FSMenu *fsmenu = fsmenuv;
diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h
index 17cfdf1c7f0..c4af27a25aa 100644
--- a/source/blender/editors/space_file/fsmenu.h
+++ b/source/blender/editors/space_file/fsmenu.h
@@ -21,8 +21,7 @@
* \ingroup spfile
*/
-#ifndef __FSMENU_H__
-#define __FSMENU_H__
+#pragma once
/* XXX could become UserPref */
#define FSMENU_RECENT_MAX 10
@@ -76,5 +75,3 @@ void fsmenu_refresh_bookmarks_status(struct wmWindowManager *wm, struct FSMenu *
int fsmenu_get_active_indices(struct FSMenu *fsmenu,
enum FSMenuCategory category,
const char *dir);
-
-#endif
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 56f3fd08bae..f520f91b89b 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -91,7 +91,7 @@ static ARegion *file_tool_props_region_ensure(ScrArea *area, ARegion *region_pre
/* ******************** default callbacks for file space ***************** */
-static SpaceLink *file_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *file_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceFile *sfile;
@@ -235,7 +235,7 @@ static void file_ensure_valid_region_state(bContext *C,
ARegion *region_ui = BKE_area_find_region_type(area, RGN_TYPE_UI);
ARegion *region_props = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS);
ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE);
- bool needs_init = false; /* To avoid multiple ED_area_initialize() calls. */
+ bool needs_init = false; /* To avoid multiple ED_area_init() calls. */
/* If there's an file-operation, ensure we have the option and execute region */
if (sfile->op && (region_props == NULL)) {
@@ -261,7 +261,7 @@ static void file_ensure_valid_region_state(bContext *C,
}
if (needs_init) {
- ED_area_initialize(wm, win, area);
+ ED_area_init(wm, win, area);
}
}
@@ -458,7 +458,7 @@ static void file_main_region_draw(const bContext *C, ARegion *region)
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
- GPU_clear_color(col[0], col[1], col[2], 0.0);
+ GPU_clear_color(col[0], col[1], col[2], 1.0f);
GPU_clear(GPU_COLOR_BIT);
/* Allow dynamically sliders to be set, saves notifiers etc. */
@@ -693,7 +693,7 @@ void ED_spacetype_file(void)
st->spaceid = SPACE_FILE;
strncpy(st->name, "File", BKE_ST_MAXNAME);
- st->new = file_new;
+ st->create = file_create;
st->free = file_free;
st->init = file_init;
st->exit = file_exit;
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 179d73a38ba..0158e12c79c 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -1420,7 +1420,7 @@ void graph_buttons_register(ARegionType *art)
pt->poll = graph_panel_drivers_poll;
BLI_addtail(&art->paneltypes, pt);
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers pover");
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers popover");
strcpy(pt->idname, "GRAPH_PT_drivers_popover");
strcpy(pt->label, N_("Add/Edit Driver"));
strcpy(pt->category, "Drivers");
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index f2071d292ca..5ae175f525f 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -327,9 +327,7 @@ static bool draw_fcurve_handles_check(SpaceGraph *sipo, FCurve *fcu)
(fcu->totvert <= 1)) {
return false;
}
- else {
- return true;
- }
+ return true;
}
/* draw lines for F-Curve handles only (this is only done in EditMode)
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 03151da8d4d..90fe95c6818 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -233,9 +233,8 @@ static int graphkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
if (ac.scene == NULL) {
return OPERATOR_CANCELLED;
}
- else {
- scene = ac.scene;
- }
+
+ scene = ac.scene;
/* set the range directly */
get_graph_keyframe_extents(&ac, &min, &max, NULL, NULL, false, false);
@@ -682,9 +681,10 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
}
}
else {
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ ac->depsgraph, (float)CFRA);
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
- float cfra = (float)CFRA;
/* Read value from property the F-Curve represents, or from the curve only?
*
@@ -706,7 +706,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path,
fcu->array_index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
&nla_cache,
flag);
@@ -715,6 +715,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
/* adjust current frame for NLA-mapping */
+ float cfra = (float)CFRA;
if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS)) {
cfra = sipo->cursorTime;
}
@@ -1486,7 +1487,7 @@ static int graphkeys_decimate_invoke(bContext *C, wmOperator *op, const wmEvent
dgo->area = CTX_wm_area(C);
dgo->region = CTX_wm_region(C);
- /* initialise percentage so that it will have the correct value before the first mouse move. */
+ /* Initialize percentage so that it will have the correct value before the first mouse move. */
decimate_mouse_update_percentage(dgo, op, event);
decimate_draw_status_header(op, dgo);
@@ -1631,11 +1632,10 @@ static int graphkeys_decimate_modal(bContext *C, wmOperator *op, const wmEvent *
graphkeys_decimate_modal_update(C, op);
break;
}
- else {
- /* unhandled event - maybe it was some view manip? */
- /* allow to pass through */
- return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
- }
+
+ /* unhandled event - maybe it was some view manip? */
+ /* allow to pass through */
+ return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
}
}
@@ -1694,7 +1694,7 @@ static bool graphkeys_decimate_poll_property(const bContext *UNUSED(C),
if (STREQ(prop_id, "remove_ratio") && mode != DECIM_RATIO) {
return false;
}
- else if (STREQ(prop_id, "remove_error_margin") && mode != DECIM_ERROR) {
+ if (STREQ(prop_id, "remove_error_margin") && mode != DECIM_ERROR) {
return false;
}
}
@@ -2577,7 +2577,7 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
if (strstr(fcu->rna_path, "rotation_euler") == NULL) {
continue;
}
- else if (ELEM(fcu->array_index, 0, 1, 2) == 0) {
+ if (ELEM(fcu->array_index, 0, 1, 2) == 0) {
BKE_reportf(op->reports,
RPT_WARNING,
"Euler Rotation F-Curve has invalid index (ID='%s', Path='%s', Index=%d)",
@@ -2689,23 +2689,22 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
"and that F-Curves for these are in consecutive XYZ order and selected");
return OPERATOR_CANCELLED;
}
- else {
- if (failed) {
- BKE_report(
- op->reports,
- RPT_ERROR,
- "Some Euler Rotations could not be corrected due to missing/unselected/out-of-order "
- "F-Curves, "
- "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;
+ if (failed) {
+ BKE_report(
+ op->reports,
+ RPT_ERROR,
+ "Some Euler Rotations could not be corrected due to missing/unselected/out-of-order "
+ "F-Curves, "
+ "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)
@@ -3347,9 +3346,7 @@ static int graph_fmodifier_copy_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied");
return OPERATOR_CANCELLED;
}
- else {
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_fmodifier_copy(wmOperatorType *ot)
@@ -3434,10 +3431,9 @@ static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports, RPT_ERROR, "No F-Modifiers to paste");
- return OPERATOR_CANCELLED;
- }
+
+ BKE_report(op->reports, RPT_ERROR, "No F-Modifiers to paste");
+ return OPERATOR_CANCELLED;
}
void GRAPH_OT_fmodifier_paste(wmOperatorType *ot)
@@ -3487,9 +3483,7 @@ static int graph_driver_vars_copy_exec(bContext *C, wmOperator *op)
if (ok) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void GRAPH_OT_driver_variables_copy(wmOperatorType *ot)
@@ -3533,9 +3527,7 @@ static int graph_driver_vars_paste_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void GRAPH_OT_driver_variables_paste(wmOperatorType *ot)
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 3ec36e43278..d00e911e3fc 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -21,8 +21,7 @@
* \ingroup spgraph
*/
-#ifndef __GRAPH_INTERN_H__
-#define __GRAPH_INTERN_H__
+#pragma once
struct ARegion;
struct ARegionType;
@@ -177,5 +176,3 @@ bool graphop_selected_fcurve_poll(struct bContext *C);
/* graph_ops.c */
void graphedit_keymap(struct wmKeyConfig *keyconf);
void graphedit_operatortypes(void);
-
-#endif /* __GRAPH_INTERN_H__ */
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index ae435b5624a..160b731629c 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -298,11 +298,10 @@ static tNearestVertInfo *get_best_nearest_fcurve_vert(ListBase *matches)
BLI_remlink(matches, nvi);
return nvi;
}
- else {
- /* if vert is selected, we've got what we want... */
- if (nvi->sel) {
- found = 1;
- }
+
+ /* if vert is selected, we've got what we want... */
+ if (nvi->sel) {
+ found = 1;
}
}
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 052e089942c..a4f76384cc6 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -64,7 +64,7 @@
/* ******************** default callbacks for ipo space ***************** */
-static SpaceLink *graph_new(const ScrArea *UNUSED(area), const Scene *scene)
+static SpaceLink *graph_create(const ScrArea *UNUSED(area), const Scene *scene)
{
ARegion *region;
SpaceGraph *sipo;
@@ -204,7 +204,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
- GPU_clear_color(col[0], col[1], col[2], 0.0);
+ GPU_clear_color(col[0], col[1], col[2], 1.0f);
GPU_clear(GPU_COLOR_BIT);
UI_view2d_view_ortho(v2d);
@@ -362,7 +362,7 @@ static void graph_channel_region_draw(const bContext *C, ARegion *region)
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
- GPU_clear_color(col[0], col[1], col[2], 0.0);
+ GPU_clear_color(col[0], col[1], col[2], 1.0f);
GPU_clear(GPU_COLOR_BIT);
UI_view2d_view_ortho(v2d);
@@ -838,7 +838,7 @@ void ED_spacetype_ipo(void)
st->spaceid = SPACE_GRAPH;
strncpy(st->name, "Graph", BKE_ST_MAXNAME);
- st->new = graph_new;
+ st->create = graph_create;
st->free = graph_free;
st->init = graph_init;
st->duplicate = graph_duplicate;
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index 12de74c6ae7..24ec7a89397 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../../blentranslation
../../bmesh
../../depsgraph
+ ../../draw
../../gpu
../../imbuf
../../makesdna
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 6f3ef44fe94..1f8dd7cfe44 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -139,9 +139,7 @@ static bool ui_imageuser_slot_menu_step(bContext *C, int direction, void *image_
WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
return true;
}
- else {
- return true;
- }
+ return true;
}
static const char *ui_imageuser_layer_fake_name(RenderResult *rr)
@@ -150,12 +148,10 @@ static const char *ui_imageuser_layer_fake_name(RenderResult *rr)
if (rv->rectf) {
return IFACE_("Composite");
}
- else if (rv->rect32) {
+ if (rv->rect32) {
return IFACE_("Sequence");
}
- else {
- return NULL;
- }
+ return NULL;
}
/* workaround for passing many args */
@@ -576,8 +572,12 @@ static void image_multiview_cb(bContext *C, void *rnd_pt, void *UNUSED(arg_v))
WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
}
-static void uiblock_layer_pass_buttons(
- uiLayout *layout, Image *image, RenderResult *rr, ImageUser *iuser, int w, short *render_slot)
+static void uiblock_layer_pass_buttons(uiLayout *layout,
+ Image *image,
+ RenderResult *rr,
+ ImageUser *iuser,
+ int w,
+ const short *render_slot)
{
struct ImageUI_Data rnd_pt_local, *rnd_pt = NULL;
uiBlock *block = uiLayoutGetBlock(layout);
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 9040ca5e79c..1038011e480 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -150,8 +150,8 @@ void ED_image_draw_info(Scene *scene,
const uchar cp[4],
const float fp[4],
const float linearcol[4],
- int *zp,
- float *zpf)
+ const int *zp,
+ const float *zpf)
{
rcti color_rect;
char str[256];
@@ -463,25 +463,24 @@ void ED_image_draw_info(Scene *scene,
/* image drawing */
static void sima_draw_zbuf_pixels(
- float x1, float y1, int rectx, int recty, int *rect, float zoomx, float zoomy)
+ float x1, float y1, int rectx, int recty, const int *rect, float zoomx, float zoomy)
{
float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
/* Slowwww */
- int *recti = MEM_mallocN(rectx * recty * sizeof(int), "temp");
+ float *rectf = MEM_mallocN(rectx * recty * sizeof(float), "temp");
for (int a = rectx * recty - 1; a >= 0; a--) {
/* zbuffer values are signed, so we need to shift color range */
- recti[a] = rect[a] * 0.5f + 0.5f;
+ rectf[a] = rect[a] * 0.5f + 0.5f;
}
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(
- &state, x1, y1, rectx, recty, GL_RED, GL_INT, GL_NEAREST, recti, zoomx, zoomy, NULL);
+ immDrawPixelsTex(&state, x1, y1, rectx, recty, GPU_R16F, false, rectf, zoomx, zoomy, NULL);
- MEM_freeN(recti);
+ MEM_freeN(rectf);
}
static void sima_draw_zbuffloat_pixels(Scene *scene,
@@ -489,7 +488,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene,
float y1,
int rectx,
int recty,
- float *rect_float,
+ const float *rect_float,
float zoomx,
float zoomy)
{
@@ -526,8 +525,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene,
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(
- &state, x1, y1, rectx, recty, GL_RED, GL_FLOAT, GL_NEAREST, rectf, zoomx, zoomy, NULL);
+ immDrawPixelsTex(&state, x1, y1, rectx, recty, GL_R16F, false, rectf, zoomx, zoomy, NULL);
MEM_freeN(rectf);
}
@@ -612,8 +610,7 @@ static void draw_image_buffer(const bContext *C,
/* If RGBA display with color management */
if ((sima_flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B | SI_SHOW_ALPHA)) == 0) {
- ED_draw_imbuf_ctx_clipping(
- C, ibuf, x, y, GL_NEAREST, 0, 0, clip_max_x, clip_max_y, zoomx, zoomy);
+ ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, false, 0, 0, clip_max_x, clip_max_y, zoomx, zoomy);
}
else {
float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f};
@@ -649,9 +646,8 @@ static void draw_image_buffer(const bContext *C,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
display_buffer,
0,
0,
@@ -780,18 +776,8 @@ static void draw_image_paint_helpers(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- immDrawPixelsTex(&state,
- x,
- y,
- ibuf->x,
- ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
- display_buffer,
- zoomx,
- zoomy,
- col);
+ immDrawPixelsTex(
+ &state, x, y, ibuf->x, ibuf->y, GPU_RGBA8, false, display_buffer, zoomx, zoomy, col);
GPU_blend(false);
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index cb0fdcf23ca..4eb4e6649d9 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -400,7 +400,10 @@ bool ED_image_slot_cycle(struct Image *image, int direction)
}
}
- if (i == num_slots) {
+ if (num_slots == 1) {
+ image->render_slot = 0;
+ }
+ else if (i == num_slots) {
image->render_slot = ((cur == 1) ? 0 : 1);
}
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index ae26363ad79..e6f5988aed8 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -21,8 +21,7 @@
* \ingroup spimage
*/
-#ifndef __IMAGE_INTERN_H__
-#define __IMAGE_INTERN_H__
+#pragma once
/* internal exports only */
struct ARegion;
@@ -96,5 +95,3 @@ void IMAGE_OT_tile_fill(struct wmOperatorType *ot);
/* image_panels.c */
struct ImageUser *ntree_get_active_iuser(struct bNodeTree *ntree);
void image_buttons_register(struct ARegionType *art);
-
-#endif /* __IMAGE_INTERN_H__ */
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index f71c92b4c1f..1a98ec0e7c1 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -69,7 +69,6 @@
#include "DEG_depsgraph.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@@ -198,11 +197,10 @@ static Image *image_from_context(const bContext *C)
if (ima) {
return ima;
}
- else {
- /* Image editor. */
- SpaceImage *sima = CTX_wm_space_image(C);
- return (sima) ? sima->image : NULL;
- }
+
+ /* Image editor. */
+ SpaceImage *sima = CTX_wm_space_image(C);
+ return (sima) ? sima->image : NULL;
}
static ImageUser *image_user_from_context(const bContext *C)
@@ -214,11 +212,10 @@ static ImageUser *image_user_from_context(const bContext *C)
if (iuser) {
return iuser;
}
- else {
- /* Image editor. */
- SpaceImage *sima = CTX_wm_space_image(C);
- return (sima) ? &sima->iuser : NULL;
- }
+
+ /* Image editor. */
+ SpaceImage *sima = CTX_wm_space_image(C);
+ return (sima) ? &sima->iuser : NULL;
}
static bool image_from_context_has_data_poll(bContext *C)
@@ -359,10 +356,9 @@ static int image_view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *eve
image_view_pan_exec(C, op);
return OPERATOR_FINISHED;
}
- else {
- image_view_pan_init(C, op, event);
- return OPERATOR_RUNNING_MODAL;
- }
+
+ image_view_pan_init(C, op, event);
+ return OPERATOR_RUNNING_MODAL;
}
static int image_view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
@@ -549,10 +545,9 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
return OPERATOR_FINISHED;
}
- else {
- image_view_zoom_init(C, op, event);
- return OPERATOR_RUNNING_MODAL;
- }
+
+ image_view_zoom_init(C, op, event);
+ return OPERATOR_RUNNING_MODAL;
}
static void image_zoom_apply(ViewZoomData *vpd,
@@ -697,27 +692,26 @@ static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmE
if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
}
- else {
- SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *region = CTX_wm_region(C);
- float pan_vec[3];
- const wmNDOFMotionData *ndof = event->customdata;
- const float speed = NDOF_PIXELS_PER_SECOND;
+ SpaceImage *sima = CTX_wm_space_image(C);
+ ARegion *region = CTX_wm_region(C);
+ float pan_vec[3];
- WM_event_ndof_pan_get(ndof, pan_vec, true);
+ const wmNDOFMotionData *ndof = event->customdata;
+ const float speed = NDOF_PIXELS_PER_SECOND;
- mul_v2_fl(pan_vec, (speed * ndof->dt) / sima->zoom);
- pan_vec[2] *= -ndof->dt;
+ WM_event_ndof_pan_get(ndof, pan_vec, true);
- sima_zoom_set_factor(sima, region, 1.0f + pan_vec[2], NULL, false);
- sima->xof += pan_vec[0];
- sima->yof += pan_vec[1];
+ mul_v2_fl(pan_vec, (speed * ndof->dt) / sima->zoom);
+ pan_vec[2] *= -ndof->dt;
- ED_region_tag_redraw(region);
+ sima_zoom_set_factor(sima, region, 1.0f + pan_vec[2], NULL, false);
+ sima->xof += pan_vec[0];
+ sima->yof += pan_vec[1];
- return OPERATOR_FINISHED;
- }
+ ED_region_tag_redraw(region);
+
+ return OPERATOR_FINISHED;
}
void IMAGE_OT_view_ndof(wmOperatorType *ot)
@@ -1678,24 +1672,23 @@ static char imtype_best_depth(ImBuf *ibuf, const char imtype)
}
return R_IMF_CHAN_DEPTH_8;
}
- else {
- if (depth_ok & R_IMF_CHAN_DEPTH_8) {
- return R_IMF_CHAN_DEPTH_8;
- }
- if (depth_ok & R_IMF_CHAN_DEPTH_12) {
- return R_IMF_CHAN_DEPTH_12;
- }
- if (depth_ok & R_IMF_CHAN_DEPTH_16) {
- return R_IMF_CHAN_DEPTH_16;
- }
- if (depth_ok & R_IMF_CHAN_DEPTH_24) {
- return R_IMF_CHAN_DEPTH_24;
- }
- if (depth_ok & R_IMF_CHAN_DEPTH_32) {
- return R_IMF_CHAN_DEPTH_32;
- }
- return R_IMF_CHAN_DEPTH_8; /* fallback, should not get here */
+
+ if (depth_ok & R_IMF_CHAN_DEPTH_8) {
+ return R_IMF_CHAN_DEPTH_8;
+ }
+ if (depth_ok & R_IMF_CHAN_DEPTH_12) {
+ return R_IMF_CHAN_DEPTH_12;
+ }
+ if (depth_ok & R_IMF_CHAN_DEPTH_16) {
+ return R_IMF_CHAN_DEPTH_16;
+ }
+ if (depth_ok & R_IMF_CHAN_DEPTH_24) {
+ return R_IMF_CHAN_DEPTH_24;
+ }
+ if (depth_ok & R_IMF_CHAN_DEPTH_32) {
+ return R_IMF_CHAN_DEPTH_32;
}
+ return R_IMF_CHAN_DEPTH_8; /* fallback, should not get here */
}
static int image_save_options_init(Main *bmain,
@@ -2147,9 +2140,8 @@ static int image_save_exec(bContext *C, wmOperator *op)
if (ok) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+
+ return OPERATOR_CANCELLED;
}
static int image_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@@ -2160,9 +2152,7 @@ static int image_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
WM_operator_name_call(C, "IMAGE_OT_save_as", WM_OP_INVOKE_DEFAULT, NULL);
return OPERATOR_CANCELLED;
}
- else {
- return image_save_exec(C, op);
- }
+ return image_save_exec(C, op);
}
void IMAGE_OT_save(wmOperatorType *ot)
@@ -2294,9 +2284,7 @@ static bool image_should_be_saved(Image *ima, bool *is_format_writable)
ELEM(ima->source, IMA_SRC_FILE, IMA_SRC_GENERATED, IMA_SRC_TILED)) {
return image_should_be_saved_when_modified(ima);
}
- else {
- return false;
- }
+ return false;
}
static bool image_has_valid_path(Image *ima)
@@ -2606,7 +2594,7 @@ static int image_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e
static void image_new_draw(bContext *UNUSED(C), wmOperator *op)
{
- uiLayout *split, *col[2];
+ uiLayout *col;
uiLayout *layout = op->layout;
PointerRNA ptr;
#if 0
@@ -2618,33 +2606,18 @@ static void image_new_draw(bContext *UNUSED(C), wmOperator *op)
/* copy of WM_operator_props_dialog_popup() layout */
- split = uiLayoutSplit(layout, 0.5f, false);
- col[0] = uiLayoutColumn(split, false);
- col[1] = uiLayoutColumn(split, false);
-
- uiItemL(col[0], IFACE_("Name"), ICON_NONE);
- uiItemR(col[1], &ptr, "name", 0, "", ICON_NONE);
-
- uiItemL(col[0], IFACE_("Width"), ICON_NONE);
- uiItemR(col[1], &ptr, "width", 0, "", ICON_NONE);
-
- uiItemL(col[0], IFACE_("Height"), ICON_NONE);
- uiItemR(col[1], &ptr, "height", 0, "", ICON_NONE);
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
- uiItemL(col[0], IFACE_("Color"), ICON_NONE);
- uiItemR(col[1], &ptr, "color", 0, "", ICON_NONE);
-
- uiItemL(col[0], "", ICON_NONE);
- uiItemR(col[1], &ptr, "alpha", 0, NULL, ICON_NONE);
-
- uiItemL(col[0], IFACE_("Generated Type"), ICON_NONE);
- uiItemR(col[1], &ptr, "generated_type", 0, "", ICON_NONE);
-
- uiItemL(col[0], "", ICON_NONE);
- uiItemR(col[1], &ptr, "float", 0, NULL, ICON_NONE);
-
- uiItemL(col[0], "", ICON_NONE);
- uiItemR(col[1], &ptr, "tiled", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, &ptr, "name", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "width", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "height", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "color", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "alpha", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "generated_type", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "float", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "tiled", 0, NULL, ICON_NONE);
#if 0
if (is_multiview) {
@@ -2795,7 +2768,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
/* force GPU reupload, all image is invalid */
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -2886,7 +2859,7 @@ static int image_scale_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
/* force GPU reupload, all image is invalid */
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
DEG_id_tag_update(&ima->id, 0);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -3741,7 +3714,7 @@ static void draw_fill_tile(PointerRNA *ptr, uiLayout *layout)
uiItemR(col[1], ptr, "float", 0, NULL, ICON_NONE);
}
-static void initialize_fill_tile(PointerRNA *ptr, Image *ima, ImageTile *tile)
+static void tile_fill_init(PointerRNA *ptr, Image *ima, ImageTile *tile)
{
ImageUser iuser;
BKE_imageuser_default(&iuser);
@@ -3854,7 +3827,7 @@ static int tile_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev
}
ImageTile *tile = BLI_findlink(&ima->tiles, ima->active_tile_index);
- initialize_fill_tile(op->ptr, ima, tile);
+ tile_fill_init(op->ptr, ima, tile);
RNA_int_set(op->ptr, "number", next_number);
RNA_int_set(op->ptr, "count", 1);
@@ -4000,7 +3973,7 @@ static int tile_fill_exec(bContext *C, wmOperator *op)
static int tile_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- initialize_fill_tile(op->ptr, CTX_data_edit_image(C), NULL);
+ tile_fill_init(op->ptr, CTX_data_edit_image(C), NULL);
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X);
}
diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c
index e0c44c3a0ba..27b84307f7d 100644
--- a/source/blender/editors/space_image/image_undo.c
+++ b/source/blender/editors/space_image/image_undo.c
@@ -60,8 +60,6 @@
#include "ED_undo.h"
#include "ED_util.h"
-#include "GPU_draw.h"
-
#include "WM_api.h"
static CLG_LogRef LOG = {"ed.image.undo"};
@@ -295,7 +293,8 @@ static void ptile_restore_runtime_list(ListBase *paint_tiles)
SWAP(uint *, ptile->rect.uint, tmpibuf->rect);
}
- GPU_free_image(image); /* force OpenGL reload (maybe partial update will operate better?) */
+ BKE_image_free_gputextures(
+ image); /* force OpenGL reload (maybe partial update will operate better?) */
if (ibuf->rect_float) {
ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
}
@@ -570,7 +569,7 @@ static void uhandle_restore_list(ListBase *undo_handles, bool use_init)
if (changed) {
BKE_image_mark_dirty(image, ibuf);
- GPU_free_image(image); /* force OpenGL reload */
+ BKE_image_free_gputextures(image); /* force OpenGL reload */
if (ibuf->rect_float) {
ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index d7d85112497..c01bc01588e 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -75,11 +75,10 @@
#include "GPU_batch_presets.h"
#include "GPU_framebuffer.h"
#include "GPU_viewport.h"
-#include "image_intern.h"
-/* TODO(fclem) remove bad level calls */
-#include "../draw/DRW_engine.h"
-#include "wm_draw.h"
+#include "DRW_engine_types.h"
+
+#include "image_intern.h"
/**************************** common state *****************************/
@@ -117,7 +116,7 @@ static void image_user_refresh_scene(const bContext *C, SpaceImage *sima)
/* ******************** default callbacks for image space ***************** */
-static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *image_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceImage *simage;
@@ -643,17 +642,18 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
// View2DScrollers *scrollers;
float col[3];
- /* XXX This is in order to draw UI batches with the DRW
- * old context since we now use it for drawing the entire area. */
- gpu_batch_presets_reset();
+ GPU_batch_presets_reset();
+ GPUViewport *viewport = WM_draw_region_get_viewport(region);
+ GPUFrameBuffer *framebuffer_default, *framebuffer_overlay;
+
+ framebuffer_default = GPU_viewport_framebuffer_default_get(viewport);
+ framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
- GPUViewport *viewport = region->draw_buffer->viewport;
- DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
- GPU_framebuffer_bind(fbl->default_fb);
+ GPU_framebuffer_bind(framebuffer_default);
GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
GPU_clear(GPU_COLOR_BIT);
- GPU_framebuffer_bind(fbl->overlay_fb);
+ GPU_framebuffer_bind(framebuffer_overlay);
/* XXX not supported yet, disabling for now */
scene->r.scemode &= ~R_COMP_CROP;
@@ -1093,7 +1093,7 @@ void ED_spacetype_image(void)
st->spaceid = SPACE_IMAGE;
strncpy(st->name, "Image", BKE_ST_MAXNAME);
- st->new = image_new;
+ st->create = image_create;
st->free = image_free;
st->init = image_init;
st->duplicate = image_duplicate;
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 3685e5de852..6c818257ec7 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -108,9 +108,8 @@ static enum eTextViewContext_LineFlag report_line_data(TextViewContext *tvc,
UI_GetThemeColor4ubv(icon_bg_id, r_icon_bg);
return TVC_LINE_FG | TVC_LINE_BG | TVC_LINE_ICON | TVC_LINE_ICON_FG | TVC_LINE_ICON_BG;
}
- else {
- return TVC_LINE_FG | TVC_LINE_BG;
- }
+
+ return TVC_LINE_FG | TVC_LINE_BG;
}
/* reports! */
@@ -159,9 +158,8 @@ static int report_textview_begin(TextViewContext *tvc)
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static void report_textview_end(TextViewContext *UNUSED(tvc))
@@ -185,17 +183,14 @@ static int report_textview_step(TextViewContext *tvc)
return true;
}
- else {
- return false;
- }
+ return false;
}
- else {
- /* step to the next newline */
- tvc->iter_char_end = tvc->iter_char_begin - 1;
- report_textview_init__internal(tvc);
- return true;
- }
+ /* step to the next newline */
+ tvc->iter_char_end = tvc->iter_char_begin - 1;
+ report_textview_init__internal(tvc);
+
+ return true;
}
static void report_textview_line_get(TextViewContext *tvc, const char **r_line, int *r_len)
diff --git a/source/blender/editors/space_info/info_intern.h b/source/blender/editors/space_info/info_intern.h
index 79bfb1fa047..a19ebe5ef04 100644
--- a/source/blender/editors/space_info/info_intern.h
+++ b/source/blender/editors/space_info/info_intern.h
@@ -21,8 +21,7 @@
* \ingroup spinfo
*/
-#ifndef __INFO_INTERN_H__
-#define __INFO_INTERN_H__
+#pragma once
/* internal exports only */
@@ -65,5 +64,3 @@ void INFO_OT_select_box(struct wmOperatorType *ot);
void INFO_OT_report_replay(struct wmOperatorType *ot);
void INFO_OT_report_delete(struct wmOperatorType *ot);
void INFO_OT_report_copy(struct wmOperatorType *ot);
-
-#endif /* __INFO_INTERN_H__ */
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index e1937dffb37..4e91da01cc9 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -43,6 +43,7 @@
#include "BLT_translation.h"
#include "BKE_blender_version.h"
+#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_editmesh.h"
@@ -405,46 +406,6 @@ static void stats_update(Depsgraph *depsgraph, ViewLayer *view_layer)
*(view_layer->stats) = stats;
}
-static const char *footer_string(ViewLayer *view_layer)
-{
-#define MAX_INFO_MEM_LEN 64
- char memstr[MAX_INFO_MEM_LEN];
- char gpumemstr[MAX_INFO_MEM_LEN] = "";
- char formatted_mem[15];
- size_t ofs = 0;
-
- uintptr_t mem_in_use = MEM_get_memory_in_use();
-
- /* get memory statistics */
- BLI_str_format_byte_unit(formatted_mem, mem_in_use, false);
- ofs = BLI_snprintf(memstr, MAX_INFO_MEM_LEN, TIP_("Mem: %s"), formatted_mem);
-
- if (GPU_mem_stats_supported()) {
- int gpu_free_mem, gpu_tot_memory;
-
- GPU_mem_stats_get(&gpu_tot_memory, &gpu_free_mem);
-
- BLI_str_format_byte_unit(formatted_mem, gpu_free_mem, false);
- ofs = BLI_snprintf(gpumemstr, MAX_INFO_MEM_LEN, TIP_(" | Free GPU Mem: %s"), formatted_mem);
-
- if (gpu_tot_memory) {
- BLI_str_format_byte_unit(formatted_mem, gpu_tot_memory, false);
- BLI_snprintf(gpumemstr + ofs, MAX_INFO_MEM_LEN - ofs, TIP_("/%s"), formatted_mem);
- }
- }
-
- BLI_snprintf(view_layer->footer_str,
- sizeof(view_layer->footer_str),
- "%s%s | %s",
- memstr,
- gpumemstr,
- BKE_blender_version_string());
-
- return view_layer->footer_str;
-
-#undef MAX_INFO_MEM_LEN
-}
-
void ED_info_stats_clear(ViewLayer *view_layer)
{
if (view_layer->stats) {
@@ -453,45 +414,26 @@ void ED_info_stats_clear(ViewLayer *view_layer)
}
}
-const char *ED_info_footer_string(ViewLayer *view_layer)
-{
- return footer_string(view_layer);
-}
-
-static void stats_row(int col1,
- const char *key,
- int col2,
- const char *value1,
- const char *value2,
- int *y,
- int height)
-{
- *y -= height;
- BLF_draw_default(col1, *y, 0.0f, key, 128);
- char values[128];
- BLI_snprintf(values, sizeof(values), (value2) ? "%s / %s" : "%s", value1, value2);
- BLF_draw_default(col2, *y, 0.0f, values, sizeof(values));
-}
-
-void ED_info_draw_stats(
- Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height)
+static bool format_stats(Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer,
+ SceneStatsFmt *stats_fmt)
{
/* Create stats if they don't already exist. */
if (!view_layer->stats) {
/* Do not not access dependency graph if interface is marked as locked. */
wmWindowManager *wm = bmain->wm.first;
if (wm->is_interface_locked) {
- return;
+ return false;
}
Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true);
stats_update(depsgraph, view_layer);
}
SceneStats *stats = view_layer->stats;
- SceneStatsFmt stats_fmt;
/* Generate formatted numbers. */
-#define SCENE_STATS_FMT_INT(_id) BLI_str_format_uint64_grouped(stats_fmt._id, stats->_id)
+#define SCENE_STATS_FMT_INT(_id) BLI_str_format_uint64_grouped(stats_fmt->_id, stats->_id)
SCENE_STATS_FMT_INT(totvert);
SCENE_STATS_FMT_INT(totvertsel);
@@ -519,6 +461,176 @@ void ED_info_draw_stats(
SCENE_STATS_FMT_INT(totgppoint);
#undef SCENE_STATS_FMT_INT
+ return true;
+}
+
+static void get_stats_string(
+ char *info, int len, size_t *ofs, ViewLayer *view_layer, SceneStatsFmt *stats_fmt)
+{
+ Object *ob = OBACT(view_layer);
+ Object *obedit = OBEDIT_FROM_OBACT(ob);
+ eObjectMode object_mode = ob ? ob->mode : OB_MODE_OBJECT;
+ LayerCollection *layer_collection = view_layer->active_collection;
+
+ if (object_mode == OB_MODE_OBJECT) {
+ *ofs += BLI_snprintf(info + *ofs,
+ len - *ofs,
+ "%s | ",
+ BKE_collection_ui_name_get(layer_collection->collection));
+ }
+
+ if (ob) {
+ *ofs += BLI_snprintf(info + *ofs, len - *ofs, "%s | ", ob->id.name + 2);
+ }
+
+ if (obedit) {
+ if (BKE_keyblock_from_object(obedit)) {
+ *ofs += BLI_strncpy_rlen(info + *ofs, TIP_("(Key) "), len - *ofs);
+ }
+
+ if (obedit->type == OB_MESH) {
+ *ofs += BLI_snprintf(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s/%s | Edges:%s/%s | Faces:%s/%s | Tris:%s"),
+ stats_fmt->totvertsel,
+ stats_fmt->totvert,
+ stats_fmt->totedgesel,
+ stats_fmt->totedge,
+ stats_fmt->totfacesel,
+ stats_fmt->totface,
+ stats_fmt->tottri);
+ }
+ else if (obedit->type == OB_ARMATURE) {
+ *ofs += BLI_snprintf(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s/%s | Bones:%s/%s"),
+ stats_fmt->totvertsel,
+ stats_fmt->totvert,
+ stats_fmt->totbonesel,
+ stats_fmt->totbone);
+ }
+ else {
+ *ofs += BLI_snprintf(
+ info + *ofs, len - *ofs, TIP_("Verts:%s/%s"), stats_fmt->totvertsel, stats_fmt->totvert);
+ }
+ }
+ else if (ob && (object_mode & OB_MODE_POSE)) {
+ *ofs += BLI_snprintf(
+ info + *ofs, len - *ofs, TIP_("Bones:%s/%s"), stats_fmt->totbonesel, stats_fmt->totbone);
+ }
+ else if ((ob) && (ob->type == OB_GPENCIL)) {
+ *ofs += BLI_snprintf(info + *ofs,
+ len - *ofs,
+ TIP_("Layers:%s | Frames:%s | Strokes:%s | Points:%s"),
+ stats_fmt->totgplayer,
+ stats_fmt->totgpframe,
+ stats_fmt->totgpstroke,
+ stats_fmt->totgppoint);
+ }
+ else if (stats_is_object_dynamic_topology_sculpt(ob, object_mode)) {
+ *ofs += BLI_snprintf(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s | Tris:%s"),
+ stats_fmt->totvert,
+ stats_fmt->tottri);
+ }
+ else {
+ *ofs += BLI_snprintf(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s | Faces:%s | Tris:%s"),
+ stats_fmt->totvert,
+ stats_fmt->totface,
+ stats_fmt->tottri);
+ }
+
+ *ofs += BLI_snprintf(
+ info + *ofs, len - *ofs, TIP_(" | Objects:%s/%s"), stats_fmt->totobjsel, stats_fmt->totobj);
+}
+
+const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C)
+{
+ char formatted_mem[15];
+ size_t ofs = 0;
+ char *info = screen->statusbar_info;
+ int len = sizeof(screen->statusbar_info);
+
+ info[0] = '\0';
+
+ /* Scene statistics. */
+ if (U.statusbar_flag & STATUSBAR_SHOW_STATS) {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Scene *scene = CTX_data_scene(C);
+ SceneStatsFmt stats_fmt;
+ if (format_stats(bmain, scene, view_layer, &stats_fmt)) {
+ get_stats_string(info + ofs, len, &ofs, view_layer, &stats_fmt);
+ }
+ }
+
+ /* Memory status. */
+ if (U.statusbar_flag & STATUSBAR_SHOW_MEMORY) {
+ if (info[0]) {
+ ofs += BLI_snprintf(info + ofs, len - ofs, " | ");
+ }
+ uintptr_t mem_in_use = MEM_get_memory_in_use();
+ BLI_str_format_byte_unit(formatted_mem, mem_in_use, false);
+ ofs += BLI_snprintf(info + ofs, len, TIP_("Memory: %s"), formatted_mem);
+ }
+
+ /* GPU VRAM status. */
+ if ((U.statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) {
+ int gpu_free_mem_kb, gpu_tot_mem_kb;
+ GPU_mem_stats_get(&gpu_tot_mem_kb, &gpu_free_mem_kb);
+ float gpu_total_gb = gpu_tot_mem_kb / 1048576.0f;
+ float gpu_free_gb = gpu_free_mem_kb / 1048576.0f;
+ if (info[0]) {
+ ofs += BLI_snprintf(info + ofs, len - ofs, " | ");
+ }
+ if (gpu_free_mem_kb && gpu_tot_mem_kb) {
+ ofs += BLI_snprintf(info + ofs,
+ len - ofs,
+ TIP_("VRAM: %.1f/%.1f GiB"),
+ gpu_total_gb - gpu_free_gb,
+ gpu_total_gb);
+ }
+ else {
+ /* Can only show amount of GPU VRAM available. */
+ ofs += BLI_snprintf(info + ofs, len - ofs, TIP_("VRAM: %.1f GiB Free"), gpu_free_gb);
+ }
+ }
+
+ /* Blender version. */
+ if (U.statusbar_flag & STATUSBAR_SHOW_VERSION) {
+ if (info[0]) {
+ ofs += BLI_snprintf(info + ofs, len - ofs, " | ");
+ }
+ ofs += BLI_snprintf(info + ofs, len - ofs, TIP_("%s"), BKE_blender_version_string());
+ }
+
+ return info;
+}
+
+static void stats_row(int col1,
+ const char *key,
+ int col2,
+ const char *value1,
+ const char *value2,
+ int *y,
+ int height)
+{
+ *y -= height;
+ BLF_draw_default(col1, *y, 0.0f, key, 128);
+ char values[128];
+ BLI_snprintf(values, sizeof(values), (value2) ? "%s / %s" : "%s", value1, value2);
+ BLF_draw_default(col2, *y, 0.0f, values, sizeof(values));
+}
+
+void ED_info_draw_stats(
+ Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height)
+{
+ SceneStatsFmt stats_fmt;
+ if (!format_stats(bmain, scene, view_layer, &stats_fmt)) {
+ return;
+ }
Object *ob = OBACT(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 836830916ed..b9153ec0cbd 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -53,7 +53,7 @@
/* ******************** default callbacks for info space ***************** */
-static SpaceLink *info_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *info_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceInfo *sinfo;
@@ -287,7 +287,7 @@ void ED_spacetype_info(void)
st->spaceid = SPACE_INFO;
strncpy(st->name, "Info", BKE_ST_MAXNAME);
- st->new = info_new;
+ st->create = info_create;
st->free = info_free;
st->init = info_init;
st->duplicate = info_duplicate;
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 8076d3d7eaf..eee8b989cc2 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -186,7 +186,7 @@ static bool textview_draw_string(TextViewDrawState *tds,
MEM_freeN(offsets);
return true;
}
- else if (y_next < tds->scroll_ymin) {
+ if (y_next < tds->scroll_ymin) {
/* Have not reached the drawable area so don't break. */
tds->xy[1] = y_next;
diff --git a/source/blender/editors/space_info/textview.h b/source/blender/editors/space_info/textview.h
index 41f8baf634e..7520dbce191 100644
--- a/source/blender/editors/space_info/textview.h
+++ b/source/blender/editors/space_info/textview.h
@@ -18,8 +18,7 @@
* \ingroup spinfo
*/
-#ifndef __TEXTVIEW_H__
-#define __TEXTVIEW_H__
+#pragma once
enum eTextViewContext_LineFlag {
TVC_LINE_FG = (1 << 0),
@@ -79,5 +78,3 @@ int textview_draw(struct TextViewContext *tvc,
const int mval_init[2],
void **r_mval_pick_item,
int *r_mval_pick_offset);
-
-#endif /* __TEXTVIEW_H__ */
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index d0d9f2f57bb..130167f1bd0 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -392,7 +392,7 @@ static void nla_panel_properties(const bContext *C, Panel *panel)
uiItemR(column, &strip_ptr, "blend_type", 0, NULL, ICON_NONE);
/* Blend in/out + auto-blending:
- * - blend in/out can only be set when autoblending is off
+ * - blend in/out can only be set when auto-blending is off.
*/
uiItemS(layout);
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index d399ea47d7e..86bb189c638 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -461,10 +461,9 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
"block)");
return OPERATOR_CANCELLED;
}
- else {
- id = adt_ptr.owner_id;
- adt = adt_ptr.data;
- }
+
+ id = adt_ptr.owner_id;
+ adt = adt_ptr.data;
}
else {
/* indexed channel */
@@ -483,7 +482,7 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
ANIM_animdata_freelist(&anim_data);
return OPERATOR_CANCELLED;
}
- else if (ale->type != ANIMTYPE_NLAACTION) {
+ if (ale->type != ANIMTYPE_NLAACTION) {
BKE_reportf(op->reports,
RPT_ERROR,
"Animation channel at index %d is not a NLA 'Active Action' channel",
@@ -505,22 +504,21 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Internal Error - AnimData block is not valid");
return OPERATOR_CANCELLED;
}
- else if (nlaedit_is_tweakmode_on(&ac)) {
+ if (nlaedit_is_tweakmode_on(&ac)) {
BKE_report(op->reports,
RPT_WARNING,
"Cannot push down actions while tweaking a strip's action, exit tweak mode first");
return OPERATOR_CANCELLED;
}
- else if (adt->action == NULL) {
+ if (adt->action == NULL) {
BKE_report(op->reports, RPT_WARNING, "No active action to push down");
return OPERATOR_CANCELLED;
}
- else {
- /* 'push-down' action - only usable when not in TweakMode */
- BKE_nla_action_pushdown(adt);
- DEG_id_tag_update_ex(CTX_data_main(C), id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE);
- }
+ /* 'push-down' action - only usable when not in TweakMode */
+ BKE_nla_action_pushdown(adt);
+
+ DEG_id_tag_update_ex(CTX_data_main(C), id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE);
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
@@ -735,14 +733,13 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
/* done */
return OPERATOR_FINISHED;
}
- else {
- /* 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;
- }
+ /* 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;
}
void NLA_OT_tracks_add(wmOperatorType *ot)
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index a56b7f8422e..96599fd92a7 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -645,8 +645,9 @@ static void nla_draw_strip_text(AnimData *adt,
UI_view2d_text_cache_add_rectf(v2d, &rect, str, str_len, col);
}
-/* add frame extents to cache of text-strings to draw in pixelspace
- * for now, only used when transforming strips
+/**
+ * Add frame extents to cache of text-strings to draw in pixel-space
+ * for now, only used when transforming strips.
*/
static void nla_draw_strip_frames_text(
NlaTrack *UNUSED(nlt), NlaStrip *strip, View2D *v2d, float UNUSED(yminc), float ymaxc)
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index dec7a0fd93c..bc9bd0e18f2 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -269,9 +269,7 @@ static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op)
if (ok) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void NLA_OT_tweakmode_exit(wmOperatorType *ot)
@@ -373,9 +371,8 @@ static int nlaedit_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
if (ac.scene == NULL) {
return OPERATOR_CANCELLED;
}
- else {
- scene = ac.scene;
- }
+
+ scene = ac.scene;
/* set the range directly */
get_nlastrip_extents(&ac, &min, &max, true);
@@ -616,7 +613,7 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
// printf("Add strip - actname = '%s'\n", actname);
return OPERATOR_CANCELLED;
}
- else if (act->idroot == 0) {
+ if (act->idroot == 0) {
/* hopefully in this case (i.e. library of userless actions),
* the user knows what they're doing... */
BKE_reportf(op->reports,
@@ -830,12 +827,11 @@ static int nlaedit_add_transition_exec(bContext *C, wmOperator *op)
/* done */
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports,
- RPT_ERROR,
- "Needs at least a pair of adjacent selected strips with a gap between them");
- return OPERATOR_CANCELLED;
- }
+
+ BKE_report(op->reports,
+ RPT_ERROR,
+ "Needs at least a pair of adjacent selected strips with a gap between them");
+ return OPERATOR_CANCELLED;
}
void NLA_OT_transition_add(wmOperatorType *ot)
@@ -1146,9 +1142,8 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op)
/* done */
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+
+ return OPERATOR_CANCELLED;
}
static int nlaedit_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@@ -1293,9 +1288,8 @@ static void nlaedit_split_strip_actclip(
if (IS_EQF(len, 0.0f)) {
return;
}
- else {
- splitframe = strip->start + (len / 2.0f);
- }
+
+ splitframe = strip->start + (len / 2.0f);
/* action range */
len = strip->actend - strip->actstart;
@@ -2504,10 +2498,9 @@ static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied");
return OPERATOR_CANCELLED;
}
- else {
- /* no updates needed - copy is non-destructive operation */
- return OPERATOR_FINISHED;
- }
+
+ /* no updates needed - copy is non-destructive operation */
+ return OPERATOR_FINISHED;
}
void NLA_OT_fmodifier_copy(wmOperatorType *ot)
@@ -2591,10 +2584,9 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports, RPT_ERROR, "No F-Modifiers to paste");
- return OPERATOR_CANCELLED;
- }
+
+ BKE_report(op->reports, RPT_ERROR, "No F-Modifiers to paste");
+ return OPERATOR_CANCELLED;
}
void NLA_OT_fmodifier_paste(wmOperatorType *ot)
diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h
index 6b0429230fe..9a9ea161f56 100644
--- a/source/blender/editors/space_nla/nla_intern.h
+++ b/source/blender/editors/space_nla/nla_intern.h
@@ -21,8 +21,7 @@
* \ingroup spnla
*/
-#ifndef __NLA_INTERN_H__
-#define __NLA_INTERN_H__
+#pragma once
/* internal exports only */
@@ -149,5 +148,3 @@ bool nlaedit_is_tweakmode_on(bAnimContext *ac);
void nla_operatortypes(void);
void nla_keymap(wmKeyConfig *keyconf);
-
-#endif /* __NLA_INTERN_H__ */
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index b09536e0621..7bbfe451eed 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -57,7 +57,7 @@
/* ******************** default callbacks for nla space ***************** */
-static SpaceLink *nla_new(const ScrArea *area, const Scene *scene)
+static SpaceLink *nla_create(const ScrArea *area, const Scene *scene)
{
ARegion *region;
SpaceNla *snla;
@@ -608,7 +608,7 @@ void ED_spacetype_nla(void)
st->spaceid = SPACE_NLA;
strncpy(st->name, "NLA", BKE_ST_MAXNAME);
- st->new = nla_new;
+ st->create = nla_create;
st->free = nla_free;
st->init = nla_init;
st->duplicate = nla_duplicate;
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 234ca5d5ce6..207f67aed1b 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -284,23 +284,21 @@ static int node_resize_area_default(bNode *node, int x, int y)
if (BLI_rctf_isect_pt(&totr, x, y)) {
return NODE_RESIZE_RIGHT;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else {
- const float size = NODE_RESIZE_MARGIN;
- 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) {
- dir |= NODE_RESIZE_LEFT;
- }
- return dir;
+ const float size = NODE_RESIZE_MARGIN;
+ 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) {
+ dir |= NODE_RESIZE_LEFT;
}
+ return dir;
}
/* ****************** BUTTON CALLBACKS FOR COMMON NODES ***************** */
@@ -862,11 +860,13 @@ static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), Poin
if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NISHITA) {
uiItemR(layout, ptr, "sun_disc", DEFAULT_FLAGS, NULL, 0);
+ uiLayout *col;
if (RNA_boolean_get(ptr, "sun_disc")) {
- uiItemR(layout, ptr, "sun_size", DEFAULT_FLAGS, NULL, ICON_NONE);
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "sun_size", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "sun_intensity", DEFAULT_FLAGS, NULL, ICON_NONE);
}
- uiLayout *col;
col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "sun_elevation", DEFAULT_FLAGS, NULL, ICON_NONE);
uiItemR(col, ptr, "sun_rotation", DEFAULT_FLAGS, NULL, ICON_NONE);
@@ -1015,7 +1015,8 @@ static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, Pointer
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- if (RNA_collection_length(&dataptr, "sculpt_vertex_colors")) {
+ if (U.experimental.use_sculpt_vertex_colors &&
+ RNA_collection_length(&dataptr, "sculpt_vertex_colors")) {
uiItemPointerR(
layout, ptr, "layer_name", &dataptr, "sculpt_vertex_colors", "", ICON_GROUP_VCOL);
}
@@ -3575,6 +3576,8 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout
break;
}
}
+
+ uiItemR(layout, ptr, "hide_value", DEFAULT_FLAGS, NULL, 0);
}
void ED_init_standard_node_socket_type(bNodeSocketType *stype)
@@ -3675,9 +3678,8 @@ void draw_nodespace_back_pix(const bContext *C,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
display_buffer,
snode->zoom,
snode->zoom,
@@ -3690,12 +3692,12 @@ void draw_nodespace_back_pix(const bContext *C,
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- ED_draw_imbuf_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
+ ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom);
GPU_blend(false);
}
else {
- ED_draw_imbuf_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
+ ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom);
}
if (cache_handle) {
@@ -3833,7 +3835,7 @@ static bool node_link_bezier_handles(View2D *v2d,
if (v2d && min_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) {
return 0; /* clipped */
}
- else if (v2d && max_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
+ if (v2d && max_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
return 0; /* clipped */
}
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 95a37f85828..037fe575973 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -382,9 +382,7 @@ static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *even
RNA_struct_property_is_set(op->ptr, "name")) {
return node_add_file_exec(C, op);
}
- else {
- return WM_operator_filesel(C, op, event);
- }
+ return WM_operator_filesel(C, op, event);
}
void NODE_OT_add_file(wmOperatorType *ot)
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index c3823d8eb27..52bd4d68649 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -97,9 +97,7 @@ static bNodeTree *node_tree_from_ID(ID *id)
if (GS(id->name) == ID_NT) {
return (bNodeTree *)id;
}
- else {
- return ntreeFromID(id);
- }
+ return ntreeFromID(id);
}
return NULL;
@@ -217,7 +215,7 @@ static bool compare_nodes(const bNode *a, const bNode *b)
if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND)) {
return 0;
}
- else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND)) {
+ if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND)) {
return 1;
}
@@ -225,7 +223,7 @@ static bool compare_nodes(const bNode *a, const bNode *b)
if (!b_active && a_active) {
return 1;
}
- else if (!b_select && (a_active || a_select)) {
+ if (!b_select && (a_active || a_select)) {
return 1;
}
@@ -949,9 +947,8 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
draw_rect.ymin,
preview->xsize,
preview->ysize,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_LINEAR,
+ GPU_RGBA8,
+ true,
preview->rect,
scale,
scale,
@@ -1558,15 +1555,13 @@ int node_get_resize_cursor(int directions)
if (directions == 0) {
return WM_CURSOR_DEFAULT;
}
- else if ((directions & ~(NODE_RESIZE_TOP | NODE_RESIZE_BOTTOM)) == 0) {
+ if ((directions & ~(NODE_RESIZE_TOP | NODE_RESIZE_BOTTOM)) == 0) {
return WM_CURSOR_Y_MOVE;
}
- else if ((directions & ~(NODE_RESIZE_RIGHT | NODE_RESIZE_LEFT)) == 0) {
+ if ((directions & ~(NODE_RESIZE_RIGHT | NODE_RESIZE_LEFT)) == 0) {
return WM_CURSOR_X_MOVE;
}
- else {
- return WM_CURSOR_EDIT;
- }
+ return WM_CURSOR_EDIT;
}
void node_set_cursor(wmWindow *win, SpaceNode *snode, float cursor[2])
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 11d87148713..c88b6a1b297 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -238,7 +238,12 @@ static void compo_progressjob(void *cjv, float progress)
}
/* only this runs inside thread */
-static void compo_startjob(void *cjv, short *stop, short *do_update, float *progress)
+static void compo_startjob(void *cjv,
+ /* Cannot be const, this function implements wm_jobs_start_callback.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ short *stop,
+ short *do_update,
+ float *progress)
{
CompoJob *cj = cjv;
bNodeTree *ntree = cj->localtree;
@@ -1692,6 +1697,8 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
}
}
+ do_tag_update |= ED_node_is_simulation(snode);
+
snode_notify(C, snode);
if (do_tag_update) {
snode_dag_update(C, snode);
@@ -1734,6 +1741,8 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
}
}
+ do_tag_update |= ED_node_is_simulation(snode);
+
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
snode_notify(C, snode);
@@ -2734,7 +2743,7 @@ static int clear_viewer_border_exec(bContext *C, wmOperator *UNUSED(op))
void NODE_OT_clear_viewer_border(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Clear Viewer Border";
+ ot->name = "Clear Viewer Region";
ot->description = "Clear the boundaries for viewer operations";
ot->idname = "NODE_OT_clear_viewer_border";
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 2617384d046..7894fade517 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -56,6 +56,7 @@
#include "UI_resources.h"
#include "NOD_common.h"
+#include "NOD_socket.h"
#include "node_intern.h" /* own include */
static bool node_group_operator_active(bContext *C)
@@ -107,13 +108,13 @@ static const char *group_node_idname(bContext *C)
if (ED_node_is_shader(snode)) {
return "ShaderNodeGroup";
}
- else if (ED_node_is_compositor(snode)) {
+ if (ED_node_is_compositor(snode)) {
return "CompositorNodeGroup";
}
- else if (ED_node_is_texture(snode)) {
+ if (ED_node_is_texture(snode)) {
return "TextureNodeGroup";
}
- else if (ED_node_is_simulation(snode)) {
+ if (ED_node_is_simulation(snode)) {
return "SimulationNodeGroup";
}
@@ -128,9 +129,7 @@ static bNode *node_group_get_active(bContext *C, const char *node_idname)
if (node && STREQ(node->idname, node_idname)) {
return node;
}
- else {
- return NULL;
- }
+ return NULL;
}
/* ***************** Edit Group operator ************* */
@@ -181,6 +180,26 @@ void NODE_OT_group_edit(wmOperatorType *ot)
/* ******************** Ungroup operator ********************** */
+/* The given paths will be owned by the returned instance. Both pointers are allowed to point to
+ * the same string. */
+static AnimationBasePathChange *animation_basepath_change_new(const char *src_basepath,
+ const char *dst_basepath)
+{
+ AnimationBasePathChange *basepath_change = MEM_callocN(sizeof(*basepath_change), AT);
+ basepath_change->src_basepath = src_basepath;
+ basepath_change->dst_basepath = dst_basepath;
+ return basepath_change;
+}
+
+static void animation_basepath_change_free(AnimationBasePathChange *basepath_change)
+{
+ if (basepath_change->src_basepath != basepath_change->dst_basepath) {
+ MEM_freeN((void *)basepath_change->src_basepath);
+ }
+ MEM_freeN((void *)basepath_change->dst_basepath);
+ MEM_freeN(basepath_change);
+}
+
/* returns 1 if its OK */
static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
{
@@ -219,16 +238,11 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
/* 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
*/
+ const char *old_animation_basepath = NULL;
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));
- }
+ old_animation_basepath = RNA_path_from_ID_to_struct(&ptr);
}
/* migrate node */
@@ -238,6 +252,14 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
/* ensure unique node name in the node tree */
nodeUniqueName(ntree, node);
+ if (wgroup->adt) {
+ PointerRNA ptr;
+ RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
+ const char *new_animation_basepath = RNA_path_from_ID_to_struct(&ptr);
+ BLI_addtail(&anim_basepaths,
+ animation_basepath_change_new(old_animation_basepath, new_animation_basepath));
+ }
+
if (!node->parent) {
node->locx += gnode->locx;
node->locy += gnode->locy;
@@ -260,7 +282,6 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
/* and copy across the animation,
* note that the animation data's action can be NULL here */
if (wgroup->adt) {
- LinkData *ld, *ldn = NULL;
bAction *waction;
/* firstly, wgroup needs to temporary dummy action
@@ -268,14 +289,11 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
waction = wgroup->adt->action = BKE_action_copy(bmain, wgroup->adt->action);
/* now perform the moving */
- BKE_animdata_separate_by_basepath(bmain, &wgroup->id, &ntree->id, &anim_basepaths);
+ BKE_animdata_transfer_by_basepath(bmain, &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);
+ LISTBASE_FOREACH_MUTABLE (AnimationBasePathChange *, basepath_change, &anim_basepaths) {
+ animation_basepath_change_free(basepath_change);
}
/* free temp action too */
@@ -460,7 +478,7 @@ static int node_group_separate_selected(
path = RNA_path_from_ID_to_struct(&ptr);
if (path) {
- BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+ BLI_addtail(&anim_basepaths, animation_basepath_change_new(path, path));
}
}
@@ -513,17 +531,12 @@ static int node_group_separate_selected(
/* 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(bmain, &ngroup->id, &ntree->id, &anim_basepaths);
+ BKE_animdata_transfer_by_basepath(bmain, &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);
+ LISTBASE_FOREACH_MUTABLE (AnimationBasePathChange *, basepath_change, &anim_basepaths) {
+ animation_basepath_change_free(basepath_change);
}
}
@@ -687,7 +700,8 @@ static bool node_group_make_test_selected(bNodeTree *ntree,
return true;
}
-static int node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min, float *max)
+static int node_get_selected_minmax(
+ bNodeTree *ntree, bNode *gnode, float *min, float *max, bool use_size)
{
bNode *node;
float loc[2];
@@ -698,6 +712,11 @@ static int node_get_selected_minmax(bNodeTree *ntree, bNode *gnode, float *min,
if (node_group_make_use_node(node, gnode)) {
nodeToView(node, 0.0f, 0.0f, &loc[0], &loc[1]);
minmax_v2v2_v2(min, max, loc);
+ if (use_size) {
+ loc[0] += node->width;
+ loc[1] -= node->height;
+ minmax_v2v2_v2(min, max, loc);
+ }
totselect++;
}
}
@@ -715,10 +734,10 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
Main *bmain = CTX_data_main(C);
bNodeTree *ngroup = (bNodeTree *)gnode->id;
bNodeLink *link, *linkn;
- bNode *node, *nextn;
- bNodeSocket *sock;
+ bNode *node, *nextn, *link_node;
+ bNodeSocket *sock, *link_sock;
ListBase anim_basepaths = {NULL, NULL};
- float min[2], max[2], center[2];
+ float min[2], max[2], real_min[2], real_max[2], center[2];
int totselect;
bool expose_visible = false;
bNode *input_node, *output_node;
@@ -732,10 +751,12 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
nodeSetSelected(node, false);
}
- totselect = node_get_selected_minmax(ntree, gnode, min, max);
+ totselect = node_get_selected_minmax(ntree, gnode, min, max, false);
add_v2_v2v2(center, min, max);
mul_v2_fl(center, 0.5f);
+ node_get_selected_minmax(ntree, gnode, real_min, real_max, true);
+
/* auto-add interface for "solo" nodes */
if (totselect == 1) {
expose_visible = true;
@@ -756,7 +777,7 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
path = RNA_path_from_ID_to_struct(&ptr);
if (path) {
- BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+ BLI_addtail(&anim_basepaths, animation_basepath_change_new(path, path));
}
}
@@ -776,16 +797,11 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
/* move animation data over */
if (ntree->adt) {
- LinkData *ld, *ldn = NULL;
-
- BKE_animdata_separate_by_basepath(bmain, &ntree->id, &ngroup->id, &anim_basepaths);
+ BKE_animdata_transfer_by_basepath(bmain, &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);
+ LISTBASE_FOREACH_MUTABLE (AnimationBasePathChange *, basepath_change, &anim_basepaths) {
+ animation_basepath_change_free(basepath_change);
}
}
@@ -794,12 +810,12 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
/* create input node */
input_node = nodeAddStaticNode(C, ngroup, NODE_GROUP_INPUT);
- input_node->locx = min[0] - center[0] - offsetx;
+ input_node->locx = real_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->locx = real_max[0] - center[0] + offsetx * 0.25f;
output_node->locy = -offsety;
/* relink external sockets */
@@ -815,12 +831,9 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
*/
nodeRemLink(ntree, link);
}
- else if (fromselect && toselect) {
- BLI_remlink(&ntree->links, link);
- BLI_addtail(&ngroup->links, link);
- }
- else if (toselect) {
- bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link->tonode, link->tosock);
+ else if (toselect && !fromselect) {
+ node_socket_skip_reroutes(&ntree->links, link->tonode, link->tosock, &link_node, &link_sock);
+ bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link_node, link_sock);
bNodeSocket *input_sock;
/* update the group node and interface node sockets,
@@ -837,7 +850,7 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
link->tonode = gnode;
link->tosock = node_group_find_input_socket(gnode, iosock->identifier);
}
- else if (fromselect) {
+ else if (fromselect && !toselect) {
/* First check whether the source of this link is already connected to an output.
* If yes, reuse that output instead of duplicating it. */
bool connected = false;
@@ -853,8 +866,9 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
}
if (!connected) {
- bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(
- ngroup, link->fromnode, link->fromsock);
+ node_socket_skip_reroutes(
+ &ntree->links, link->fromnode, link->fromsock, &link_node, &link_sock);
+ bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link_node, link_sock);
bNodeSocket *output_sock;
/* update the group node and interface node sockets,
@@ -874,6 +888,19 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
}
}
+ /* move internal links */
+ 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 && toselect) {
+ BLI_remlink(&ntree->links, link);
+ BLI_addtail(&ngroup->links, link);
+ }
+ }
+
/* move nodes in the group to the center */
for (node = ngroup->nodes.first; node; node = node->next) {
if (node_group_make_use_node(node, gnode) && !node->parent) {
@@ -955,7 +982,7 @@ static bNode *node_group_make_from_selected(const bContext *C,
float min[2], max[2];
int totselect;
- totselect = node_get_selected_minmax(ntree, NULL, min, max);
+ totselect = node_get_selected_minmax(ntree, NULL, min, max, false);
/* don't make empty group */
if (totselect == 0) {
return NULL;
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 04186c3a727..9461892360e 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -21,8 +21,7 @@
* \ingroup spnode
*/
-#ifndef __NODE_INTERN_H__
-#define __NODE_INTERN_H__
+#pragma once
#include "BKE_node.h"
#include "UI_interface.h"
@@ -301,5 +300,3 @@ enum eNodeSpace_ButEvents {
B_NODE_LOADIMAGE,
B_NODE_SETIMAGE,
};
-
-#endif /* __NODE_INTERN_H__ */
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 144e3bd3506..9110d82fb84 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -76,10 +76,9 @@ static bool ntree_check_nodes_connected_dfs(bNodeTree *ntree, bNode *from, bNode
if (link->tonode == to) {
return true;
}
- else {
- if (ntree_check_nodes_connected_dfs(ntree, link->tonode, to)) {
- return true;
- }
+
+ if (ntree_check_nodes_connected_dfs(ntree, link->tonode, to)) {
+ return true;
}
}
}
@@ -191,9 +190,7 @@ static int sort_nodes_locx(const void *a, const void *b)
if (node1->locx > node2->locx) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
static bool socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, const bool allow_used)
@@ -254,6 +251,12 @@ static bNodeSocket *best_socket_output(bNodeTree *ntree,
}
}
+ /* Always allow linking to an reroute node. The socket type of the reroute sockets might change
+ * after the link has been created. */
+ if (node->type == NODE_REROUTE) {
+ return node->outputs.first;
+ }
+
return NULL;
}
@@ -667,6 +670,8 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
}
ntree->is_updating = false;
+ do_tag_update |= ED_node_is_simulation(snode);
+
ntreeUpdateTree(bmain, ntree);
snode_notify(C, snode);
if (do_tag_update) {
@@ -921,9 +926,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
- else {
- return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
- }
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
static void node_link_cancel(bContext *C, wmOperator *op)
@@ -1069,6 +1072,8 @@ static int cut_links_exec(bContext *C, wmOperator *op)
}
}
+ do_tag_update |= ED_node_is_simulation(snode);
+
if (found) {
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
snode_notify(C, snode);
@@ -1078,9 +1083,8 @@ static int cut_links_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+
+ return OPERATOR_CANCELLED;
}
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
@@ -1473,9 +1477,7 @@ static bool ed_node_link_conditions(ScrArea *area,
if (select) {
break;
}
- else {
- select = node;
- }
+ select = node;
}
}
/* only one selected */
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 06f568c80f3..90b824811d9 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -1097,9 +1097,7 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op)
if (node->type == active->type) {
break;
}
- else {
- node = NULL;
- }
+ node = NULL;
}
if (node) {
active = node;
@@ -1184,7 +1182,7 @@ static void node_find_update_fn(const struct bContext *C,
else {
BLI_strncpy(name, node->name, 256);
}
- if (!UI_search_item_add(items, name, node, ICON_NONE, 0)) {
+ if (!UI_search_item_add(items, name, node, ICON_NONE, 0, 0)) {
break;
}
}
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 87b1f662b59..4f15cec8c84 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -71,9 +71,7 @@ static bool node_link_item_compare(bNode *node, NodeLinkItem *item)
if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
return (node->id == (ID *)item->ngroup);
}
- else {
- return true;
- }
+ return true;
}
static void node_link_item_apply(Main *bmain, bNode *node, NodeLinkItem *item)
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index e879e01ecc4..ce66740dc60 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -133,9 +133,7 @@ static int node_view_all_exec(bContext *C, wmOperator *op)
if (space_node_view_flag(C, snode, region, 0, smooth_viewtx)) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void NODE_OT_view_all(wmOperatorType *ot)
@@ -162,9 +160,7 @@ static int node_view_selected_exec(bContext *C, wmOperator *op)
if (space_node_view_flag(C, snode, region, NODE_SELECT, smooth_viewtx)) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void NODE_OT_view_selected(wmOperatorType *ot)
@@ -423,7 +419,7 @@ static void sample_draw(const bContext *C, ARegion *region, void *arg_info)
* And here we've got recursion in the comments tips...
*/
bool ED_space_node_color_sample(
- Main *bmain, SpaceNode *snode, ARegion *region, int mval[2], float r_col[3])
+ Main *bmain, SpaceNode *snode, ARegion *region, const int mval[2], float r_col[3])
{
void *lock;
Image *ima;
@@ -460,7 +456,7 @@ bool ED_space_node_color_sample(
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
- /* IB_PROFILE_NONE is default but infact its linear */
+ /* #IB_PROFILE_NONE is default but in fact its linear. */
copy_v3_v3(r_col, fp);
ret = true;
}
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 562aa6b078c..6d570001347 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -244,7 +244,7 @@ void snode_group_offset(SpaceNode *snode, float *x, float *y)
/* ******************** default callbacks for node space ***************** */
-static SpaceLink *node_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *node_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceNode *snode;
@@ -641,9 +641,7 @@ static bool node_ima_drop_poll(bContext *UNUSED(C),
/* rule might not work? */
return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
}
- else {
- return WM_drag_ID(drag, ID_IM) != NULL;
- }
+ return WM_drag_ID(drag, ID_IM) != NULL;
}
static bool node_mask_drop_poll(bContext *UNUSED(C),
@@ -787,7 +785,7 @@ static int node_context(const bContext *C, const char *member, bContextDataResul
CTX_data_dir_set(result, node_context_dir);
return 1;
}
- else if (CTX_data_equals(member, "selected_nodes")) {
+ if (CTX_data_equals(member, "selected_nodes")) {
bNode *node;
if (snode->edittree) {
@@ -800,7 +798,7 @@ static int node_context(const bContext *C, const char *member, bContextDataResul
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "active_node")) {
+ if (CTX_data_equals(member, "active_node")) {
if (snode->edittree) {
bNode *node = nodeGetActive(snode->edittree);
CTX_data_pointer_set(result, &snode->edittree->id, &RNA_Node, node);
@@ -809,7 +807,7 @@ static int node_context(const bContext *C, const char *member, bContextDataResul
CTX_data_type_set(result, CTX_DATA_TYPE_POINTER);
return 1;
}
- else if (CTX_data_equals(member, "node_previews")) {
+ if (CTX_data_equals(member, "node_previews")) {
if (snode->nodetree) {
CTX_data_pointer_set(
result, &snode->nodetree->id, &RNA_NodeInstanceHash, snode->nodetree->previews);
@@ -818,19 +816,19 @@ static int node_context(const bContext *C, const char *member, bContextDataResul
CTX_data_type_set(result, CTX_DATA_TYPE_POINTER);
return 1;
}
- else if (CTX_data_equals(member, "material")) {
+ if (CTX_data_equals(member, "material")) {
if (snode->id && GS(snode->id->name) == ID_MA) {
CTX_data_id_pointer_set(result, snode->id);
}
return 1;
}
- else if (CTX_data_equals(member, "light")) {
+ if (CTX_data_equals(member, "light")) {
if (snode->id && GS(snode->id->name) == ID_LA) {
CTX_data_id_pointer_set(result, snode->id);
}
return 1;
}
- else if (CTX_data_equals(member, "world")) {
+ if (CTX_data_equals(member, "world")) {
if (snode->id && GS(snode->id->name) == ID_WO) {
CTX_data_id_pointer_set(result, snode->id);
}
@@ -956,7 +954,7 @@ void ED_spacetype_node(void)
st->spaceid = SPACE_NODE;
strncpy(st->name, "Node", BKE_ST_MAXNAME);
- st->new = node_new;
+ st->create = node_create;
st->free = node_free;
st->init = node_init;
st->duplicate = node_duplicate;
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 131491fcc40..0964e0c753e 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -70,7 +70,7 @@ bool outliner_is_collection_tree_element(const TreeElement *te)
TSE_VIEW_COLLECTION_BASE)) {
return true;
}
- else if (tselem->type == 0 && te->idcode == ID_GR) {
+ if (tselem->type == 0 && te->idcode == ID_GR) {
return true;
}
@@ -89,11 +89,11 @@ Collection *outliner_collection_from_tree_element(const TreeElement *te)
LayerCollection *lc = te->directdata;
return lc->collection;
}
- else if (ELEM(tselem->type, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
+ if (ELEM(tselem->type, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
Scene *scene = (Scene *)tselem->id;
return scene->master_collection;
}
- else if (tselem->type == 0 && te->idcode == ID_GR) {
+ if (tselem->type == 0 && te->idcode == ID_GR) {
return (Collection *)tselem->id;
}
@@ -338,7 +338,7 @@ void outliner_collection_delete(
skip = true;
break;
}
- else if (parent->flag & COLLECTION_IS_MASTER) {
+ if (parent->flag & COLLECTION_IS_MASTER) {
Scene *parent_scene = BKE_collection_master_scene_search(bmain, parent);
if (ID_IS_LINKED(parent_scene)) {
skip = true;
@@ -717,7 +717,7 @@ static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op))
GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- while (BKE_collection_find_cycle(active_lc->collection, collection)) {
+ while (BKE_collection_cycle_find(active_lc->collection, collection)) {
active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
}
}
@@ -1194,7 +1194,7 @@ static bool collection_flag_poll(bContext *C, bool clear, int flag)
if (clear && (collection->flag & flag)) {
return true;
}
- else if (!clear && !(collection->flag & flag)) {
+ if (!clear && !(collection->flag & flag)) {
return true;
}
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index 70a628eead0..5baaef958fa 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -123,9 +123,7 @@ static ID *outliner_ID_drop_find(bContext *C, const wmEvent *event, short idcode
if (te && te->idcode == idcode && tselem->type == 0) {
return tselem->id;
}
- else {
- return NULL;
- }
+ return NULL;
}
/* Find tree element to drop into, with additional before and after reorder support. */
@@ -154,44 +152,35 @@ static TreeElement *outliner_drop_insert_find(bContext *C,
*r_insert_type = TE_INSERT_INTO;
return te_hovered;
}
- else {
- *r_insert_type = TE_INSERT_BEFORE;
- return te_hovered->subtree.first;
- }
+ *r_insert_type = TE_INSERT_BEFORE;
+ return te_hovered->subtree.first;
}
- else {
- *r_insert_type = TE_INSERT_AFTER;
- return te_hovered;
- }
- }
- else if (view_mval[1] > (te_hovered->ys + (3 * margin))) {
- *r_insert_type = TE_INSERT_BEFORE;
+ *r_insert_type = TE_INSERT_AFTER;
return te_hovered;
}
- else {
- *r_insert_type = TE_INSERT_INTO;
+ if (view_mval[1] > (te_hovered->ys + (3 * margin))) {
+ *r_insert_type = TE_INSERT_BEFORE;
return te_hovered;
}
+ *r_insert_type = TE_INSERT_INTO;
+ return te_hovered;
}
- else {
- /* Mouse doesn't hover any item (ignoring x-axis),
- * so it's either above list bounds or below. */
- TreeElement *first = soops->tree.first;
- TreeElement *last = soops->tree.last;
- if (view_mval[1] < last->ys) {
- *r_insert_type = TE_INSERT_AFTER;
- return last;
- }
- else if (view_mval[1] > (first->ys + UI_UNIT_Y)) {
- *r_insert_type = TE_INSERT_BEFORE;
- return first;
- }
- else {
- BLI_assert(0);
- return NULL;
- }
+ /* Mouse doesn't hover any item (ignoring x-axis),
+ * so it's either above list bounds or below. */
+ TreeElement *first = soops->tree.first;
+ TreeElement *last = soops->tree.last;
+
+ if (view_mval[1] < last->ys) {
+ *r_insert_type = TE_INSERT_AFTER;
+ return last;
+ }
+ if (view_mval[1] > (first->ys + UI_UNIT_Y)) {
+ *r_insert_type = TE_INSERT_BEFORE;
+ return first;
}
+ BLI_assert(0);
+ return NULL;
}
static Collection *outliner_collection_from_tree_element_and_parents(TreeElement *te,
@@ -270,9 +259,7 @@ static bool parent_drop_allowed(TreeElement *te, Object *potential_child)
}
return false;
}
- else {
- return true;
- }
+ return true;
}
static bool allow_parenting_without_modifier_key(SpaceOutliner *soops)
@@ -650,7 +637,7 @@ static Collection *collection_parent_from_ID(ID *id)
if (GS(id->name) == ID_SCE) {
return ((Scene *)id)->master_collection;
}
- else if (GS(id->name) == ID_GR) {
+ if (GS(id->name) == ID_GR) {
return (Collection *)id;
}
@@ -772,12 +759,10 @@ static bool collection_drop_poll(bContext *C,
}
return true;
}
- else {
- if (changed) {
- ED_region_tag_redraw_no_rebuild(region);
- }
- return false;
+ if (changed) {
+ ED_region_tag_redraw_no_rebuild(region);
}
+ return false;
}
static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
@@ -873,6 +858,8 @@ void OUTLINER_OT_collection_drop(wmOperatorType *ot)
/* ********************* Outliner Drag Operator ******************** */
+#define OUTLINER_DRAG_SCOLL_OUTSIDE_PAD 7 /* In UI units */
+
static TreeElement *outliner_item_drag_element_find(SpaceOutliner *soops,
ARegion *region,
const wmEvent *event)
@@ -907,8 +894,16 @@ static int outliner_item_drag_drop_invoke(bContext *C,
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
- /* Scroll view when dragging near edges */
- WM_operator_name_call(C, "VIEW2D_OT_edge_pan", WM_OP_INVOKE_DEFAULT, NULL);
+ /* Scroll the view when dragging near edges, but not
+ * when the drag goes too far outside the region. */
+ {
+ wmOperatorType *ot = WM_operatortype_find("VIEW2D_OT_edge_pan", true);
+ PointerRNA op_ptr;
+ WM_operator_properties_create_ptr(&op_ptr, ot);
+ RNA_int_set(&op_ptr, "outside_padding", OUTLINER_DRAG_SCOLL_OUTSIDE_PAD);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_ptr);
+ WM_operator_properties_free(&op_ptr);
+ }
wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
@@ -1008,6 +1003,8 @@ void OUTLINER_OT_item_drag_drop(wmOperatorType *ot)
ot->poll = ED_operator_outliner_active;
}
+#undef OUTLINER_DRAG_SCOLL_OUTSIDE_PAD
+
/* *************************** Drop Boxes ************************** */
/* region dropbox definition */
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 6f5f1294167..a45b415b629 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -80,8 +80,8 @@
#include "outliner_intern.h"
-/* disable - this is far too slow - campbell */
-// #define USE_GROUP_SELECT
+/* Disable - this is far too slow - campbell. */
+/* #define USE_GROUP_SELECT */
/* ****************************************************** */
/* Tree Size Functions */
@@ -173,12 +173,12 @@ static void restrictbutton_recursive_bone(Bone *bone_parent, int flag, bool set_
}
}
-static void restrictbutton_r_lay_cb(bContext *C, void *poin, void *UNUSED(poin2))
+static void restrictbutton_r_lay_fn(bContext *C, void *poin, void *UNUSED(poin2))
{
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, poin);
}
-static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *UNUSED(poin2))
+static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void *UNUSED(poin2))
{
Bone *bone = (Bone *)poin;
@@ -187,7 +187,7 @@ static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *UNU
}
}
-static void restrictbutton_bone_select_cb(bContext *C, void *UNUSED(poin), void *poin2)
+static void restrictbutton_bone_select_fn(bContext *C, void *UNUSED(poin), void *poin2)
{
Bone *bone = (Bone *)poin2;
if (bone->flag & BONE_UNSELECTABLE) {
@@ -201,7 +201,7 @@ static void restrictbutton_bone_select_cb(bContext *C, void *UNUSED(poin), void
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
-static void restrictbutton_ebone_select_cb(bContext *C, void *UNUSED(poin), void *poin2)
+static void restrictbutton_ebone_select_fn(bContext *C, void *UNUSED(poin), void *poin2)
{
EditBone *ebone = (EditBone *)poin2;
@@ -217,7 +217,7 @@ static void restrictbutton_ebone_select_cb(bContext *C, void *UNUSED(poin), void
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
-static void restrictbutton_ebone_visibility_cb(bContext *C, void *UNUSED(poin), void *poin2)
+static void restrictbutton_ebone_visibility_fn(bContext *C, void *UNUSED(poin), void *poin2)
{
EditBone *ebone = (EditBone *)poin2;
if (ebone->flag & BONE_HIDDEN_A) {
@@ -231,7 +231,7 @@ static void restrictbutton_ebone_visibility_cb(bContext *C, void *UNUSED(poin),
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
-static void restrictbutton_gp_layer_flag_cb(bContext *C, void *poin, void *UNUSED(poin2))
+static void restrictbutton_gp_layer_flag_fn(bContext *C, void *poin, void *UNUSED(poin2))
{
ID *id = (ID *)poin;
@@ -253,7 +253,7 @@ static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void
}
}
-static void outliner_object_set_flag_recursive_cb(bContext *C,
+static void outliner_object_set_flag_recursive_fn(bContext *C,
Base *base,
Object *ob,
const char *propname)
@@ -313,21 +313,21 @@ static void outliner_object_set_flag_recursive_cb(bContext *C,
/**
* Object properties.
* */
-static void outliner__object_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
+static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
Object *ob = poin;
char *propname = poin2;
- outliner_object_set_flag_recursive_cb(C, NULL, ob, propname);
+ outliner_object_set_flag_recursive_fn(C, NULL, ob, propname);
}
/**
* Base properties.
* */
-static void outliner__base_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
+static void outliner__base_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
Base *base = poin;
char *propname = poin2;
- outliner_object_set_flag_recursive_cb(C, base, NULL, propname);
+ outliner_object_set_flag_recursive_fn(C, base, NULL, propname);
}
/** Create either a RNA_LayerCollection or a RNA_Collection pointer. */
@@ -568,7 +568,7 @@ void outliner_collection_isolate_flag(Scene *scene,
}
}
-static void outliner_collection_set_flag_recursive_cb(bContext *C,
+static void outliner_collection_set_flag_recursive_fn(bContext *C,
LayerCollection *layer_collection,
Collection *collection,
const char *propname)
@@ -632,24 +632,24 @@ static void outliner_collection_set_flag_recursive_cb(bContext *C,
* Layer collection properties called from the ViewLayer mode.
* Change the (non-excluded) collection children, and the objects nested to them all.
*/
-static void view_layer__layer_collection_set_flag_recursive_cb(bContext *C,
+static void view_layer__layer_collection_set_flag_recursive_fn(bContext *C,
void *poin,
void *poin2)
{
LayerCollection *layer_collection = poin;
char *propname = poin2;
- outliner_collection_set_flag_recursive_cb(C, layer_collection, NULL, propname);
+ outliner_collection_set_flag_recursive_fn(C, layer_collection, NULL, propname);
}
/**
* Collection properties called from the ViewLayer mode.
* Change the (non-excluded) collection children, and the objects nested to them all.
*/
-static void view_layer__collection_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
+static void view_layer__collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
LayerCollection *layer_collection = poin;
char *propname = poin2;
- outliner_collection_set_flag_recursive_cb(
+ outliner_collection_set_flag_recursive_fn(
C, layer_collection, layer_collection->collection, propname);
}
@@ -657,14 +657,14 @@ static void view_layer__collection_set_flag_recursive_cb(bContext *C, void *poin
* Collection properties called from the Scenes mode.
* Change the collection children but no objects.
*/
-static void scenes__collection_set_flag_recursive_cb(bContext *C, void *poin, void *poin2)
+static void scenes__collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
{
Collection *collection = poin;
char *propname = poin2;
- outliner_collection_set_flag_recursive_cb(C, NULL, collection, propname);
+ outliner_collection_set_flag_recursive_fn(C, NULL, collection, propname);
}
-static void namebutton_cb(bContext *C, void *tsep, char *oldname)
+static void namebutton_fn(bContext *C, void *tsep, char *oldname)
{
Main *bmain = CTX_data_main(C);
SpaceOutliner *soops = CTX_wm_space_outliner(C);
@@ -731,7 +731,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
else {
switch (tselem->type) {
case TSE_DEFGROUP:
- BKE_object_defgroup_unique_name(te->directdata, (Object *)tselem->id); // id = object
+ BKE_object_defgroup_unique_name(te->directdata, (Object *)tselem->id); /* id = object. */
break;
case TSE_NLA_ACTION:
BLI_libblock_ensure_unique_name(bmain, tselem->id->name);
@@ -790,7 +790,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
break;
}
case TSE_POSEGRP: {
- Object *ob = (Object *)tselem->id; // id = object
+ Object *ob = (Object *)tselem->id; /* id = object. */
bActionGroup *grp = te->directdata;
BLI_uniquename(&ob->pose->agroups,
@@ -809,7 +809,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
/* always make layer active */
BKE_gpencil_layer_active_set(gpd, gpl);
- // XXX: name needs translation stuff
+ /* XXX: name needs translation stuff. */
BLI_uniquename(
&gpd->layers, gpl, "GP Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
@@ -1073,7 +1073,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
0,
0,
TIP_("Use view layer for rendering"));
- UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
+ UI_but_func_set(bt, restrictbutton_r_lay_fn, tselem->id, NULL);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
}
@@ -1111,7 +1111,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
TIP_("Temporarily hide in viewport\n"
"* Shift to set children"));
UI_but_func_set(
- bt, outliner__base_set_flag_recursive_cb, base, (void *)"hide_viewport");
+ bt, outliner__base_set_flag_recursive_fn, base, (void *)"hide_viewport");
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
if (!props_active.base_hide_viewport) {
UI_but_flag_enable(bt, UI_BUT_INACTIVE);
@@ -1137,7 +1137,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
-1,
TIP_("Disable selection in viewport\n"
"* Shift to set children"));
- UI_but_func_set(bt, outliner__object_set_flag_recursive_cb, ob, (char *)"hide_select");
+ UI_but_func_set(bt, outliner__object_set_flag_recursive_fn, ob, (char *)"hide_select");
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
if (!props_active.object_hide_select) {
UI_but_flag_enable(bt, UI_BUT_INACTIVE);
@@ -1162,7 +1162,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
-1,
TIP_("Globally disable in viewports\n"
"* Shift to set children"));
- UI_but_func_set(bt, outliner__object_set_flag_recursive_cb, ob, (void *)"hide_viewport");
+ UI_but_func_set(bt, outliner__object_set_flag_recursive_fn, ob, (void *)"hide_viewport");
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
if (!props_active.object_hide_viewport) {
UI_but_flag_enable(bt, UI_BUT_INACTIVE);
@@ -1187,7 +1187,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
-1,
TIP_("Globally disable in renders\n"
"* Shift to set children"));
- UI_but_func_set(bt, outliner__object_set_flag_recursive_cb, ob, (char *)"hide_render");
+ UI_but_func_set(bt, outliner__object_set_flag_recursive_fn, ob, (char *)"hide_render");
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
if (!props_active.object_hide_render) {
UI_but_flag_enable(bt, UI_BUT_INACTIVE);
@@ -1301,7 +1301,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
-1,
-1,
TIP_("Restrict visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_bone_visibility_cb, bone, NULL);
+ UI_but_func_set(bt, restrictbutton_bone_visibility_fn, bone, NULL);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
}
@@ -1322,7 +1322,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
0,
0,
TIP_("Restrict selection in the 3D View"));
- UI_but_func_set(bt, restrictbutton_bone_select_cb, ob->data, bone);
+ UI_but_func_set(bt, restrictbutton_bone_select_fn, ob->data, bone);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
}
@@ -1346,7 +1346,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
0,
0,
TIP_("Restrict visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
+ UI_but_func_set(bt, restrictbutton_ebone_visibility_fn, NULL, ebone);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
}
@@ -1367,7 +1367,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
0,
0,
TIP_("Restrict selection in the 3D View"));
- UI_but_func_set(bt, restrictbutton_ebone_select_cb, NULL, ebone);
+ UI_but_func_set(bt, restrictbutton_ebone_select_fn, NULL, ebone);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
}
@@ -1376,13 +1376,13 @@ static void outliner_draw_restrictbuts(uiBlock *block,
ID *id = tselem->id;
bGPDlayer *gpl = (bGPDlayer *)te->directdata;
- if (soops->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
+ if (soops->show_restrict_flags & SO_RESTRICT_HIDE) {
bt = uiDefIconButBitS(block,
UI_BTYPE_ICON_TOGGLE,
GP_LAYER_HIDE,
0,
ICON_HIDE_OFF,
- (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
+ (int)(region->v2d.cur.xmax - restrict_offsets.hide),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
@@ -1392,7 +1392,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
0,
0,
TIP_("Restrict visibility in the 3D View"));
- UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_fn, id, gpl);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE);
}
@@ -1413,7 +1413,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
0,
0,
TIP_("Restrict editing of strokes and keyframes in this layer"));
- UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, id, gpl);
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_fn, id, gpl);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
}
@@ -1450,7 +1450,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
"* Ctrl to isolate collection\n"
"* Shift to set inside collections and objects"));
UI_but_func_set(bt,
- view_layer__layer_collection_set_flag_recursive_cb,
+ view_layer__layer_collection_set_flag_recursive_fn,
layer_collection,
(char *)"hide_viewport");
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
@@ -1479,7 +1479,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
"* Ctrl to isolate collection\n"
"* Shift to set inside collections"));
UI_but_func_set(bt,
- view_layer__layer_collection_set_flag_recursive_cb,
+ view_layer__layer_collection_set_flag_recursive_fn,
layer_collection,
(char *)"holdout");
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
@@ -1510,7 +1510,7 @@ static void outliner_draw_restrictbuts(uiBlock *block,
"* Ctrl to isolate collection\n"
"* Shift to set inside collections"));
UI_but_func_set(bt,
- view_layer__layer_collection_set_flag_recursive_cb,
+ view_layer__layer_collection_set_flag_recursive_fn,
layer_collection,
(char *)"indirect_only");
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
@@ -1542,13 +1542,13 @@ static void outliner_draw_restrictbuts(uiBlock *block,
"* Shift to set inside collections and objects"));
if (layer_collection != NULL) {
UI_but_func_set(bt,
- view_layer__collection_set_flag_recursive_cb,
+ view_layer__collection_set_flag_recursive_fn,
layer_collection,
(char *)"hide_viewport");
}
else {
UI_but_func_set(bt,
- scenes__collection_set_flag_recursive_cb,
+ scenes__collection_set_flag_recursive_fn,
collection,
(char *)"hide_viewport");
}
@@ -1579,13 +1579,13 @@ static void outliner_draw_restrictbuts(uiBlock *block,
"* Shift to set inside collections and objects"));
if (layer_collection != NULL) {
UI_but_func_set(bt,
- view_layer__collection_set_flag_recursive_cb,
+ view_layer__collection_set_flag_recursive_fn,
layer_collection,
(char *)"hide_render");
}
else {
UI_but_func_set(
- bt, scenes__collection_set_flag_recursive_cb, collection, (char *)"hide_render");
+ bt, scenes__collection_set_flag_recursive_fn, collection, (char *)"hide_render");
}
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
if (!props_active.collection_hide_render) {
@@ -1614,13 +1614,13 @@ static void outliner_draw_restrictbuts(uiBlock *block,
"* Shift to set inside collections and objects"));
if (layer_collection != NULL) {
UI_but_func_set(bt,
- view_layer__collection_set_flag_recursive_cb,
+ view_layer__collection_set_flag_recursive_fn,
layer_collection,
(char *)"hide_select");
}
else {
UI_but_func_set(
- bt, scenes__collection_set_flag_recursive_cb, collection, (char *)"hide_select");
+ bt, scenes__collection_set_flag_recursive_fn, collection, (char *)"hide_select");
}
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
if (!props_active.collection_hide_select) {
@@ -1869,7 +1869,7 @@ static void outliner_buttons(const bContext *C,
0,
0,
"");
- UI_but_func_rename_set(bt, namebutton_cb, tselem);
+ UI_but_func_rename_set(bt, namebutton_fn, tselem);
/* returns false if button got removed */
if (false == UI_but_active_only(C, region, block, bt)) {
@@ -2816,13 +2816,11 @@ int tree_element_id_type_to_index(TreeElement *te)
if (id_index < INDEX_ID_OB) {
return id_index;
}
- else if (id_index == INDEX_ID_OB) {
+ if (id_index == INDEX_ID_OB) {
const Object *ob = (Object *)tselem->id;
return INDEX_ID_OB + ob->type;
}
- else {
- return id_index + OB_TYPE_MAX;
- }
+ return id_index + OB_TYPE_MAX;
}
typedef struct MergedIconRow {
@@ -3071,7 +3069,7 @@ static void outliner_draw_tree_element(bContext *C,
icon_border);
GPU_blend(true); /* roundbox disables it */
- te->flag |= TE_ACTIVE; // for lookup in display hierarchies
+ te->flag |= TE_ACTIVE; /* For lookup in display hierarchies. */
}
if (tselem->type == TSE_VIEW_COLLECTION_BASE) {
@@ -3082,7 +3080,7 @@ static void outliner_draw_tree_element(bContext *C,
/* open/close icon, only when sublevels, except for scene */
int icon_x = startx;
- // icons a bit higher
+ /* Icons a bit higher. */
if (TSELEM_OPEN(tselem, soops)) {
UI_icon_draw_alpha((float)icon_x + 2 * ufac,
(float)*starty + 1 * ufac,
@@ -3489,7 +3487,7 @@ static void outliner_draw_tree(bContext *C,
int starty, startx;
GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); // only once
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); /* Only once. */
if (soops->outlinevis == SO_DATA_API) {
/* struct marks */
@@ -3512,13 +3510,12 @@ static void outliner_draw_tree(bContext *C,
GPU_scissor(0, 0, mask_x, region->winy);
}
- // gray hierarchy lines
-
+ /* Gray hierarchy lines. */
starty = (int)region->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET;
startx = UI_UNIT_X / 2 - (U.pixelsize + 1) / 2;
outliner_draw_hierarchy_lines(soops, &soops->tree, startx, &starty);
- // items themselves
+ /* Items themselves. */
starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
startx = 0;
LISTBASE_FOREACH (TreeElement *, te, &soops->tree) {
@@ -3590,9 +3587,7 @@ static int outliner_width(SpaceOutliner *soops, int max_tree_width, float restri
if (soops->outlinevis == SO_DATA_API) {
return outliner_data_api_buttons_start_x(max_tree_width) + OL_RNA_COL_SIZEX + 10 * UI_DPI_FAC;
}
- else {
- return max_tree_width + restrict_column_width;
- }
+ return max_tree_width + restrict_column_width;
}
static void outliner_update_viewable_area(ARegion *region,
@@ -3625,7 +3620,7 @@ void draw_outliner(const bContext *C)
TreeViewContext tvc;
outliner_viewcontext_init(C, &tvc);
- outliner_build_tree(mainvar, tvc.scene, tvc.view_layer, soops, region); // always
+ outliner_build_tree(mainvar, tvc.scene, tvc.view_layer, soops, region); /* Always. */
/* If global sync select is dirty, flag other outliners */
if (ED_outliner_select_sync_is_dirty(C)) {
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index bee8b28e658..4fe3d5b0df7 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -500,14 +500,14 @@ static void id_delete(bContext *C, ReportList *reports, TreeElement *te, TreeSto
BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked id '%s'", id->name);
return;
}
- else if (BKE_library_ID_is_indirectly_used(bmain, id) && ID_REAL_USERS(id) <= 1) {
+ if (BKE_library_ID_is_indirectly_used(bmain, id) && ID_REAL_USERS(id) <= 1) {
BKE_reportf(reports,
RPT_WARNING,
"Cannot delete id '%s', indirectly used data-blocks need at least one user",
id->name);
return;
}
- else if (te->idcode == ID_WS) {
+ if (te->idcode == ID_WS) {
BKE_workspace_id_tag_all_visible(bmain, LIB_TAG_DOIT);
if (id->tag & LIB_TAG_DOIT) {
BKE_reportf(
@@ -947,12 +947,10 @@ static int outliner_lib_relocate_invoke_do(
((Library *)tselem->id)->filepath_abs);
return OPERATOR_CANCELLED;
}
- else {
- wmOperatorType *ot = WM_operatortype_find(
- reload ? "WM_OT_lib_reload" : "WM_OT_lib_relocate", false);
- return lib_relocate(C, te, tselem, ot, reload);
- }
+ wmOperatorType *ot = WM_operatortype_find(reload ? "WM_OT_lib_reload" : "WM_OT_lib_relocate",
+ false);
+ return lib_relocate(C, te, tselem, ot, reload);
}
}
else {
@@ -1477,7 +1475,7 @@ void OUTLINER_OT_scroll_page(wmOperatorType *ot)
/** \} */
-#if 0 // TODO: probably obsolete now with filtering?
+#if 0 /* TODO: probably obsolete now with filtering? */
/* -------------------------------------------------------------------- */
/** \name Search
@@ -1521,7 +1519,7 @@ static TreeElement *outliner_find_name(
static void outliner_find_panel(
Scene *UNUSED(scene), ARegion *region, SpaceOutliner *soops, int again, int flags)
{
- ReportList *reports = NULL; // CTX_wm_reports(C);
+ ReportList *reports = NULL; /* CTX_wm_reports(C); */
TreeElement *te = NULL;
TreeElement *last_find;
TreeStoreElem *tselem;
@@ -1548,10 +1546,10 @@ static void outliner_find_panel(
else {
/* pop up panel - no previous, or user didn't want search after previous */
name[0] = '\0';
- // XXX if (sbutton(name, 0, sizeof(name) - 1, "Find: ") && name[0]) {
- // te = outliner_find_name(soops, &soops->tree, name, flags, NULL, &prevFound);
- // }
- // else return; /* XXX RETURN! XXX */
+ /* XXX if (sbutton(name, 0, sizeof(name) - 1, "Find: ") && name[0]) { */
+ /* te = outliner_find_name(soops, &soops->tree, name, flags, NULL, &prevFound); */
+ /* } */
+ /* else return; XXX RETURN! XXX */
}
/* do selection and reveal */
@@ -1766,7 +1764,7 @@ void OUTLINER_OT_show_hierarchy(wmOperatorType *ot)
/* callbacks */
ot->exec = outliner_show_hierarchy_exec;
- ot->poll = ED_operator_outliner_active; // TODO: shouldn't be allowed in RNA views...
+ ot->poll = ED_operator_outliner_active; /* TODO: shouldn't be allowed in RNA views... */
/* no undo or registry, UI option */
}
@@ -2052,7 +2050,7 @@ static int outliner_drivers_addsel_exec(bContext *C, wmOperator *op)
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
+ WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); /* XXX */
return OPERATOR_FINISHED;
}
@@ -2091,7 +2089,7 @@ static int outliner_drivers_deletesel_exec(bContext *C, wmOperator *op)
do_outliner_drivers_editop(soutliner, &soutliner->tree, op->reports, DRIVERS_EDITMODE_REMOVE);
/* send notifiers */
- WM_event_add_notifier(C, ND_KEYS, NULL); // XXX
+ WM_event_add_notifier(C, ND_KEYS, NULL); /* XXX */
return OPERATOR_FINISHED;
}
@@ -2128,8 +2126,8 @@ enum {
KEYINGSET_EDITMODE_REMOVE,
} /*eKeyingSet_EditModes*/;
-/* find the 'active' KeyingSet, and add if not found (if adding is allowed) */
-// TODO: should this be an API func?
+/* 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;
@@ -2144,8 +2142,8 @@ static KeyingSet *verify_active_keyingset(Scene *scene, short add)
ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
}
- /* add if none found */
- // XXX the default settings have yet to evolve
+ /* 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);
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index b6fff3a1022..05729414f91 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -21,8 +21,7 @@
* \ingroup spoutliner
*/
-#ifndef __OUTLINER_INTERN_H__
-#define __OUTLINER_INTERN_H__
+#pragma once
#include "RNA_types.h"
@@ -63,15 +62,15 @@ typedef TreeTraversalAction (*TreeTraversalFunc)(struct TreeElement *te, void *c
typedef struct TreeElement {
struct TreeElement *next, *prev, *parent;
ListBase subtree;
- int xs, ys; // do selection
- TreeStoreElem *store_elem; // element in tree store
- short flag; // flag for non-saved stuff
- short index; // index for data arrays
- short idcode; // from TreeStore id
- short xend; // width of item display, for select
+ int xs, ys; /* Do selection. */
+ TreeStoreElem *store_elem; /* Element in tree store. */
+ short flag; /* Flag for non-saved stuff. */
+ short index; /* Index for data arrays. */
+ short idcode; /* From TreeStore id. */
+ short xend; /* Width of item display, for select. */
const char *name;
- void *directdata; // Armature Bones, Base, Sequence, Strip...
- PointerRNA rnaptr; // RNA Pointer
+ void *directdata; /* Armature Bones, Base, Sequence, Strip... */
+ PointerRNA rnaptr; /* RNA Pointer. */
} TreeElement;
typedef struct TreeElementIcon {
@@ -517,5 +516,3 @@ void outliner_scroll_view(struct ARegion *region, int delta_y);
/* outliner_sync.c ---------------------------------------------- */
void outliner_sync_selection(const struct bContext *C, struct SpaceOutliner *soops);
-
-#endif /* __OUTLINER_INTERN_H__ */
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 8a408a41897..8bf05c3018a 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -455,7 +455,7 @@ static eOLDrawState tree_element_active_material(bContext *C,
/* we search for the object parent */
ob = (Object *)outliner_search_back(te, ID_OB);
- // note: ob->matbits can be NULL when a local object points to a library mesh.
+ /* 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 */
}
@@ -465,7 +465,7 @@ static eOLDrawState tree_element_active_material(bContext *C,
if (tes->idcode == ID_OB) {
if (set != OL_SETSEL_NONE) {
ob->actcol = te->index + 1;
- ob->matbits[te->index] = 1; // make ob material active too
+ ob->matbits[te->index] = 1; /* Make ob material active too. */
}
else {
if (ob->actcol == te->index + 1) {
@@ -479,7 +479,7 @@ static eOLDrawState tree_element_active_material(bContext *C,
else {
if (set != OL_SETSEL_NONE) {
ob->actcol = te->index + 1;
- ob->matbits[te->index] = 0; // make obdata material active too
+ ob->matbits[te->index] = 0; /* Make obdata material active too. */
}
else {
if (ob->actcol == te->index + 1) {
@@ -520,9 +520,7 @@ static eOLDrawState tree_element_active_camera(bContext *C,
return OL_DRAWSEL_NONE;
}
- else {
- return scene->camera == ob;
- }
+ return scene->camera == ob;
}
static eOLDrawState tree_element_active_world(bContext *C,
@@ -552,10 +550,7 @@ static eOLDrawState tree_element_active_world(bContext *C,
}
if (tep == NULL || tselem->id == (ID *)scene) {
- if (set != OL_SETSEL_NONE) {
- // XXX extern_set_butspace(F8KEY, 0);
- }
- else {
+ if (set == OL_SETSEL_NONE) {
return OL_DRAWSEL_NORMAL;
}
}
@@ -767,14 +762,14 @@ static void tree_element_active_ebone__sel(bContext *C, bArmature *arm, EditBone
if (sel) {
ebone->flag |= BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL;
arm->act_edbone = ebone;
- // flush to parent?
+ /* Flush to parent? */
if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
ebone->parent->flag |= BONE_TIPSEL;
}
}
else {
ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
- // flush to parent?
+ /* Flush to parent? */
if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
ebone->parent->flag &= ~BONE_TIPSEL;
}
@@ -842,8 +837,6 @@ static eOLDrawState tree_element_active_modifier(bContext *C,
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;
@@ -859,8 +852,6 @@ static eOLDrawState tree_element_active_psys(bContext *C,
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;
@@ -877,23 +868,11 @@ static int tree_element_active_constraint(bContext *C,
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;
}
-static eOLDrawState tree_element_active_text(bContext *UNUSED(C),
- Scene *UNUSED(scene),
- ViewLayer *UNUSED(sl),
- SpaceOutliner *UNUSED(soops),
- TreeElement *UNUSED(te),
- int UNUSED(set))
-{
- // XXX removed
- return OL_DRAWSEL_NONE;
-}
-
static eOLDrawState tree_element_active_pose(bContext *UNUSED(C),
Scene *UNUSED(scene),
ViewLayer *view_layer,
@@ -971,7 +950,7 @@ static eOLDrawState tree_element_active_sequence_dup(Scene *scene,
return OL_DRAWSEL_NONE;
}
- // XXX select_single_seq(seq, 1);
+ /* XXX select_single_seq(seq, 1); */
p = ed->seqbasep->first;
while (p) {
if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) {
@@ -979,8 +958,8 @@ static eOLDrawState tree_element_active_sequence_dup(Scene *scene,
continue;
}
- // if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name))
- // XXX select_single_seq(p, 0);
+ /* XXX: if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) select_single_seq(p,
+ * 0); */
p = p->next;
}
return OL_DRAWSEL_NONE;
@@ -1001,9 +980,7 @@ static eOLDrawState tree_element_active_keymap_item(bContext *UNUSED(C),
}
return OL_DRAWSEL_NORMAL;
}
- else {
- kmi->flag ^= KMI_INACTIVE;
- }
+ kmi->flag ^= KMI_INACTIVE;
return OL_DRAWSEL_NONE;
}
@@ -1075,8 +1052,6 @@ eOLDrawState tree_element_active(bContext *C,
return tree_element_active_material(C, tvc->scene, tvc->view_layer, te, set);
case ID_WO:
return tree_element_active_world(C, tvc->scene, tvc->view_layer, soops, te, set);
- case ID_TXT:
- return tree_element_active_text(C, tvc->scene, tvc->view_layer, soops, te, set);
case ID_CA:
return tree_element_active_camera(C, tvc->scene, tvc->view_layer, te, set);
}
@@ -1185,7 +1160,7 @@ static void do_outliner_item_activate_tree_element(bContext *C,
recursive && tselem->type == 0);
}
- if (tselem->type == 0) { // the lib blocks
+ if (tselem->type == 0) { /* The lib blocks. */
if (do_activate_data == false) {
/* Only select in outliner. */
}
@@ -1234,7 +1209,7 @@ static void do_outliner_item_activate_tree_element(bContext *C,
DEG_id_tag_update(&tvc->scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, tvc->scene);
}
- else { // rest of types
+ else { /* Rest of types. */
tree_element_active(C, tvc, soops, te, OL_SETSEL_NORMAL, false);
}
}
@@ -1397,7 +1372,7 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
else {
- /* The row may also contain children, if one is hovered we want this instead of current te */
+ /* The row may also contain children, if one is hovered we want this instead of current te. */
bool merged_elements = false;
TreeElement *activate_te = outliner_find_item_at_x_in_row(
soops, te, view_mval[0], &merged_elements);
@@ -1620,9 +1595,7 @@ static TreeElement *outliner_element_find_successor_in_parents(TreeElement *te)
te = successor->parent->next;
break;
}
- else {
- successor = successor->parent;
- }
+ successor = successor->parent;
}
return te;
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index c0632de1cd7..dae2ba32f09 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -54,6 +54,7 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_idtype.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_override.h"
@@ -542,7 +543,7 @@ static void merged_element_search_cb_recursive(
/* Don't allow duplicate named items */
if (UI_search_items_find_index(items, name) == -1) {
- if (!UI_search_item_add(items, name, te, iconid, 0)) {
+ if (!UI_search_item_add(items, name, te, iconid, 0, 0)) {
break;
}
}
@@ -699,8 +700,8 @@ static void outliner_object_delete_fn(bContext *C, ReportList *reports, Scene *s
reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", ob->id.name + 2);
return;
}
- else if (BKE_library_ID_is_indirectly_used(bmain, ob) && ID_REAL_USERS(ob) <= 1 &&
- ID_EXTRA_USERS(ob) == 0) {
+ if (BKE_library_ID_is_indirectly_used(bmain, ob) && ID_REAL_USERS(ob) <= 1 &&
+ ID_EXTRA_USERS(ob) == 0) {
BKE_reportf(reports,
RPT_WARNING,
"Cannot delete object '%s' from scene '%s', indirectly used objects need at "
@@ -739,26 +740,91 @@ static void id_local_cb(bContext *C,
}
}
-static void id_override_library_cb(bContext *C,
- ReportList *UNUSED(reports),
- Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
- TreeStoreElem *UNUSED(tsep),
- TreeStoreElem *tselem,
- void *UNUSED(user_data))
+typedef struct OutlinerLibOverrideData {
+ bool do_hierarchy;
+} OutlinerLibOverrideData;
+
+static void id_override_library_create_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *user_data)
{
- if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id)) {
+ BLI_assert(TSE_IS_REAL_ID(tselem));
+ ID *id_root = tselem->id;
+ OutlinerLibOverrideData *data = user_data;
+ const bool do_hierarchy = data->do_hierarchy;
+
+ if (ID_IS_OVERRIDABLE_LIBRARY(id_root) || (ID_IS_LINKED(id_root) && do_hierarchy)) {
Main *bmain = CTX_data_main(C);
+
+ id_root->tag |= LIB_TAG_DOIT;
+
/* For now, remapp all local usages of linked ID to local override one here. */
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, true);
- ID *override_id = BKE_lib_override_library_create_from_id(bmain, tselem->id, true);
- if (override_id != NULL) {
- BKE_main_id_clear_newpoins(bmain);
+ ID *id_iter;
+ FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+ if (ID_IS_LINKED(id_iter)) {
+ id_iter->tag &= ~LIB_TAG_DOIT;
+ }
+ else {
+ id_iter->tag |= LIB_TAG_DOIT;
+ }
}
+ FOREACH_MAIN_ID_END;
+
+ if (do_hierarchy) {
+ /* Tag all linked parents in tree hierarchy to be also overridden. */
+ while ((te = te->parent) != NULL) {
+ if (!TSE_IS_REAL_ID(te->store_elem)) {
+ continue;
+ }
+ if (!ID_IS_LINKED(te->store_elem->id)) {
+ break;
+ }
+ te->store_elem->id->tag |= LIB_TAG_DOIT;
+ }
+ BKE_lib_override_library_create(
+ bmain, CTX_data_scene(C), CTX_data_view_layer(C), id_root, NULL);
+ }
+ else if (ID_IS_OVERRIDABLE_LIBRARY(id_root)) {
+ BKE_lib_override_library_create_from_id(bmain, id_root, true);
+ }
+
+ BKE_main_id_clear_newpoins(bmain);
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
}
}
+static void id_override_library_reset_cb(bContext *C,
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *user_data)
+{
+ BLI_assert(TSE_IS_REAL_ID(tselem));
+ ID *id_root = tselem->id;
+ OutlinerLibOverrideData *data = user_data;
+ const bool do_hierarchy = data->do_hierarchy;
+
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
+ Main *bmain = CTX_data_main(C);
+
+ if (do_hierarchy) {
+ BKE_lib_override_library_id_hierarchy_reset(bmain, id_root);
+ }
+ else {
+ BKE_lib_override_library_id_reset(bmain, id_root);
+ }
+
+ WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ }
+}
+
static void id_fake_user_set_cb(bContext *UNUSED(C),
ReportList *UNUSED(reports),
Scene *UNUSED(scene),
@@ -801,11 +867,17 @@ static void id_select_linked_cb(bContext *C,
static void singleuser_action_cb(bContext *C,
ReportList *UNUSED(reports),
Scene *UNUSED(scene),
- TreeElement *UNUSED(te),
+ TreeElement *te,
TreeStoreElem *tsep,
TreeStoreElem *tselem,
void *UNUSED(user_data))
{
+ /* This callback runs for all selected elements, some of which may not be actions which results
+ * in a crash. */
+ if (te->idcode != ID_AC) {
+ return;
+ }
+
ID *id = tselem->id;
if (id) {
@@ -862,12 +934,12 @@ void outliner_do_object_operation_ex(bContext *C,
bool select_handled = false;
if (tselem->flag & TSE_SELECTED) {
if (tselem->type == 0 && te->idcode == ID_OB) {
- // when objects selected in other scenes... dunno if that should be allowed
+ /* When objects selected in other scenes... dunno if that should be allowed. */
Scene *scene_owner = (Scene *)outliner_search_back(te, ID_SCE);
if (scene_owner && scene_act != scene_owner) {
WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), scene_owner);
}
- /* important to use 'scene_owner' not scene_act else deleting objects can crash.
+ /* Important to use 'scene_owner' not scene_act else deleting objects can crash.
* only use 'scene_act' when 'scene_owner' is NULL, which can happen when the
* outliner isn't showing scenes: Visible Layer draw mode for eg. */
operation_cb(
@@ -1127,6 +1199,7 @@ static void modifier_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem
{
bContext *C = (bContext *)Carg;
Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
ModifierData *md = (ModifierData *)te->directdata;
Object *ob = (Object *)outliner_search_back(te, ID_OB);
@@ -1141,7 +1214,7 @@ static void modifier_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
}
else if (event == OL_MODIFIER_OP_DELETE) {
- ED_object_modifier_remove(NULL, bmain, ob, md);
+ ED_object_modifier_remove(NULL, bmain, scene, ob, md);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER | NA_REMOVED, ob);
te->store_elem->flag &= ~TSE_SELECTED;
}
@@ -1202,8 +1275,8 @@ static Base *outline_batch_delete_hierarchy(
base->object->id.name + 2);
return base_next;
}
- else if (BKE_library_ID_is_indirectly_used(bmain, object) && ID_REAL_USERS(object) <= 1 &&
- ID_EXTRA_USERS(object) == 0) {
+ if (BKE_library_ID_is_indirectly_used(bmain, object) && ID_REAL_USERS(object) <= 1 &&
+ ID_EXTRA_USERS(object) == 0) {
BKE_reportf(reports,
RPT_WARNING,
"Cannot delete object '%s' from scene '%s', indirectly used objects need at least "
@@ -1299,7 +1372,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
event = RNA_enum_get(op->ptr, "type");
if (event == OL_OP_SELECT) {
- Scene *sce = scene; // to be able to delete, scenes are set...
+ Scene *sce = scene; /* To be able to delete, scenes are set... */
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, object_select_cb);
if (scene != sce) {
WM_window_set_active_scene(bmain, C, win, sce);
@@ -1309,7 +1382,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
selection_changed = true;
}
else if (event == OL_OP_SELECT_HIERARCHY) {
- Scene *sce = scene; // to be able to delete, scenes are set...
+ Scene *sce = scene; /* To be able to delete, scenes are set... */
outliner_do_object_operation_ex(
C, op->reports, scene, soops, &soops->tree, object_select_hierarchy_cb, NULL, false);
if (scene != sce) {
@@ -1325,8 +1398,8 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
}
else if (event == OL_OP_REMAP) {
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
- /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth trick
- * does not work here). */
+ /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
+ * trick does not work here). */
}
else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, id_local_cb);
@@ -1506,7 +1579,10 @@ typedef enum eOutlinerIdOpTypes {
OUTLINER_IDOP_UNLINK,
OUTLINER_IDOP_LOCAL,
- OUTLINER_IDOP_OVERRIDE_LIBRARY,
+ OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE,
+ OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY,
+ OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET,
+ OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY,
OUTLINER_IDOP_SINGLE,
OUTLINER_IDOP_DELETE,
OUTLINER_IDOP_REMAP,
@@ -1521,15 +1597,10 @@ typedef enum eOutlinerIdOpTypes {
OUTLINER_IDOP_SELECT_LINKED,
} eOutlinerIdOpTypes;
-// TODO: implement support for changing the ID-block used
+/* TODO: implement support for changing the ID-block used. */
static const EnumPropertyItem prop_id_op_types[] = {
{OUTLINER_IDOP_UNLINK, "UNLINK", 0, "Unlink", ""},
{OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""},
- {OUTLINER_IDOP_OVERRIDE_LIBRARY,
- "OVERRIDE_LIBRARY",
- 0,
- "Add Library Override",
- "Add a local override of this linked data-block"},
{OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
{OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""},
{OUTLINER_IDOP_REMAP,
@@ -1538,6 +1609,27 @@ static const EnumPropertyItem prop_id_op_types[] = {
"Remap Users",
"Make all users of selected data-blocks to use instead current (clicked) one"},
{0, "", 0, NULL, NULL},
+ {OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE,
+ "OVERRIDE_LIBRARY_CREATE",
+ 0,
+ "Add Library Override",
+ "Add a local override of this linked data-block"},
+ {OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY,
+ "OVERRIDE_LIBRARY_CREATE_HIERARCHY",
+ 0,
+ "Add Library Override Hierarchy",
+ "Add a local override of this linked data-block, and its hierarchy of dependencies"},
+ {OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET,
+ "OVERRIDE_LIBRARY_RESET",
+ 0,
+ "Reset Library Override",
+ "Reset this local override to its linked values"},
+ {OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY,
+ "OVERRIDE_LIBRARY_RESET_HIERARCHY",
+ 0,
+ "Reset Library Override Hierarchy",
+ "Reset this local override to its linked values, as well as its hierarchy of dependencies"},
+ {0, "", 0, NULL, NULL},
{OUTLINER_IDOP_COPY, "COPY", ICON_COPYDOWN, "Copy", ""},
{OUTLINER_IDOP_PASTE, "PASTE", ICON_PASTEDOWN, "Paste", ""},
{0, "", 0, NULL, NULL},
@@ -1561,8 +1653,12 @@ static bool outliner_id_operation_item_poll(bContext *C,
SpaceOutliner *soops = CTX_wm_space_outliner(C);
switch (enum_value) {
- case OUTLINER_IDOP_OVERRIDE_LIBRARY:
- return BKE_lib_override_library_is_enabled();
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE:
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY:
+ return true;
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET:
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY:
+ return true;
case OUTLINER_IDOP_SINGLE:
if (!soops || ELEM(soops->outlinevis, SO_SCENES, SO_VIEW_LAYER)) {
return true;
@@ -1675,13 +1771,52 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
ED_undo_push(C, "Localized Data");
break;
}
- case OUTLINER_IDOP_OVERRIDE_LIBRARY: {
- if (BKE_lib_override_library_is_enabled()) {
- /* make local */
- outliner_do_libdata_operation(
- C, op->reports, scene, soops, &soops->tree, id_override_library_cb, NULL);
- ED_undo_push(C, "Overridden Data");
- }
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE: {
+ /* make local */
+ outliner_do_libdata_operation(C,
+ op->reports,
+ scene,
+ soops,
+ &soops->tree,
+ id_override_library_create_cb,
+ &(OutlinerLibOverrideData){.do_hierarchy = false});
+ ED_undo_push(C, "Overridden Data");
+ break;
+ }
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY: {
+ /* make local */
+ outliner_do_libdata_operation(C,
+ op->reports,
+ scene,
+ soops,
+ &soops->tree,
+ id_override_library_create_cb,
+ &(OutlinerLibOverrideData){.do_hierarchy = true});
+ ED_undo_push(C, "Overridden Data Hierarchy");
+ break;
+ }
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET: {
+ /* make local */
+ outliner_do_libdata_operation(C,
+ op->reports,
+ scene,
+ soops,
+ &soops->tree,
+ id_override_library_reset_cb,
+ &(OutlinerLibOverrideData){.do_hierarchy = false});
+ ED_undo_push(C, "Reset Overridden Data");
+ break;
+ }
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY: {
+ /* make local */
+ outliner_do_libdata_operation(C,
+ op->reports,
+ scene,
+ soops,
+ &soops->tree,
+ id_override_library_reset_cb,
+ &(OutlinerLibOverrideData){.do_hierarchy = true});
+ ED_undo_push(C, "Reset Overridden Data Hierarchy");
break;
}
case OUTLINER_IDOP_SINGLE: {
@@ -1776,14 +1911,14 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
break;
default:
- // invalid - unhandled
+ /* 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;
@@ -1959,7 +2094,7 @@ static void actionset_id_cb(TreeElement *UNUSED(te),
/* "animation" entries case again */
BKE_animdata_set_action(NULL, tsep->id, act);
}
- // TODO: other cases not supported yet
+ /* TODO: other cases not supported yet. */
}
static int outliner_action_set_exec(bContext *C, wmOperator *op)
@@ -1983,7 +2118,7 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No valid action to add");
return OPERATOR_CANCELLED;
}
- else if (act->idroot == 0) {
+ if (act->idroot == 0) {
/* Hopefully in this case (i.e. library of userless actions),
* the user knows what they're doing. */
BKE_reportf(op->reports,
@@ -2031,7 +2166,7 @@ void OUTLINER_OT_action_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- // TODO: this would be nicer as an ID-pointer...
+ /* TODO: this would be nicer as an ID-pointer... */
prop = RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, "Action", "");
RNA_def_enum_funcs(prop, RNA_action_itemf);
RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
@@ -2055,8 +2190,8 @@ typedef enum eOutliner_AnimDataOps {
OUTLINER_ANIMOP_REFRESH_DRV,
OUTLINER_ANIMOP_CLEAR_DRV
- // OUTLINER_ANIMOP_COPY_DRIVERS,
- // OUTLINER_ANIMOP_PASTE_DRIVERS
+ /* OUTLINER_ANIMOP_COPY_DRIVERS, */
+ /* OUTLINER_ANIMOP_PASTE_DRIVERS */
} eOutliner_AnimDataOps;
static const EnumPropertyItem prop_animdata_op_types[] = {
@@ -2068,8 +2203,8 @@ static const EnumPropertyItem prop_animdata_op_types[] = {
{OUTLINER_ANIMOP_SET_ACT, "SET_ACT", 0, "Set Action", ""},
{OUTLINER_ANIMOP_CLEAR_ACT, "CLEAR_ACT", 0, "Unlink Action", ""},
{OUTLINER_ANIMOP_REFRESH_DRV, "REFRESH_DRIVERS", 0, "Refresh Drivers", ""},
- //{OUTLINER_ANIMOP_COPY_DRIVERS, "COPY_DRIVERS", 0, "Copy Drivers", ""},
- //{OUTLINER_ANIMOP_PASTE_DRIVERS, "PASTE_DRIVERS", 0, "Paste Drivers", ""},
+ /* {OUTLINER_ANIMOP_COPY_DRIVERS, "COPY_DRIVERS", 0, "Copy Drivers", ""}, */
+ /* {OUTLINER_ANIMOP_PASTE_DRIVERS, "PASTE_DRIVERS", 0, "Paste Drivers", ""}, */
{OUTLINER_ANIMOP_CLEAR_DRV, "CLEAR_DRIVERS", 0, "Clear Drivers", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -2125,7 +2260,7 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
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? */
+ /* ED_undo_push(C, "Refresh Drivers"); No undo needed - shouldn't have any impact? */
break;
case OUTLINER_ANIMOP_CLEAR_DRV:
@@ -2136,7 +2271,7 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
ED_undo_push(C, "Clear Drivers");
break;
- default: // invalid
+ default: /* Invalid. */
break;
}
@@ -2267,7 +2402,7 @@ void OUTLINER_OT_modifier_operation(wmOperatorType *ot)
/** \name Data Menu Operator
* \{ */
-// XXX: select linked is for RNA structs only
+/* XXX: select linked is for RNA structs only. */
static const EnumPropertyItem prop_data_op_types[] = {
{OL_DOP_SELECT, "SELECT", 0, "Select", ""},
{OL_DOP_DESELECT, "DESELECT", 0, "Deselect", ""},
@@ -2386,7 +2521,7 @@ static int outliner_operator_menu(bContext *C, const char *opname)
static int do_outliner_operation_event(
bContext *C, ARegion *region, SpaceOutliner *soops, TreeElement *te, const float mval[2])
{
- ReportList *reports = CTX_wm_reports(C); // XXX...
+ 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;
@@ -2414,32 +2549,29 @@ static int do_outliner_operation_event(
BKE_report(reports, RPT_WARNING, "Mixed selection");
return OPERATOR_CANCELLED;
}
- else {
- return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
- }
+ return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
}
- else if (objectlevel) {
+ if (objectlevel) {
WM_menu_name_call(C, "OUTLINER_MT_object", WM_OP_INVOKE_REGION_WIN);
return OPERATOR_FINISHED;
}
- else if (idlevel) {
+ if (idlevel) {
if (idlevel == -1 || datalevel) {
BKE_report(reports, RPT_WARNING, "Mixed selection");
return OPERATOR_CANCELLED;
}
- else {
- switch (idlevel) {
- case ID_GR:
- WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- break;
- case ID_LI:
- return outliner_operator_menu(C, "OUTLINER_OT_lib_operation");
- break;
- default:
- return outliner_operator_menu(C, "OUTLINER_OT_id_operation");
- break;
- }
+
+ switch (idlevel) {
+ case ID_GR:
+ WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ break;
+ case ID_LI:
+ return outliner_operator_menu(C, "OUTLINER_OT_lib_operation");
+ break;
+ default:
+ return outliner_operator_menu(C, "OUTLINER_OT_id_operation");
+ break;
}
}
else if (datalevel) {
@@ -2447,35 +2579,32 @@ static int do_outliner_operation_event(
BKE_report(reports, RPT_WARNING, "Mixed selection");
return OPERATOR_CANCELLED;
}
- else {
- if (datalevel == TSE_ANIM_DATA) {
- return outliner_operator_menu(C, "OUTLINER_OT_animdata_operation");
- }
- else if (datalevel == TSE_DRIVER_BASE) {
- /* do nothing... no special ops needed yet */
- return OPERATOR_CANCELLED;
- }
- else if (datalevel == TSE_LAYER_COLLECTION) {
- WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- }
- else if (ELEM(datalevel, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
- WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
- return OPERATOR_FINISHED;
- }
- else if (datalevel == TSE_ID_BASE) {
- /* do nothing... there are no ops needed here yet */
- }
- else if (datalevel == TSE_CONSTRAINT) {
- return outliner_operator_menu(C, "OUTLINER_OT_constraint_operation");
- }
- else if (datalevel == TSE_MODIFIER) {
- return outliner_operator_menu(C, "OUTLINER_OT_modifier_operation");
- }
- else {
- return outliner_operator_menu(C, "OUTLINER_OT_data_operation");
- }
+ if (datalevel == TSE_ANIM_DATA) {
+ return outliner_operator_menu(C, "OUTLINER_OT_animdata_operation");
+ }
+ if (datalevel == TSE_DRIVER_BASE) {
+ /* do nothing... no special ops needed yet */
+ return OPERATOR_CANCELLED;
+ }
+ if (datalevel == TSE_LAYER_COLLECTION) {
+ WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ }
+ if (ELEM(datalevel, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
+ WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
+ return OPERATOR_FINISHED;
+ }
+ if (datalevel == TSE_ID_BASE) {
+ /* do nothing... there are no ops needed here yet */
+ return 0;
+ }
+ if (datalevel == TSE_CONSTRAINT) {
+ return outliner_operator_menu(C, "OUTLINER_OT_constraint_operation");
+ }
+ if (datalevel == TSE_MODIFIER) {
+ return outliner_operator_menu(C, "OUTLINER_OT_modifier_operation");
}
+ return outliner_operator_menu(C, "OUTLINER_OT_data_operation");
}
return 0;
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index bc272431e3a..e1d92c551c3 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -340,7 +340,7 @@ static void outliner_add_scene_contents(SpaceOutliner *soops,
}
}
-// can be inlined if necessary
+/* Can be inlined if necessary. */
static void outliner_add_object_contents(SpaceOutliner *soops,
TreeElement *te,
TreeStoreElem *tselem,
@@ -351,7 +351,7 @@ static void outliner_add_object_contents(SpaceOutliner *soops,
}
outliner_add_element(
- soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this
+ 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);
@@ -378,12 +378,12 @@ static void outliner_add_object_contents(SpaceOutliner *soops,
pchan->temp = (void *)ten;
if (pchan->constraints.first) {
- // Object *target;
+ /* Object *target; */
bConstraint *con;
TreeElement *ten1;
TreeElement *tenla1 = outliner_add_element(
soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
- // char *str;
+ /* char *str; */
tenla1->name = IFACE_("Constraints");
for (con = pchan->constraints.first; con; con = con->next, const_index++) {
@@ -447,11 +447,11 @@ static void outliner_add_object_contents(SpaceOutliner *soops,
}
if (ob->constraints.first) {
- // Object *target;
+ /* Object *target; */
bConstraint *con;
TreeElement *ten;
TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
- // char *str;
+ /* char *str; */
int a;
tenla->name = IFACE_("Constraints");
@@ -535,7 +535,7 @@ static void outliner_add_object_contents(SpaceOutliner *soops,
}
}
-// can be inlined if necessary
+/* Can be inlined if necessary. */
static void outliner_add_id_contents(SpaceOutliner *soops,
TreeElement *te,
TreeStoreElem *tselem,
@@ -677,8 +677,8 @@ static void outliner_add_id_contents(SpaceOutliner *soops,
break;
}
case ID_AC: {
- // XXX do we want to be exposing the F-Curves here?
- // bAction *act = (bAction *)id;
+ /* XXX do we want to be exposing the F-Curves here? */
+ /* bAction *act = (bAction *)id; */
break;
}
case ID_AR: {
@@ -752,7 +752,7 @@ static void outliner_add_id_contents(SpaceOutliner *soops,
outliner_add_element(soops, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
}
- // TODO: base element for layers?
+ /* TODO: base element for layers? */
for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
outliner_add_element(soops, &te->subtree, gpl, te, TSE_GP_LAYER, a);
a++;
@@ -769,20 +769,23 @@ static void outliner_add_id_contents(SpaceOutliner *soops,
}
case ID_HA: {
Hair *hair = (Hair *)id;
- if (outliner_animdata_test(hair->adt))
+ if (outliner_animdata_test(hair->adt)) {
outliner_add_element(soops, &te->subtree, hair, te, TSE_ANIM_DATA, 0);
+ }
break;
}
case ID_PT: {
PointCloud *pointcloud = (PointCloud *)id;
- if (outliner_animdata_test(pointcloud->adt))
+ if (outliner_animdata_test(pointcloud->adt)) {
outliner_add_element(soops, &te->subtree, pointcloud, te, TSE_ANIM_DATA, 0);
+ }
break;
}
case ID_VO: {
Volume *volume = (Volume *)id;
- if (outliner_animdata_test(volume->adt))
+ if (outliner_animdata_test(volume->adt)) {
outliner_add_element(soops, &te->subtree, volume, te, TSE_ANIM_DATA, 0);
+ }
break;
}
case ID_SIM: {
@@ -848,7 +851,7 @@ static TreeElement *outliner_add_element(
}
te->parent = parent;
- te->index = index; // for data arrays
+ te->index = index; /* For data arrays. */
if (ELEM(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
/* pass */
}
@@ -873,7 +876,7 @@ static TreeElement *outliner_add_element(
te->name = ((Library *)id)->filepath;
}
else {
- te->name = id->name + 2; // default, can be overridden by Library or non-ID data
+ te->name = id->name + 2; /* Default, can be overridden by Library or non-ID data. */
}
te->idcode = GS(id->name);
}
@@ -914,7 +917,7 @@ static TreeElement *outliner_add_element(
/* loop over all targets used here */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
if (lastadded != dtar->id) {
- // XXX this lastadded check is rather lame, and also fails quite badly...
+ /* XXX this lastadded check is rather lame, and also fails quite badly... */
outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
lastadded = dtar->id;
}
@@ -1526,7 +1529,7 @@ static void outliner_make_object_parent_hierarchy(ListBase *lb)
TreeStoreElem *tselem;
/* build hierarchy */
- // XXX also, set extents here...
+ /* XXX also, set extents here... */
te = lb->first;
while (te) {
ten = te->next;
@@ -1666,10 +1669,10 @@ static int treesort_alpha_ob(const void *v1, const void *v2)
if (comp == 1) {
return 1;
}
- else if (comp == 2) {
+ if (comp == 2) {
return -1;
}
- else if (comp == 3) {
+ if (comp == 3) {
/* Among objects first come the ones in the collection, followed by the ones not on it.
* This way we can have the dashed lines in a separate style connecting the former. */
if ((x1->te->flag & TE_CHILD_NOT_IN_COLLECTION) !=
@@ -1682,7 +1685,7 @@ static int treesort_alpha_ob(const void *v1, const void *v2)
if (comp > 0) {
return 1;
}
- else if (comp < 0) {
+ if (comp < 0) {
return -1;
}
return 0;
@@ -1714,7 +1717,7 @@ static int treesort_alpha(const void *v1, const void *v2)
if (comp > 0) {
return 1;
}
- else if (comp < 0) {
+ if (comp < 0) {
return -1;
}
return 0;
@@ -1790,10 +1793,10 @@ static void outliner_sort(ListBase *lb)
tp->idcode = te->idcode;
if (tselem->type && tselem->type != TSE_DEFGROUP) {
- tp->idcode = 0; // don't sort this
+ tp->idcode = 0; /* Don't sort this. */
}
if (tselem->type == TSE_ID_BASE) {
- tp->idcode = 1; // do sort this
+ tp->idcode = 1; /* Do sort this. */
}
tp->id = tselem->id;
@@ -1981,9 +1984,7 @@ static TreeElement *outliner_find_first_desired_element_at_y(const SpaceOutliner
if (te->ys + UI_UNIT_Y > view_co_limit) {
return te_sub;
}
- else {
- return NULL;
- }
+ return NULL;
}
if (te->next) {
@@ -2191,7 +2192,9 @@ static bool outliner_element_is_collection_or_object(TreeElement *te)
if ((tselem->type == 0) && (te->idcode == ID_OB)) {
return true;
}
- else if (outliner_is_collection_tree_element(te)) {
+
+ /* Collection instance datablocks should not be extracted. */
+ if (outliner_is_collection_tree_element(te) && !(te->parent && te->parent->idcode == ID_OB)) {
return true;
}
@@ -2241,7 +2244,7 @@ static int outliner_filter_subtree(SpaceOutliner *soops,
te_next = outliner_extract_children_from_subtree(te, lb);
continue;
}
- else if ((exclude_filter & SO_FILTER_SEARCH) == 0) {
+ if ((exclude_filter & SO_FILTER_SEARCH) == 0) {
/* Filter subtree too. */
outliner_filter_subtree(soops, view_layer, &te->subtree, search_string, exclude_filter);
continue;
@@ -2306,8 +2309,8 @@ static void outliner_filter_tree(SpaceOutliner *soops, ViewLayer *view_layer)
/* ======================================================= */
/* Main Tree Building API */
-/* Main entry point for building the tree data-structure that the outliner represents */
-// TODO: split each mode into its own function?
+/* Main entry point for building the tree data-structure that the outliner represents. */
+/* TODO: split each mode into its own function? */
void outliner_build_tree(
Main *mainvar, Scene *scene, ViewLayer *view_layer, SpaceOutliner *soops, ARegion *region)
{
@@ -2458,7 +2461,9 @@ void outliner_build_tree(
te_object->directdata = base;
}
- outliner_make_object_parent_hierarchy(&soops->tree);
+ if ((soops->filter & SO_FILTER_NO_CHILDREN) == 0) {
+ outliner_make_object_parent_hierarchy(&soops->tree);
+ }
}
else {
/* Show collections in the view layer. */
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index a120718e36b..9accf35784a 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -122,7 +122,7 @@ static TreeElement *outliner_find_item_at_x_in_row_recursive(const TreeElement *
if ((child_te->flag & TE_ICONROW) && over_element) {
return child_te;
}
- else if ((child_te->flag & TE_ICONROW_MERGED) && over_element) {
+ if ((child_te->flag & TE_ICONROW_MERGED) && over_element) {
if (r_merged) {
*r_merged = true;
}
@@ -409,9 +409,7 @@ bool outliner_is_element_visible(const TreeElement *te)
if (tselem->flag & TSE_CLOSED) {
return false;
}
- else {
- te = te->parent;
- }
+ te = te->parent;
}
return true;
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index aa1663dff01..8a78211f145 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -294,7 +294,7 @@ static void outliner_header_region_listener(wmWindow *UNUSED(win),
/* ******************** default callbacks for outliner space ***************** */
-static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *outliner_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceOutliner *soutliner;
@@ -407,7 +407,7 @@ void ED_spacetype_outliner(void)
st->spaceid = SPACE_OUTLINER;
strncpy(st->name, "Outliner", BKE_ST_MAXNAME);
- st->new = outliner_new;
+ st->create = outliner_create;
st->free = outliner_free;
st->init = outliner_init;
st->duplicate = outliner_duplicate;
diff --git a/source/blender/editors/space_script/script_intern.h b/source/blender/editors/space_script/script_intern.h
index c6f72784b05..5d73bca350c 100644
--- a/source/blender/editors/space_script/script_intern.h
+++ b/source/blender/editors/space_script/script_intern.h
@@ -21,8 +21,7 @@
* \ingroup spscript
*/
-#ifndef __SCRIPT_INTERN_H__
-#define __SCRIPT_INTERN_H__
+#pragma once
/* internal exports only */
@@ -33,5 +32,3 @@ void script_keymap(struct wmKeyConfig *keyconf);
/* script_edit.c */
void SCRIPT_OT_reload(struct wmOperatorType *ot);
void SCRIPT_OT_python_file_run(struct wmOperatorType *ot);
-
-#endif /* __SCRIPT_INTERN_H__ */
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index 343f35421a4..4d0c2b658c6 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -51,7 +51,7 @@
/* ******************** default callbacks for script space ***************** */
-static SpaceLink *script_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *script_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceScript *sscript;
@@ -179,7 +179,7 @@ void ED_spacetype_script(void)
st->spaceid = SPACE_SCRIPT;
strncpy(st->name, "Script", BKE_ST_MAXNAME);
- st->new = script_new;
+ st->create = script_create;
st->free = script_free;
st->init = script_init;
st->duplicate = script_duplicate;
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 6202a3556a4..a35feb62c9d 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -151,7 +151,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type)
int proximity = INT_MAX;
if (!ed || !ed->seqbasep) {
- return 2;
+ return 1;
}
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -165,7 +165,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type)
if (tgt) {
return tgt->machine + 1;
}
- return 2;
+ return 1;
}
static void sequencer_generic_invoke_xy__internal(bContext *C, wmOperator *op, int flag, int type)
@@ -581,10 +581,10 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
seq = seq_load_fn(C, ed->seqbasep, &seq_load);
if (seq) {
- sequencer_add_apply_overlap(C, op, seq);
if (seq_load.seq_sound) {
sequencer_add_apply_overlap(C, op, seq_load.seq_sound);
}
+ sequencer_add_apply_overlap(C, op, seq);
}
}
RNA_END;
@@ -594,10 +594,10 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
seq = seq_load_fn(C, ed->seqbasep, &seq_load);
if (seq) {
- sequencer_add_apply_overlap(C, op, seq);
if (seq_load.seq_sound) {
sequencer_add_apply_overlap(C, op, seq_load.seq_sound);
}
+ sequencer_add_apply_overlap(C, op, seq);
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 1af552680a3..7863d2b724d 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1450,8 +1450,11 @@ static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
}
}
-static void *sequencer_OCIO_transform_ibuf(
- const bContext *C, ImBuf *ibuf, bool *r_glsl_used, int *r_format, int *r_type)
+static void *sequencer_OCIO_transform_ibuf(const bContext *C,
+ ImBuf *ibuf,
+ bool *r_glsl_used,
+ eGPUTextureFormat *r_format,
+ eGPUDataFormat *r_data)
{
void *display_buffer;
void *cache_handle = NULL;
@@ -1460,30 +1463,32 @@ static void *sequencer_OCIO_transform_ibuf(
force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
force_fallback |= (ibuf->dither != 0.0f);
+ /* Default */
+ *r_format = GPU_RGBA8;
+ *r_data = GPU_DATA_UNSIGNED_BYTE;
+
/* Fallback to CPU based color space conversion. */
if (force_fallback) {
*r_glsl_used = false;
- *r_format = GL_RGBA;
- *r_type = GL_UNSIGNED_BYTE;
display_buffer = NULL;
}
else if (ibuf->rect_float) {
display_buffer = ibuf->rect_float;
+ *r_data = GPU_DATA_FLOAT;
if (ibuf->channels == 4) {
- *r_format = GL_RGBA;
+ *r_format = GPU_RGBA16F;
}
else if (ibuf->channels == 3) {
- *r_format = GL_RGB;
+ /* Alpha is implicitly 1. */
+ *r_format = GPU_RGB16F;
}
else {
BLI_assert(!"Incompatible number of channels for float buffer in sequencer");
- *r_format = GL_RGBA;
+ *r_format = GPU_RGBA16F;
display_buffer = NULL;
}
- *r_type = GL_FLOAT;
-
if (ibuf->float_colorspace) {
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
C, ibuf->float_colorspace, ibuf->dither, true);
@@ -1494,15 +1499,11 @@ static void *sequencer_OCIO_transform_ibuf(
}
else if (ibuf->rect) {
display_buffer = ibuf->rect;
- *r_format = GL_RGBA;
- *r_type = GL_UNSIGNED_BYTE;
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
C, ibuf->rect_colorspace, ibuf->dither, false);
}
else {
- *r_format = GL_RGBA;
- *r_type = GL_UNSIGNED_BYTE;
display_buffer = NULL;
}
@@ -1510,8 +1511,6 @@ static void *sequencer_OCIO_transform_ibuf(
* properly, in this case we fallback to CPU-based display transform. */
if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) {
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
- *r_format = GL_RGBA;
- *r_type = GL_UNSIGNED_BYTE;
}
if (cache_handle) {
IMB_display_buffer_release(cache_handle);
@@ -1600,11 +1599,11 @@ static void sequencer_draw_display_buffer(const bContext *C,
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
- /* Format needs to be created prior to any immBindProgram call.
+ /* Format needs to be created prior to any immBindShader call.
* Do it here because OCIO binds it's own shader. */
- int format, type;
+ eGPUTextureFormat format;
+ eGPUDataFormat data;
bool glsl_used = false;
- GLuint texid;
GPUVertFormat *imm_format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint texCoord = GPU_vertformat_attr_add(
@@ -1618,11 +1617,11 @@ static void sequencer_draw_display_buffer(const bContext *C,
}
display_buffer = (uchar *)ibuf->rect;
- format = GL_RGBA;
- type = GL_UNSIGNED_BYTE;
+ format = GPU_RGBA8;
+ data = GPU_DATA_UNSIGNED_BYTE;
}
else {
- display_buffer = sequencer_OCIO_transform_ibuf(C, ibuf, &glsl_used, &format, &type);
+ display_buffer = sequencer_OCIO_transform_ibuf(C, ibuf, &glsl_used, &format, &data);
}
if (draw_backdrop) {
@@ -1632,18 +1631,11 @@ static void sequencer_draw_display_buffer(const bContext *C,
GPU_matrix_identity_projection_set();
}
- glGenTextures(1, (GLuint *)&texid);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texid);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ GPUTexture *texture = GPU_texture_create_nD(
+ ibuf->x, ibuf->y, 0, 2, display_buffer, format, data, 0, false, NULL);
+ GPU_texture_filter_mode(texture, false);
- if (type == GL_FLOAT) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, ibuf->x, ibuf->y, 0, format, type, display_buffer);
- }
- else {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, format, type, display_buffer);
- }
+ GPU_texture_bind(texture, 0);
if (!glsl_used) {
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
@@ -1677,8 +1669,9 @@ static void sequencer_draw_display_buffer(const bContext *C,
immVertex2f(pos, preview.xmax, preview.ymin);
immEnd();
- glBindTexture(GL_TEXTURE_2D, 0);
- glDeleteTextures(1, &texid);
+
+ GPU_texture_unbind(texture);
+ GPU_texture_free(texture);
if (!glsl_used) {
immUnbindProgram();
@@ -1898,19 +1891,19 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
if ((seq->flag & SELECT) != sel) {
continue;
}
- else if (seq == last_seq && (last_seq->flag & SELECT)) {
+ if (seq == last_seq && (last_seq->flag & SELECT)) {
continue;
}
- else if (min_ii(seq->startdisp, seq->start) > v2d->cur.xmax) {
+ if (min_ii(seq->startdisp, seq->start) > v2d->cur.xmax) {
continue;
}
- else if (max_ii(seq->enddisp, seq->start + seq->len) < v2d->cur.xmin) {
+ if (max_ii(seq->enddisp, seq->start + seq->len) < v2d->cur.xmin) {
continue;
}
- else if (seq->machine + 1.0f < v2d->cur.ymin) {
+ if (seq->machine + 1.0f < v2d->cur.ymin) {
continue;
}
- else if (seq->machine > v2d->cur.ymax) {
+ if (seq->machine > v2d->cur.ymax) {
continue;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index f74a4eae3bb..99d4c2d9f1a 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -227,7 +227,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports)
BKE_reportf(reports, RPT_WARNING, "Proxy is not enabled for %s, skipping", seq->name);
continue;
}
- else if (seq->strip->proxy->build_size_flags == 0) {
+ if (seq->strip->proxy->build_size_flags == 0) {
BKE_reportf(reports, RPT_WARNING, "Resolution is not selected for %s, skipping", seq->name);
continue;
}
@@ -392,7 +392,7 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i
best_seq = seq;
break;
}
- else if (dist < best_dist) {
+ if (dist < best_dist) {
best_dist = dist;
best_seq = seq;
}
@@ -467,30 +467,6 @@ static bool seq_is_parent(Sequence *par, Sequence *seq)
return ((par->seq1 == seq) || (par->seq2 == seq) || (par->seq3 == seq));
}
-static bool seq_is_predecessor(Sequence *pred, Sequence *seq)
-{
- if (!pred) {
- return 0;
- }
- if (pred == seq) {
- return 0;
- }
- else if (seq_is_parent(pred, seq)) {
- return 1;
- }
- else if (pred->seq1 && seq_is_predecessor(pred->seq1, seq)) {
- return 1;
- }
- else if (pred->seq2 && seq_is_predecessor(pred->seq2, seq)) {
- return 1;
- }
- else if (pred->seq3 && seq_is_predecessor(pred->seq3, seq)) {
- return 1;
- }
-
- return 0;
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -690,78 +666,6 @@ int seq_effect_find_selected(Scene *scene,
/** \name Delete Utilities
* \{ */
-static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq)
-{
- Sequence *seq1, *seq2, *seq3;
-
- /* Try to find a replacement input sequence, and flag for later deletion if
- * no replacement can be found. */
-
- if (!seq) {
- return NULL;
- }
- else if (!(seq->type & SEQ_TYPE_EFFECT)) {
- return ((seq->flag & SELECT) ? NULL : seq);
- }
- else if (!(seq->flag & SELECT)) {
- /* Try to find replacement for effect inputs. */
- seq1 = del_seq_find_replace_recurs(scene, seq->seq1);
- seq2 = del_seq_find_replace_recurs(scene, seq->seq2);
- seq3 = del_seq_find_replace_recurs(scene, seq->seq3);
-
- if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) {
- /* Pass. */
- }
- else if (seq1 || seq2 || seq3) {
- seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3;
- seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3;
- seq->seq3 = (seq3) ? seq3 : (seq1) ? seq1 : seq2;
-
- BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1);
- }
- else {
- seq->flag |= SELECT; /* Mark for delete. */
- }
- }
-
- if (seq->flag & SELECT) {
- if ((seq1 = del_seq_find_replace_recurs(scene, seq->seq1))) {
- return seq1;
- }
- if ((seq2 = del_seq_find_replace_recurs(scene, seq->seq2))) {
- return seq2;
- }
- if ((seq3 = del_seq_find_replace_recurs(scene, seq->seq3))) {
- return seq3;
- }
- else {
- return NULL;
- }
- }
- else {
- return seq;
- }
-}
-
-static void del_seq_clear_modifiers_recurs(Scene *scene, Sequence *deleting_sequence)
-{
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- Sequence *current_sequence;
-
- SEQP_BEGIN (ed, current_sequence) {
- if (!(current_sequence->flag & SELECT) && current_sequence != deleting_sequence) {
- SequenceModifierData *smd;
-
- for (smd = current_sequence->modifiers.first; smd; smd = smd->next) {
- if (smd->mask_sequence == deleting_sequence) {
- smd->mask_sequence = NULL;
- }
- }
- }
- }
- SEQ_END;
-}
-
static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short deleteall)
{
Sequence *seq, *seqn;
@@ -1096,6 +1000,7 @@ static bool sequence_offset_after_frame(Scene *scene, const int delta, const int
if (seq->startdisp >= cfra) {
BKE_sequence_translate(scene, seq, delta);
BKE_sequence_calc(scene, seq);
+ BKE_sequence_invalidate_cache_preprocessed(scene, seq);
done = true;
}
}
@@ -1744,9 +1649,7 @@ static int sequencer_slip_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static void sequencer_slip_update_header(Scene *scene, ScrArea *area, SlipData *data, int offset)
@@ -2239,14 +2142,16 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
}
if (!seq_effect_find_selected(
- scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg)) {
+ scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg) ||
+ BKE_sequence_effect_get_num_inputs(last_seq->type) == 0) {
BKE_report(op->reports, RPT_ERROR, error_msg);
return OPERATOR_CANCELLED;
}
/* Check if reassigning would create recursivity. */
- if (seq_is_predecessor(seq1, last_seq) || seq_is_predecessor(seq2, last_seq) ||
- seq_is_predecessor(seq3, last_seq)) {
- BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: no cycles allowed");
+ if (BKE_sequencer_render_loop_check(seq1, last_seq) ||
+ BKE_sequencer_render_loop_check(seq2, last_seq) ||
+ BKE_sequencer_render_loop_check(seq3, last_seq)) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: recursion detected");
return OPERATOR_CANCELLED;
}
@@ -2365,6 +2270,8 @@ static int sequencer_split_exec(bContext *C, wmOperator *op)
split_side = RNA_enum_get(op->ptr, "side");
ignore_selection = RNA_boolean_get(op->ptr, "ignore_selection");
+ BKE_sequencer_prefetch_stop(scene);
+
if (split_hard == SEQ_SPLIT_HARD) {
changed = split_seq_list(bmain,
scene,
@@ -2433,10 +2340,9 @@ static int sequencer_split_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
}
- else {
- /* Passthrough to selection if used as tool. */
- return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
- }
+
+ /* Passthrough to selection if used as tool. */
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
static int sequencer_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -2570,7 +2476,8 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
if (nseqbase.first) {
Sequence *seq = nseqbase.first;
- /* Rely on the nseqbase list being added at the end. */
+ /* Rely on the nseqbase list being added at the end.
+ * Their UUIDs has been re-generated by the BKE_sequence_base_dupli_recursive(), */
BLI_movelisttolist(ed->seqbasep, &nseqbase);
for (; seq; seq = seq->next) {
@@ -2611,59 +2518,20 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
- MetaStack *ms;
- bool nothing_selected = true;
- seq = BKE_sequencer_active_get(scene);
- if (seq && seq->flag & SELECT) { /* Avoid a loop since this is likely to be selected. */
- nothing_selected = false;
- }
- else {
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if (seq->flag & SELECT) {
- nothing_selected = false;
- break;
- }
- }
- }
+ BKE_sequencer_prefetch_stop(scene);
- if (nothing_selected) {
- return OPERATOR_FINISHED;
- }
-
- /* For effects and modifiers, try to find a replacement input. */
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if (!(seq->flag & SELECT)) {
- if ((seq->type & SEQ_TYPE_EFFECT)) {
- del_seq_find_replace_recurs(scene, seq);
- }
- }
- else {
- del_seq_clear_modifiers_recurs(scene, seq);
+ SEQP_BEGIN (scene->ed, seq) {
+ if (seq->flag & SELECT) {
+ BKE_sequencer_flag_for_removal(scene, ed->seqbasep, seq);
}
}
-
- /* Delete all selected strips. */
- recurs_del_seq_flag(scene, ed->seqbasep, SELECT, 0);
-
- /* Update lengths, etc. */
- seq = ed->seqbasep->first;
- while (seq) {
- BKE_sequence_calc(scene, seq);
- seq = seq->next;
- }
-
- /* Free parent metas. */
- ms = ed->metastack.last;
- while (ms) {
- BKE_sequence_calc(scene, ms->parseq);
- ms = ms->prev;
- }
+ SEQ_END;
+ BKE_sequencer_remove_flagged_sequences(scene, ed->seqbasep);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
return OPERATOR_FINISHED;
}
@@ -2981,6 +2849,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
if (seq != seqm && (seq->flag & SELECT)) {
BKE_sequence_invalidate_cache_composite(scene, seq);
channel_max = max_ii(seq->machine, channel_max);
+ /* Sequence is moved within the same edit, no need to re-generate the UUID. */
BLI_remlink(ed->seqbasep, seq);
BLI_addtail(&seqm->seqbase, seq);
}
@@ -3030,18 +2899,16 @@ static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
if (seq == seqm) {
return 1;
}
- else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) {
+ if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) {
return 1;
}
- else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) {
+ if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) {
return 1;
}
- else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) {
+ if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
@@ -3059,6 +2926,9 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
BKE_sequence_invalidate_cache_composite(scene, seq);
}
+ /* This moves strips from meta to parent, sating within same edit and no new strips are
+ * allocated. If the UUID was unique already (as it should) it will stay unique.
+ * No need to re-generate the UUIDs. */
BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase);
BLI_listbase_clear(&last_seq->seqbase);
@@ -3398,8 +3268,15 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_sequence_base_dupli_recursive(
- scene, scene, &seqbase_clipboard, ed->seqbasep, 0, LIB_ID_CREATE_NO_USER_REFCOUNT);
+ /* NOTE: The UUID is re-generated on paste, so we can keep UUID in the clipboard since
+ * nobody can reach them anyway.
+ * This reduces chance or running out of UUIDs if a cat falls asleep on Ctrl-C. */
+ BKE_sequence_base_dupli_recursive(scene,
+ scene,
+ &seqbase_clipboard,
+ ed->seqbasep,
+ 0,
+ (LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_FREE_NO_MAIN));
seqbase_clipboard_frame = scene->r.cfra;
@@ -3457,6 +3334,8 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
iseq_first = nseqbase.first;
+ /* NOTE: BKE_sequence_base_dupli_recursive() takes care of generating new UUIDs for sequences
+ * in the new list. */
BLI_movelisttolist(ed->seqbasep, &nseqbase);
for (iseq = iseq_first; iseq; iseq = iseq->next) {
@@ -3772,9 +3651,8 @@ static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "One of the effect inputs is unset, cannot swap");
return OPERATOR_CANCELLED;
}
- else {
- SWAP(Sequence *, *seq_1, *seq_2);
- }
+
+ SWAP(Sequence *, *seq_1, *seq_2);
BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
@@ -3829,15 +3707,14 @@ static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "New effect needs more input strips");
return OPERATOR_CANCELLED;
}
- else {
- sh = BKE_sequence_get_effect(seq);
- sh.free(seq, true);
- seq->type = new_type;
+ sh = BKE_sequence_get_effect(seq);
+ sh.free(seq, true);
- sh = BKE_sequence_get_effect(seq);
- sh.init(seq);
- }
+ seq->type = new_type;
+
+ sh = BKE_sequence_get_effect(seq);
+ sh.init(seq);
BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
/* Invalidate cache. */
@@ -4191,7 +4068,7 @@ static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Select one or more strips");
return OPERATOR_CANCELLED;
}
- else if (efra < 0) {
+ if (efra < 0) {
BKE_report(op->reports, RPT_ERROR, "Can't set a negative range");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index fee07e8941d..1d168866e7c 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -21,8 +21,7 @@
* \ingroup spseq
*/
-#ifndef __SEQUENCER_INTERN_H__
-#define __SEQUENCER_INTERN_H__
+#pragma once
#include "DNA_sequence_types.h"
#include "RNA_access.h"
@@ -208,5 +207,3 @@ int sequencer_image_seq_get_minmax_frame(struct wmOperator *op,
int *r_numdigits);
void sequencer_image_seq_reserve_frames(
struct wmOperator *op, struct StripElem *se, int len, int minframe, int numdigits);
-
-#endif /* __SEQUENCER_INTERN_H__ */
diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c
index 243a6e193eb..80b1c7a5194 100644
--- a/source/blender/editors/space_sequencer/sequencer_scopes.c
+++ b/source/blender/editors/space_sequencer/sequencer_scopes.c
@@ -50,14 +50,14 @@ static void rgb_to_yuv_normalized(const float rgb[3], float yuv[3])
yuv[2] += 0.5f;
}
-static void scope_put_pixel(uchar *table, uchar *pos)
+static void scope_put_pixel(const uchar *table, uchar *pos)
{
uchar newval = table[*pos];
pos[0] = pos[1] = pos[2] = newval;
pos[3] = 255;
}
-static void scope_put_pixel_single(uchar *table, uchar *pos, int col)
+static void scope_put_pixel_single(const uchar *table, uchar *pos, int col)
{
char newval = table[pos[col]];
pos[col] = newval;
@@ -232,9 +232,7 @@ ImBuf *make_waveform_view_from_ibuf(ImBuf *ibuf)
if (ibuf->rect_float) {
return make_waveform_view_from_ibuf_float(ibuf);
}
- else {
- return make_waveform_view_from_ibuf_byte(ibuf);
- }
+ return make_waveform_view_from_ibuf_byte(ibuf);
}
static ImBuf *make_sep_waveform_view_from_ibuf_byte(ImBuf *ibuf)
@@ -336,9 +334,7 @@ ImBuf *make_sep_waveform_view_from_ibuf(ImBuf *ibuf)
if (ibuf->rect_float) {
return make_sep_waveform_view_from_ibuf_float(ibuf);
}
- else {
- return make_sep_waveform_view_from_ibuf_byte(ibuf);
- }
+ return make_sep_waveform_view_from_ibuf_byte(ibuf);
}
static void draw_zebra_byte(ImBuf *src, ImBuf *ibuf, float perc)
@@ -541,7 +537,7 @@ BLI_INLINE int get_bin_float(float f)
if (f < -0.25f) {
return 0;
}
- else if (f >= 1.25f) {
+ if (f >= 1.25f) {
return 511;
}
@@ -627,9 +623,7 @@ ImBuf *make_histogram_view_from_ibuf(ImBuf *ibuf)
if (ibuf->rect_float) {
return make_histogram_view_from_ibuf_float(ibuf);
}
- else {
- return make_histogram_view_from_ibuf_byte(ibuf);
- }
+ return make_histogram_view_from_ibuf_byte(ibuf);
}
static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, int h, int size)
@@ -757,7 +751,5 @@ ImBuf *make_vectorscope_view_from_ibuf(ImBuf *ibuf)
if (ibuf->rect_float) {
return make_vectorscope_view_from_ibuf_float(ibuf);
}
- else {
- return make_vectorscope_view_from_ibuf_byte(ibuf);
- }
+ return make_vectorscope_view_from_ibuf_byte(ibuf);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c
index f91db3efef4..c1dac30bcb6 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -321,9 +321,7 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void SEQUENCER_OT_view_selected(wmOperatorType *ot)
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 368f9c1af19..b8bb3e4d43b 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -86,7 +86,7 @@ static ARegion *sequencer_find_region(ScrArea *area, short type)
/* ******************** default callbacks for sequencer space ***************** */
-static SpaceLink *sequencer_new(const ScrArea *UNUSED(area), const Scene *scene)
+static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *scene)
{
ARegion *region;
SpaceSeq *sseq;
@@ -231,12 +231,12 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
case SEQ_VIEW_SEQUENCE:
if (region_main && (region_main->flag & RGN_FLAG_HIDDEN)) {
region_main->flag &= ~RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
if (region_preview && !(region_preview->flag & RGN_FLAG_HIDDEN)) {
region_preview->flag |= RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_preview->handlers);
view_changed = true;
}
@@ -252,13 +252,13 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
case SEQ_VIEW_PREVIEW:
if (region_main && !(region_main->flag & RGN_FLAG_HIDDEN)) {
region_main->flag |= RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_main->handlers);
view_changed = true;
}
if (region_preview && (region_preview->flag & RGN_FLAG_HIDDEN)) {
region_preview->flag &= ~RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
region_preview->v2d.cur = region_preview->v2d.tot;
view_changed = true;
}
@@ -281,13 +281,13 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
* 'full window' views before, though... Better than nothing. */
if (region_main->flag & RGN_FLAG_HIDDEN) {
region_main->flag &= ~RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
region_preview->sizey = (int)(height - region_main->sizey);
view_changed = true;
}
if (region_preview->flag & RGN_FLAG_HIDDEN) {
region_preview->flag &= ~RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
region_preview->v2d.cur = region_preview->v2d.tot;
region_main->sizey = (int)(height - region_preview->sizey);
view_changed = true;
@@ -312,7 +312,7 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
}
if (view_changed) {
- ED_area_initialize(wm, window, area);
+ ED_area_init(wm, window, area);
ED_area_tag_redraw(area);
}
}
@@ -464,7 +464,7 @@ static int sequencer_context(const bContext *C, const char *member, bContextData
return true;
}
- else if (CTX_data_equals(member, "edit_mask")) {
+ if (CTX_data_equals(member, "edit_mask")) {
Mask *mask = BKE_sequencer_mask_get(scene);
if (mask) {
CTX_data_id_pointer_set(result, &mask->id);
@@ -852,7 +852,7 @@ void ED_spacetype_sequencer(void)
st->spaceid = SPACE_SEQ;
strncpy(st->name, "Sequencer", BKE_ST_MAXNAME);
- st->new = sequencer_new;
+ st->create = sequencer_create;
st->free = sequencer_free;
st->init = sequencer_init;
st->duplicate = sequencer_duplicate;
diff --git a/source/blender/editors/space_statusbar/space_statusbar.c b/source/blender/editors/space_statusbar/space_statusbar.c
index 34d7f8b0216..ae56b111360 100644
--- a/source/blender/editors/space_statusbar/space_statusbar.c
+++ b/source/blender/editors/space_statusbar/space_statusbar.c
@@ -42,7 +42,7 @@
/* ******************** default callbacks for statusbar space ******************** */
-static SpaceLink *statusbar_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *statusbar_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceStatusBar *sstatusbar;
@@ -158,7 +158,7 @@ void ED_spacetype_statusbar(void)
st->spaceid = SPACE_STATUSBAR;
strncpy(st->name, "Status Bar", BKE_ST_MAXNAME);
- st->new = statusbar_new;
+ st->create = statusbar_create;
st->free = statusbar_free;
st->init = statusbar_init;
st->duplicate = statusbar_duplicate;
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 76d61193ce0..f6d00ec94bf 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -53,7 +53,7 @@
/* ******************** default callbacks for text space ***************** */
-static SpaceLink *text_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *text_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceText *stext;
@@ -256,7 +256,7 @@ static int text_context(const bContext *C, const char *member, bContextDataResul
CTX_data_dir_set(result, text_context_dir);
return 1;
}
- else if (CTX_data_equals(member, "edit_text")) {
+ if (CTX_data_equals(member, "edit_text")) {
if (st->text != NULL) {
CTX_data_id_pointer_set(result, &st->text->id);
}
@@ -445,7 +445,7 @@ void ED_spacetype_text(void)
st->spaceid = SPACE_TEXT;
strncpy(st->name, "Text", BKE_ST_MAXNAME);
- st->new = text_new;
+ st->create = text_create;
st->free = text_free;
st->init = text_init;
st->duplicate = text_duplicate;
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index 1f034bdbd09..24c55e60513 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -319,15 +319,12 @@ static int text_autocomplete_invoke(bContext *C, wmOperator *op, const wmEvent *
ED_undo_push(C, op->type->name);
return OPERATOR_FINISHED;
}
- else {
- WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
- }
- else {
- text_autocomplete_free(C, op);
- return OPERATOR_CANCELLED;
+
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
}
+ text_autocomplete_free(C, op);
+ return OPERATOR_CANCELLED;
}
static int doc_scroll = 0;
@@ -590,10 +587,8 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
}
return retval;
}
- else {
- text_autocomplete_free(C, op);
- return OPERATOR_FINISHED;
- }
+ text_autocomplete_free(C, op);
+ return OPERATOR_FINISHED;
}
static void text_autocomplete_free(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index a0339b35c57..e9ac6946032 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -234,11 +234,10 @@ void wrap_offset(
if (i - lines < 0) {
break;
}
- else {
- linep = linep->next;
- (*offl) += lines - 1;
- i -= lines;
- }
+
+ linep = linep->next;
+ (*offl) += lines - 1;
+ i -= lines;
}
max = wrap_width(st, region);
@@ -849,9 +848,7 @@ int text_get_span_wrap(const SpaceText *st, ARegion *region, TextLine *from, Tex
return ret;
}
- else {
- return txt_get_span(from, to);
- }
+ return txt_get_span(from, to);
}
int text_get_total_lines(SpaceText *st, ARegion *region)
@@ -1612,11 +1609,10 @@ void draw_text_main(SpaceText *st, ARegion *region)
wrap_skip = st->top - wraplinecount;
break;
}
- else {
- wraplinecount += lines;
- tmp = tmp->next;
- linecount++;
- }
+
+ wraplinecount += lines;
+ tmp = tmp->next;
+ linecount++;
}
else {
tmp = tmp->next;
diff --git a/source/blender/editors/space_text/text_format.c b/source/blender/editors/space_text/text_format.c
index bdbf55d9198..d099f2a20d8 100644
--- a/source/blender/editors/space_text/text_format.c
+++ b/source/blender/editors/space_text/text_format.c
@@ -222,10 +222,9 @@ TextFormatType *ED_text_format_get(Text *text)
* the "default" text format */
return tft_lb.first;
}
- else {
- /* Return the "default" text format */
- return tft_lb.first;
- }
+
+ /* Return the "default" text format */
+ return tft_lb.first;
}
bool ED_text_is_syntax_highlight_supported(Text *text)
diff --git a/source/blender/editors/space_text/text_format.h b/source/blender/editors/space_text/text_format.h
index 07635e4227a..bb9574ee55e 100644
--- a/source/blender/editors/space_text/text_format.h
+++ b/source/blender/editors/space_text/text_format.h
@@ -21,8 +21,7 @@
* \ingroup sptext
*/
-#ifndef __TEXT_FORMAT_H__
-#define __TEXT_FORMAT_H__
+#pragma once
/* *** Flatten String *** */
typedef struct FlattenString {
@@ -110,5 +109,3 @@ void ED_text_format_register_pov_ini(void);
#define STR_LITERAL_STARTSWITH(str, str_literal, len_var) \
(strncmp(str, str_literal, len_var = (sizeof(str_literal) - 1)) == 0)
-
-#endif /* __TEXT_FORMAT_H__ */
diff --git a/source/blender/editors/space_text/text_format_lua.c b/source/blender/editors/space_text/text_format_lua.c
index 42a52ce0f58..4f6d91451e0 100644
--- a/source/blender/editors/space_text/text_format_lua.c
+++ b/source/blender/editors/space_text/text_format_lua.c
@@ -226,7 +226,7 @@ static void txtfmt_lua_format_line(SpaceText *st, TextLine *line, const bool do_
continue;
}
/* Handle continuations */
- else if (cont) {
+ if (cont) {
/* Multi-line comments */
if (cont & FMT_CONT_COMMENT_C) {
if (*str == ']' && *(str + 1) == ']') {
diff --git a/source/blender/editors/space_text/text_format_osl.c b/source/blender/editors/space_text/text_format_osl.c
index 53e38cfe870..b205996d1d2 100644
--- a/source/blender/editors/space_text/text_format_osl.c
+++ b/source/blender/editors/space_text/text_format_osl.c
@@ -252,7 +252,7 @@ static void txtfmt_osl_format_line(SpaceText *st, TextLine *line, const bool do_
continue;
}
/* Handle continuations */
- else if (cont) {
+ if (cont) {
/* C-Style comments */
if (cont & FMT_CONT_COMMENT_C) {
if (*str == '*' && *(str + 1) == '/') {
diff --git a/source/blender/editors/space_text/text_format_pov.c b/source/blender/editors/space_text/text_format_pov.c
index 52aaad034bf..96d9c234a40 100644
--- a/source/blender/editors/space_text/text_format_pov.c
+++ b/source/blender/editors/space_text/text_format_pov.c
@@ -825,7 +825,7 @@ static void txtfmt_pov_format_line(SpaceText *st, TextLine *line, const bool do_
continue;
}
/* Handle continuations */
- else if (cont) {
+ if (cont) {
/* C-Style comments */
if (cont & FMT_CONT_COMMENT_C) {
if (*str == '*' && *(str + 1) == '/') {
diff --git a/source/blender/editors/space_text/text_format_pov_ini.c b/source/blender/editors/space_text/text_format_pov_ini.c
index df4f1e6b38c..8d6b877d3f7 100644
--- a/source/blender/editors/space_text/text_format_pov_ini.c
+++ b/source/blender/editors/space_text/text_format_pov_ini.c
@@ -410,7 +410,7 @@ static void txtfmt_pov_ini_format_line(SpaceText *st, TextLine *line, const bool
continue;
}
/* Handle continuations */
- else if (cont) {
+ if (cont) {
/* Multi-line comments */
if (cont & FMT_CONT_COMMENT_C) {
if (*str == ']' && *(str + 1) == ']') {
diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c
index 3858f7225ef..39985438462 100644
--- a/source/blender/editors/space_text/text_format_py.c
+++ b/source/blender/editors/space_text/text_format_py.c
@@ -376,7 +376,7 @@ static void txtfmt_py_format_line(SpaceText *st, TextLine *line, const bool do_n
continue;
}
/* Handle continuations */
- else if (cont) {
+ if (cont) {
/* Triple strings ("""...""" or '''...''') */
if (cont & FMT_CONT_TRIPLE) {
find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h
index d6588dda797..abafad4c241 100644
--- a/source/blender/editors/space_text/text_intern.h
+++ b/source/blender/editors/space_text/text_intern.h
@@ -21,8 +21,7 @@
* \ingroup sptext
*/
-#ifndef __TEXT_INTERN_H__
-#define __TEXT_INTERN_H__
+#pragma once
/* internal exports only */
@@ -181,5 +180,3 @@ void TEXT_OT_autocomplete(struct wmOperatorType *ot);
/* space_text.c */
extern const char *text_context_dir[]; /* doc access */
-
-#endif /* __TEXT_INTERN_H__ */
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index c0343900f8b..6be436cffb5 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -3012,7 +3012,7 @@ static void text_cursor_set_to_pos_wrapped(
break;
/* Exactly at the cursor */
}
- else if (y == 0 && i - start <= x && i + columns - start > x) {
+ if (y == 0 && i - start <= x && i + columns - start > x) {
/* current position could be wrapped to next line */
/* this should be checked when end of current line would be reached */
charp = curs = j;
@@ -3471,21 +3471,20 @@ static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if ((event->ctrl || event->oskey) && !event->utf8_buf[0]) {
return OPERATOR_PASS_THROUGH;
}
- 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);
- }
- else {
- /* in theory, ghost can set value to extended ascii here */
- len = BLI_str_utf8_from_unicode(event->ascii, str);
- }
- str[len] = '\0';
- RNA_string_set(op->ptr, "text", str);
+ 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);
}
+ else {
+ /* in theory, ghost can set value to extended ascii here */
+ len = BLI_str_utf8_from_unicode(event->ascii, str);
+ }
+ str[len] = '\0';
+ RNA_string_set(op->ptr, "text", str);
}
ret = text_insert_exec(C, op);
@@ -3673,9 +3672,7 @@ static int text_replace_exec(bContext *C, wmOperator *op)
if (replace_all) {
return text_replace_all(C);
}
- else {
- return text_find_and_replace(C, op, TEXT_REPLACE);
- }
+ return text_find_and_replace(C, op, TEXT_REPLACE);
}
void TEXT_OT_replace(wmOperatorType *ot)
diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c
index d06c567988d..dc357cdd355 100644
--- a/source/blender/editors/space_topbar/space_topbar.c
+++ b/source/blender/editors/space_topbar/space_topbar.c
@@ -52,7 +52,7 @@
/* ******************** default callbacks for topbar space ***************** */
-static SpaceLink *topbar_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *topbar_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceTopBar *stopbar;
@@ -250,7 +250,7 @@ void ED_spacetype_topbar(void)
st->spaceid = SPACE_TOPBAR;
strncpy(st->name, "Top Bar", BKE_ST_MAXNAME);
- st->new = topbar_new;
+ st->create = topbar_create;
st->free = topbar_free;
st->init = topbar_init;
st->duplicate = topbar_duplicate;
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 9eae722d5c8..0242bb4fe24 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -45,7 +45,7 @@
/* ******************** default callbacks for userpref space ***************** */
-static SpaceLink *userpref_new(const ScrArea *area, const Scene *UNUSED(scene))
+static SpaceLink *userpref_create(const ScrArea *area, const Scene *UNUSED(scene))
{
ARegion *region;
SpaceUserPref *spref;
@@ -115,7 +115,7 @@ static void userpref_main_region_init(wmWindowManager *wm, ARegion *region)
{
/* do not use here, the properties changed in userprefs do a system-wide refresh,
* then scroller jumps back */
- /* region->v2d.flag &= ~V2D_IS_INITIALISED; */
+ /* region->v2d.flag &= ~V2D_IS_INIT; */
region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
@@ -235,7 +235,7 @@ void ED_spacetype_userpref(void)
st->spaceid = SPACE_USERPREF;
strncpy(st->name, "Userpref", BKE_ST_MAXNAME);
- st->new = userpref_new;
+ st->create = userpref_create;
st->free = userpref_free;
st->init = userpref_init;
st->duplicate = userpref_duplicate;
diff --git a/source/blender/editors/space_userpref/userpref_intern.h b/source/blender/editors/space_userpref/userpref_intern.h
index 56930d3a231..506e93ae7ac 100644
--- a/source/blender/editors/space_userpref/userpref_intern.h
+++ b/source/blender/editors/space_userpref/userpref_intern.h
@@ -21,9 +21,6 @@
* \ingroup spuserpref
*/
-#ifndef __USERPREF_INTERN_H__
-#define __USERPREF_INTERN_H__
+#pragma once
/* internal exports only */
-
-#endif /* __USERPREF_INTERN_H__ */
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 5959052b0ab..f17d7ccd136 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -126,7 +126,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
}
}
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
+ GPU_front_facing(ob->transflag & OB_NEG_SCALE);
/* Just to create the data to pass to immediate mode, grr! */
const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 4fc98789c18..e5ba27cef07 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -120,11 +120,10 @@ bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_regi
*r_region = region;
return true;
}
- else {
- if (ED_view3d_area_user_region(area, v3d, r_region)) {
- *r_v3d = v3d;
- return true;
- }
+
+ if (ED_view3d_area_user_region(area, v3d, r_region)) {
+ *r_v3d = v3d;
+ return true;
}
}
}
@@ -261,7 +260,7 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *area)
/* ******************** default callbacks for view3d space ***************** */
-static SpaceLink *view3d_new(const ScrArea *UNUSED(area), const Scene *scene)
+static SpaceLink *view3d_create(const ScrArea *UNUSED(area), const Scene *scene)
{
ARegion *region;
View3D *v3d;
@@ -508,9 +507,8 @@ static bool view3d_ima_drop_poll(bContext *C,
/* rule might not work? */
return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE));
}
- else {
- return WM_drag_ID(drag, ID_IM) != NULL;
- }
+
+ return WM_drag_ID(drag, ID_IM) != NULL;
}
static bool view3d_ima_bg_is_camera_view(bContext *C)
@@ -618,11 +616,12 @@ static void view3d_lightcache_update(bContext *C)
return;
}
- WM_operator_properties_create(&op_ptr, "SCENE_OT_light_cache_bake");
+ wmOperatorType *ot = WM_operatortype_find("SCENE_OT_light_cache_bake", true);
+ WM_operator_properties_create_ptr(&op_ptr, ot);
RNA_int_set(&op_ptr, "delay", 200);
RNA_enum_set_identifier(C, &op_ptr, "subset", "DIRTY");
- WM_operator_name_call(C, "SCENE_OT_light_cache_bake", WM_OP_INVOKE_DEFAULT, &op_ptr);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_ptr);
WM_operator_properties_free(&op_ptr);
}
@@ -827,6 +826,7 @@ static void view3d_main_region_listener(
case ND_POSE:
case ND_DRAW:
case ND_MODIFIER:
+ case ND_SHADERFX:
case ND_CONSTRAINT:
case ND_KEYS:
case ND_PARTICLE:
@@ -1383,6 +1383,7 @@ static void view3d_buttons_region_listener(wmWindow *UNUSED(win),
case ND_DRAW:
case ND_KEYS:
case ND_MODIFIER:
+ case ND_SHADERFX:
ED_region_tag_redraw(region);
break;
}
@@ -1610,7 +1611,7 @@ void ED_spacetype_view3d(void)
st->spaceid = SPACE_VIEW3D;
strncpy(st->name, "View3D", BKE_ST_MAXNAME);
- st->new = view3d_new;
+ st->create = view3d_create;
st->free = view3d_free;
st->init = view3d_init;
st->listener = space_view3d_listener;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index cb87ddafea1..d78c58c0c64 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -126,27 +126,25 @@ static float compute_scale_factor(const float ve_median, const float median)
if (ve_median <= 0.0f) {
return 0.0f;
}
- else if (ve_median >= 1.0f) {
+ if (ve_median >= 1.0f) {
return 1.0f;
}
- else {
- /* Scale value to target median. */
- float median_new = ve_median;
- float median_orig = ve_median - median; /* Previous median value. */
- /* In case of floating point error. */
- CLAMP(median_orig, 0.0f, 1.0f);
- CLAMP(median_new, 0.0f, 1.0f);
+ /* Scale value to target median. */
+ float median_new = ve_median;
+ float median_orig = ve_median - median; /* Previous median value. */
- if (median_new <= median_orig) {
- /* Scale down. */
- return median_new / median_orig;
- }
- else {
- /* Scale up, negative to indicate it... */
- return -(1.0f - median_new) / (1.0f - median_orig);
- }
+ /* In case of floating point error. */
+ CLAMP(median_orig, 0.0f, 1.0f);
+ CLAMP(median_new, 0.0f, 1.0f);
+
+ if (median_new <= median_orig) {
+ /* Scale down. */
+ return median_new / median_orig;
}
+
+ /* Scale up, negative to indicate it... */
+ return -(1.0f - median_new) / (1.0f - median_orig);
}
/**
@@ -1117,13 +1115,12 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
/* not for me */
return;
}
- else {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *ob = view_layer->basact->object;
- ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
- }
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = view_layer->basact->object;
+ ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
}
static bool view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
@@ -1477,6 +1474,7 @@ static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
uiLayout *col;
if (!mball || !(mball->lastelem)) {
+ uiItemL(layout, IFACE_("Nothing selected"), ICON_NONE);
return;
}
@@ -1641,14 +1639,13 @@ static int view3d_object_mode_menu(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "No active object found");
return OPERATOR_CANCELLED;
}
- else if (((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) {
+ if (((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) {
ED_object_mode_set(C, (ob->mode == OB_MODE_OBJECT) ? OB_MODE_POSE : OB_MODE_OBJECT);
return OPERATOR_CANCELLED;
}
- else {
- UI_pie_menu_invoke(C, "VIEW3D_MT_object_mode_pie", CTX_wm_window(C)->eventstate);
- return OPERATOR_CANCELLED;
- }
+
+ UI_pie_menu_invoke(C, "VIEW3D_MT_object_mode_pie", CTX_wm_window(C)->eventstate);
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_object_mode_pie_or_toggle(wmOperatorType *ot)
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index aeabe68c2d0..1d5b33e7b90 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -116,9 +116,8 @@ Object *ED_view3d_cameracontrol_object_get(View3DCameraControl *vctrl)
if (rv3d->persp == RV3D_CAMOB) {
return view3d_cameracontrol_object(vctrl);
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/**
@@ -199,6 +198,56 @@ struct View3DCameraControl *ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph
}
/**
+ * A version of #BKE_object_apply_mat4 that respects #Object.protectflag,
+ * applying the locking back to the view to avoid the view.
+ * This is needed so the view doesn't get out of sync with the object,
+ * causing visible jittering when in fly/walk mode for e.g.
+ *
+ * \note This could be exposed as an API option, as we might not want the view
+ * to be constrained by the thing it's controlling.
+ */
+static bool object_apply_mat4_with_protect(Object *ob,
+ const float obmat[4][4],
+ const bool use_parent,
+ /* Only use when applying lock. */
+ RegionView3D *rv3d,
+ const float view_mat[4][4])
+{
+ const bool use_protect = (ob->protectflag != 0);
+ bool view_changed = false;
+
+ ObjectTfmProtectedChannels obtfm;
+ if (use_protect) {
+ BKE_object_tfm_protected_backup(ob, &obtfm);
+ }
+
+ BKE_object_apply_mat4(ob, obmat, true, use_parent);
+
+ if (use_protect) {
+ float obmat_noprotect[4][4], obmat_protect[4][4];
+
+ BKE_object_to_mat4(ob, obmat_noprotect);
+ BKE_object_tfm_protected_restore(ob, &obtfm, ob->protectflag);
+ BKE_object_to_mat4(ob, obmat_protect);
+
+ if (!equals_m4m4(obmat_noprotect, obmat_protect)) {
+ /* Apply the lock protection back to the view, without this the view
+ * keeps moving, ignoring the object locking, causing jittering in some cases. */
+ float diff_mat[4][4];
+ float view_mat_protect[4][4];
+ float obmat_noprotect_inv[4][4];
+ invert_m4_m4(obmat_noprotect_inv, obmat_noprotect);
+ mul_m4_m4m4(diff_mat, obmat_protect, obmat_noprotect_inv);
+
+ mul_m4_m4m4(view_mat_protect, diff_mat, view_mat);
+ ED_view3d_from_m4(view_mat_protect, rv3d->ofs, rv3d->viewquat, &rv3d->dist);
+ view_changed = true;
+ }
+ }
+ return view_changed;
+}
+
+/**
* Updates cameras from the ``rv3d`` values, optionally auto-keyframing.
*/
void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl,
@@ -217,21 +266,25 @@ void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl,
ID *id_key;
+ float view_mat[4][4];
+ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+
/* transform the parent or the camera? */
if (vctrl->root_parent) {
Object *ob_update;
- float view_mat[4][4];
float prev_view_imat[4][4];
float diff_mat[4][4];
float parent_mat[4][4];
invert_m4_m4(prev_view_imat, vctrl->view_mat_prev);
- ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
mul_m4_m4m4(diff_mat, view_mat, prev_view_imat);
mul_m4_m4m4(parent_mat, diff_mat, vctrl->root_parent->obmat);
- BKE_object_apply_mat4(vctrl->root_parent, parent_mat, true, false);
+ if (object_apply_mat4_with_protect(vctrl->root_parent, parent_mat, false, rv3d, view_mat)) {
+ /* Calculate again since the view locking changes the matrix. */
+ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+ }
ob_update = v3d->camera->parent;
while (ob_update) {
@@ -244,18 +297,16 @@ void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl,
id_key = &vctrl->root_parent->id;
}
else {
- float view_mat[4][4];
float scale_mat[4][4];
float scale_back[3];
/* even though we handle the scale matrix, this still changes over time */
copy_v3_v3(scale_back, v3d->camera->scale);
- ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
size_to_mat4(scale_mat, v3d->camera->scale);
mul_m4_m4m4(view_mat, view_mat, scale_mat);
- BKE_object_apply_mat4(v3d->camera, view_mat, true, true);
+ object_apply_mat4_with_protect(v3d->camera, view_mat, true, rv3d, view_mat);
DEG_id_tag_update(&v3d->camera->id, ID_RECALC_TRANSFORM);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 6f7d815c33a..0442a0f35c9 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -36,6 +36,7 @@
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_layer.h"
#include "BKE_main.h"
@@ -74,7 +75,6 @@
#include "GPU_batch.h"
#include "GPU_batch_presets.h"
-#include "GPU_draw.h"
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
@@ -115,8 +115,8 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
const Scene *scene,
View3D *v3d,
ARegion *region,
- float viewmat[4][4],
- float winmat[4][4],
+ const float viewmat[4][4],
+ const float winmat[4][4],
const rcti *rect,
bool offscreen)
{
@@ -197,8 +197,8 @@ static void view3d_main_region_setup_view(Depsgraph *depsgraph,
Scene *scene,
View3D *v3d,
ARegion *region,
- float viewmat[4][4],
- float winmat[4][4],
+ const float viewmat[4][4],
+ const float winmat[4][4],
const rcti *rect)
{
RegionView3D *rv3d = region->regiondata;
@@ -214,8 +214,8 @@ static void view3d_main_region_setup_offscreen(Depsgraph *depsgraph,
const Scene *scene,
View3D *v3d,
ARegion *region,
- float viewmat[4][4],
- float winmat[4][4])
+ const float viewmat[4][4],
+ const float winmat[4][4])
{
RegionView3D *rv3d = region->regiondata;
ED_view3d_update_viewmat(depsgraph, scene, v3d, region, viewmat, winmat, NULL, true);
@@ -353,8 +353,8 @@ void ED_view3d_draw_setup_view(const wmWindowManager *wm,
Scene *scene,
ARegion *region,
View3D *v3d,
- float viewmat[4][4],
- float winmat[4][4],
+ const float viewmat[4][4],
+ const float winmat[4][4],
const rcti *rect)
{
RegionView3D *rv3d = region->regiondata;
@@ -668,7 +668,8 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
/* safety border */
if (ca) {
- immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
+ GPU_blend(true);
+ immUniformThemeColorAlpha(TH_VIEW_OVERLAY, 0.75f);
if (ca->dtx & CAM_DTX_CENTER) {
float x3, y3;
@@ -778,6 +779,8 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
* 2.0f round corner effect was nearly not visible anyway... */
imm_draw_box_wire_2d(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
+
+ GPU_blend(false);
}
immUnbindProgram();
@@ -844,16 +847,9 @@ void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bo
ED_view3d_draw_setup_view(
G_MAIN->wm.first, NULL, depsgraph, scene, region, v3d, NULL, NULL, NULL);
- GPU_clear(GPU_DEPTH_BIT);
-
- if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
- ED_view3d_clipping_set(rv3d);
- }
/* get surface depth without bias */
rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
- GPU_depth_test(true);
-
/* Needed in cases the view-port isn't already setup. */
WM_draw_region_viewport_ensure(region, SPACE_VIEW3D);
WM_draw_region_viewport_bind(region);
@@ -867,14 +863,8 @@ void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bo
WM_draw_region_viewport_unbind(region);
- if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
- ED_view3d_clipping_disable();
- }
rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
- /* Reset default for UI */
- GPU_depth_test(false);
-
U.glalphaclip = glalphaclip;
v3d->flag = flag;
@@ -1085,7 +1075,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d)
GPU_blend(true);
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- glDepthMask(GL_FALSE); /* don't overwrite zbuf */
+ GPU_depth_mask(false); /* don't overwrite zbuf */
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -1175,7 +1165,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d)
immUnbindProgram();
GPU_blend(false);
- glDepthMask(GL_TRUE);
+ GPU_depth_mask(true);
}
#endif /* WITH_INPUT_NDOF */
@@ -1619,9 +1609,7 @@ RenderEngineType *ED_view3d_engine_type(const Scene *scene, int drawtype)
if (drawtype == OB_MATERIAL && (type->flag & RE_USE_EEVEE_VIEWPORT)) {
return RE_engines_find(RE_engine_id_BLENDER_EEVEE);
}
- else {
- return type;
- }
+ return type;
}
void view3d_main_region_draw(const bContext *C, ARegion *region)
@@ -1632,7 +1620,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *region)
view3d_draw_view(C, region);
DRW_cache_free_old_batches(bmain);
- GPU_free_images_old(bmain);
+ BKE_image_free_old_gputextures(bmain);
GPU_pass_cache_garbage_collect();
/* XXX This is in order to draw UI batches with the DRW
@@ -1655,7 +1643,7 @@ static void view3d_stereo3d_setup_offscreen(Depsgraph *depsgraph,
const Scene *scene,
View3D *v3d,
ARegion *region,
- float winmat[4][4],
+ const float winmat[4][4],
const char *viewname)
{
/* update the viewport matrices with the new camera */
@@ -1682,8 +1670,8 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
ARegion *region,
int winx,
int winy,
- float viewmat[4][4],
- float winmat[4][4],
+ const float viewmat[4][4],
+ const float winmat[4][4],
bool is_image_render,
bool do_sky,
bool UNUSED(is_persp),
@@ -1714,10 +1702,15 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
/* set flags */
G.f |= G_FLAG_RENDER_VIEWPORT;
+ /* There are too many functions inside the draw manager that check the shading type,
+ * so use a temporary override instead. */
+ const eDrawType drawtype_orig = v3d->shading.type;
+ v3d->shading.type = drawtype;
+
{
/* free images which can have changed on frame-change
* warning! can be slow so only free animated images - campbell */
- GPU_free_images_anim(G.main); /* XXX :((( */
+ BKE_image_free_anim_gputextures(G.main); /* XXX :((( */
}
GPU_matrix_push_projection();
@@ -1754,6 +1747,7 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
UI_Theme_Restore(&theme_state);
+ v3d->shading.type = drawtype_orig;
G.f &= ~G_FLAG_RENDER_VIEWPORT;
}
@@ -1768,8 +1762,8 @@ void ED_view3d_draw_offscreen_simple(Depsgraph *depsgraph,
int winx,
int winy,
uint draw_flags,
- float viewmat[4][4],
- float winmat[4][4],
+ const float viewmat[4][4],
+ const float winmat[4][4],
float clip_start,
float clip_end,
bool is_image_render,
@@ -1963,10 +1957,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
NULL);
if (ibuf->rect_float) {
- GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
+ GPU_offscreen_read_pixels(ofs, GPU_DATA_FLOAT, ibuf->rect_float);
}
else if (ibuf->rect) {
- GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
+ GPU_offscreen_read_pixels(ofs, GPU_DATA_UNSIGNED_BYTE, ibuf->rect);
}
/* unbind */
@@ -2116,27 +2110,6 @@ bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const
return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
}
-void ED_view3d_clipping_set(RegionView3D *UNUSED(rv3d))
-{
- for (uint a = 0; a < 6; a++) {
- glEnable(GL_CLIP_DISTANCE0 + a);
- }
-}
-
-/* Use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set. */
-void ED_view3d_clipping_disable(void)
-{
- for (uint a = 0; a < 6; a++) {
- glDisable(GL_CLIP_DISTANCE0 + a);
- }
-}
-void ED_view3d_clipping_enable(void)
-{
- for (uint a = 0; a < 6; a++) {
- glEnable(GL_CLIP_DISTANCE0 + a);
- }
-}
-
/* *********************** backdraw for selection *************** */
/**
@@ -2194,13 +2167,8 @@ static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void
GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0);
GPU_framebuffer_bind(tmp_fb);
- glReadPixels(rect->xmin,
- rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- GL_DEPTH_COMPONENT,
- GL_FLOAT,
- data);
+ GPU_framebuffer_read_depth(
+ tmp_fb, rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), data);
GPU_framebuffer_restore();
GPU_framebuffer_free(tmp_fb);
@@ -2287,7 +2255,9 @@ void view3d_update_depths_rect(ARegion *region, ViewDepths *d, rcti *rect)
if (d->damaged) {
GPUViewport *viewport = WM_draw_region_get_viewport(region);
view3d_opengl_read_Z_pixels(viewport, rect, d->depths);
- glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
+ /* Range is assumed to be this as they are never changed. */
+ d->depth_range[0] = 0.0;
+ d->depth_range[1] = 1.0;
d->damaged = false;
}
}
@@ -2322,7 +2292,9 @@ void ED_view3d_depth_update(ARegion *region)
.ymax = d->h,
};
view3d_opengl_read_Z_pixels(viewport, &r, d->depths);
- glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
+ /* Assumed to be this as they are never changed. */
+ d->depth_range[0] = 0.0;
+ d->depth_range[1] = 1.0;
d->damaged = false;
}
}
@@ -2437,7 +2409,7 @@ struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv);
copy_v4_v4(rv3dmat->viewcamtexcofac, rv3d->viewcamtexcofac);
rv3dmat->pixsize = rv3d->pixsize;
- return (void *)rv3dmat;
+ return rv3dmat;
}
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat_pt)
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 3c3dea1509d..19aa9cb203b 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -509,8 +509,8 @@ static void viewops_data_create(bContext *C,
negate_v3_v3(my_origin, rv3d->ofs); /* ofs is flipped */
- /* Set the dist value to be the distance from this 3d point this means youll
- * always be able to zoom into it and panning wont go bad when dist was zero */
+ /* Set the dist value to be the distance from this 3d point this means you'll
+ * always be able to zoom into it and panning wont go bad when dist was zero. */
/* remove dist value */
upvec[0] = upvec[1] = 0;
@@ -1021,12 +1021,11 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
- else {
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
}
static void viewrotate_cancel(bContext *C, wmOperator *op)
@@ -1848,12 +1847,11 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
- else {
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
}
static void viewmove_cancel(bContext *C, wmOperator *op)
@@ -2407,18 +2405,17 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
viewops_data_free(C, op);
return OPERATOR_FINISHED;
}
- else {
- if (U.viewzoom == USER_ZOOM_CONT) {
- /* needs a timer to continue redrawing */
- vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
- vod->prev.time = PIL_check_seconds_timer();
- }
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
+ if (U.viewzoom == USER_ZOOM_CONT) {
+ /* needs a timer to continue redrawing */
+ vod->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
+ vod->prev.time = PIL_check_seconds_timer();
}
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_FINISHED;
}
@@ -2500,9 +2497,7 @@ static bool viewdolly_offset_lock_check(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "Cannot dolly when the view offset is locked");
return true;
}
- else {
- return false;
- }
+ return false;
}
static void view_dolly_to_vector_3d(ARegion *region, float orig_ofs[3], float dvec[3], float dfac)
@@ -2726,12 +2721,10 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
viewops_data_free(C, op);
return OPERATOR_FINISHED;
}
- else {
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_FINISHED;
}
@@ -2952,6 +2945,9 @@ static int view3d_all_exec(bContext *C, wmOperator *op)
}
if (center) {
+ struct wmMsgBus *mbus = CTX_wm_message_bus(C);
+ WM_msg_publish_rna_prop(mbus, &scene->id, &scene->cursor, View3DCursor, location);
+
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
}
@@ -3170,9 +3166,8 @@ static int view_lock_clear_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_view_lock_clear(wmOperatorType *ot)
@@ -3228,9 +3223,8 @@ static int view_lock_to_active_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_view_lock_to_active(wmOperatorType *ot)
@@ -4500,10 +4494,9 @@ static int viewroll_exec(bContext *C, wmOperator *op)
viewops_data_free(C, op);
return OPERATOR_FINISHED;
}
- else {
- viewops_data_free(C, op);
- return OPERATOR_CANCELLED;
- }
+
+ viewops_data_free(C, op);
+ return OPERATOR_CANCELLED;
}
static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -4535,12 +4528,10 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
viewops_data_free(C, op);
return OPERATOR_FINISHED;
}
- else {
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_FINISHED;
}
@@ -4755,9 +4746,8 @@ static Camera *background_image_camera_from_context(bContext *C)
}
return NULL;
}
- else {
- return CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
- }
+
+ return CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
}
static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
@@ -4848,9 +4838,7 @@ static int background_image_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_background_image_remove(wmOperatorType *ot)
@@ -4880,7 +4868,9 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot)
* Draw border or toggle off.
* \{ */
-static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mat[4][4])
+static void calc_local_clipping(float clip_local[6][4],
+ const BoundBox *clipbb,
+ const float mat[4][4])
{
BoundBox clipbb_local;
float imat[4][4];
@@ -4895,7 +4885,7 @@ static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float
ED_view3d_clipping_calc_from_boundbox(clip_local, &clipbb_local, is_negative_m4(mat));
}
-void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
+void ED_view3d_clipping_local(RegionView3D *rv3d, const float mat[4][4])
{
if (rv3d->rflag & RV3D_CLIPPING) {
calc_local_clipping(rv3d->clip_local, rv3d->clipbb, mat);
@@ -4933,9 +4923,7 @@ static int view3d_clipping_invoke(bContext *C, wmOperator *op, const wmEvent *ev
rv3d->clipbb = NULL;
return OPERATOR_FINISHED;
}
- else {
- return WM_gesture_box_invoke(C, op, event);
- }
+ return WM_gesture_box_invoke(C, op, event);
}
void VIEW3D_OT_clip_border(wmOperatorType *ot)
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 506969443fd..556b5d51505 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -16,6 +16,10 @@
/** \file
* \ingroup spview3d
+ *
+ * Interactive fly navigation modal operator (flying around in space).
+ *
+ * \note Similar logic to `view3d_walk.c` changes here may apply there too.
*/
/* defines VIEW3D_OT_fly modal operator */
@@ -200,7 +204,7 @@ typedef struct FlyInfo {
float grid;
/* compare between last state */
- /** Used to accelerate when using the mousewheel a lot. */
+ /** Used to accelerate when using the mouse-wheel a lot. */
double time_lastwheel;
/** Time between draws. */
double time_lastdraw;
@@ -425,7 +429,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
if (fly->state == FLY_RUNNING) {
return OPERATOR_RUNNING_MODAL;
}
- else if (fly->state == FLY_CONFIRM) {
+ if (fly->state == FLY_CONFIRM) {
/* Needed for auto_keyframe. */
#ifdef WITH_INPUT_NDOF
if (fly->ndof) {
@@ -614,8 +618,8 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event)
fly->axis = -1;
}
else {
- /* flip speed rather than stopping, game like motion,
- * else increase like mousewheel if we're already moving in that direction */
+ /* Flip speed rather than stopping, game like motion,
+ * else increase like mouse-wheel if we're already moving in that direction. */
if (fly->speed < 0.0f) {
fly->speed = -fly->speed;
}
@@ -998,19 +1002,6 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
interp_v3_v3v3(
dvec, dvec_tmp, fly->dvec_prev, (1.0f / (1.0f + (time_redraw * FLY_SMOOTH_FAC))));
- if (rv3d->persp == RV3D_CAMOB) {
- Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control);
- if (lock_ob->protectflag & OB_LOCK_LOCX) {
- dvec[0] = 0.0;
- }
- if (lock_ob->protectflag & OB_LOCK_LOCY) {
- dvec[1] = 0.0;
- }
- if (lock_ob->protectflag & OB_LOCK_LOCZ) {
- dvec[2] = 0.0;
- }
- }
-
add_v3_v3(rv3d->ofs, dvec);
if (rv3d->persp == RV3D_CAMOB) {
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
index f3bc0a8a15b..59b2e378955 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
@@ -397,9 +397,7 @@ static bool view3d_ruler_item_mousemove(struct Depsgraph *depsgraph,
}
return true;
}
- else {
- return false;
- }
+ return false;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c
index 18617b4368f..3f258a0699a 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_tool_generic.c
@@ -126,9 +126,8 @@ static void WIDGETGROUP_tool_generic_refresh(const bContext *C, wmGizmoGroup *gz
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
return;
}
- else {
- gzgroup->use_fallback_keymap = true;
- }
+
+ gzgroup->use_fallback_keymap = true;
/* skip, we don't draw anything anyway */
{
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 50cd71d7edc..83707ca4383 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -21,8 +21,7 @@
* \ingroup spview3d
*/
-#ifndef __VIEW3D_INTERN_H__
-#define __VIEW3D_INTERN_H__
+#pragma once
#include "ED_view3d.h"
@@ -284,5 +283,3 @@ void VIEW3D_GGT_placement(struct wmGizmoGroupType *gzgt);
extern uchar view3d_camera_border_hack_col[3];
extern bool view3d_camera_border_hack_test;
#endif
-
-#endif /* __VIEW3D_INTERN_H__ */
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index 131fbbc02ee..b7219290654 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -86,6 +86,11 @@ enum ePlace_Depth {
PLACE_DEPTH_CURSOR_VIEW = 3,
};
+enum ePlace_Orient {
+ PLACE_ORIENT_SURFACE = 1,
+ PLACE_ORIENT_DEFAULT = 2,
+};
+
struct InteractivePlaceData {
/* Window manager variables (set these even when waiting for input). */
Scene *scene;
@@ -145,16 +150,96 @@ struct InteractivePlaceData {
/* On-screen snap distance. */
#define MVAL_MAX_PX_DIST 12.0f
-static bool idp_snap_point_from_gizmo(wmGizmo *gz, float r_location[3])
+static bool idp_snap_point_from_gizmo_ex(wmGizmo *gz, const char *prop_id, float r_location[3])
{
if (gz->state & WM_GIZMO_STATE_HIGHLIGHT) {
- PropertyRNA *prop_location = RNA_struct_find_property(gz->ptr, "location");
+ PropertyRNA *prop_location = RNA_struct_find_property(gz->ptr, prop_id);
RNA_property_float_get_array(gz->ptr, prop_location, r_location);
return true;
}
return false;
}
+static bool idp_snap_point_from_gizmo(wmGizmo *gz, float r_location[3])
+{
+ return idp_snap_point_from_gizmo_ex(gz, "location", r_location);
+}
+
+static bool idp_snap_normal_from_gizmo(wmGizmo *gz, float r_normal[3])
+{
+ return idp_snap_point_from_gizmo_ex(gz, "normal", r_normal);
+}
+
+/**
+ * Calculate a 3x3 orientation matrix from the surface under the cursor.
+ */
+static bool idp_poject_surface_normal(SnapObjectContext *snap_context,
+ struct Depsgraph *depsgraph,
+ const float mval_fl[2],
+ const float mat_fallback[3][3],
+ const float normal_fallback[3],
+ float r_mat[3][3])
+{
+ bool success = false;
+ float normal[3] = {0.0f};
+ float co_dummy[3];
+ /* We could use the index to get the orientation from the face. */
+ Object *ob_snap;
+ float obmat[4][4];
+
+ if (ED_transform_snap_object_project_view3d_ex(snap_context,
+ depsgraph,
+ SCE_SNAP_MODE_FACE,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = true,
+ },
+ mval_fl,
+ NULL,
+ NULL,
+ co_dummy,
+ normal,
+ NULL,
+ &ob_snap,
+ obmat)) {
+ /* pass */
+ }
+ else if (normal_fallback != NULL) {
+ copy_m4_m3(obmat, mat_fallback);
+ copy_v3_v3(normal, normal_fallback);
+ }
+
+ if (!is_zero_v3(normal)) {
+ float mat[3][3];
+ copy_m3_m4(mat, obmat);
+ normalize_m3(mat);
+
+ float dot_best = fabsf(dot_v3v3(mat[0], normal));
+ int i_best = 0;
+ for (int i = 1; i < 3; i++) {
+ float dot_test = fabsf(dot_v3v3(mat[i], normal));
+ if (dot_test > dot_best) {
+ i_best = i;
+ dot_best = dot_test;
+ }
+ }
+ if (dot_v3v3(mat[i_best], normal) < 0.0f) {
+ negate_v3(mat[(i_best + 1) % 3]);
+ negate_v3(mat[(i_best + 2) % 3]);
+ }
+ copy_v3_v3(mat[i_best], normal);
+ orthogonalize_m3(mat, i_best);
+ normalize_m3(mat);
+
+ copy_v3_v3(r_mat[0], mat[(i_best + 1) % 3]);
+ copy_v3_v3(r_mat[1], mat[(i_best + 2) % 3]);
+ copy_v3_v3(r_mat[2], mat[i_best]);
+ success = true;
+ }
+
+ return success;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -549,30 +634,69 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
const int plane_axis = RNA_enum_get(op->ptr, "plane_axis");
const enum ePlace_Depth plane_depth = RNA_enum_get(op->ptr, "plane_depth");
const enum ePlace_Origin plane_origin = RNA_enum_get(op->ptr, "plane_origin");
+ const enum ePlace_Orient plane_orient = RNA_enum_get(op->ptr, "plane_orientation");
+
+ const float mval_fl[2] = {UNPACK2(event->mval)};
struct InteractivePlaceData *ipd = op->customdata;
RegionView3D *rv3d = ipd->region->regiondata;
+ /* Assign snap gizmo which is may be used as part of the tool. */
+ {
+ wmGizmoMap *gzmap = ipd->region->gizmo_map;
+ wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, view3d_gzgt_placement_id) : NULL;
+ if ((gzgroup != NULL) && gzgroup->gizmos.first) {
+ ipd->snap_gizmo = gzgroup->gizmos.first;
+ }
+ }
+
ipd->launch_event = WM_userdef_event_type_from_keymap_type(event->type);
ED_transform_calc_orientation_from_type(C, ipd->matrix_orient);
+ /* Set the orientation. */
+ if (plane_orient == PLACE_ORIENT_SURFACE) {
+ bool snap_context_free = false;
+ SnapObjectContext *snap_context =
+ (ipd->snap_gizmo ? ED_gizmotypes_snap_3d_context_ensure(
+ ipd->scene, ipd->region, ipd->v3d, ipd->snap_gizmo) :
+ NULL);
+ if (snap_context == NULL) {
+ snap_context = ED_transform_snap_object_context_create_view3d(
+ ipd->scene, 0, ipd->region, ipd->v3d);
+ snap_context_free = true;
+ }
+
+ float matrix_orient_surface[3][3];
+
+ /* Use the snap normal as a fallback in case the cursor isn't over a surface
+ * but snapping is enabled. */
+ float normal_fallback[3];
+ bool use_normal_fallback = ipd->snap_gizmo ?
+ idp_snap_normal_from_gizmo(ipd->snap_gizmo, normal_fallback) :
+ false;
+
+ if (idp_poject_surface_normal(snap_context,
+ CTX_data_ensure_evaluated_depsgraph(C),
+ mval_fl,
+ use_normal_fallback ? ipd->matrix_orient : NULL,
+ use_normal_fallback ? normal_fallback : NULL,
+ matrix_orient_surface)) {
+ copy_m3_m3(ipd->matrix_orient, matrix_orient_surface);
+ }
+
+ if (snap_context_free) {
+ ED_transform_snap_object_context_destroy(snap_context);
+ }
+ }
+
ipd->orient_axis = plane_axis;
ipd->is_centered_init = (plane_origin == PLACE_ORIGIN_CENTER);
ipd->step[0].is_centered = ipd->is_centered_init;
ipd->step[1].is_centered = ipd->is_centered_init;
ipd->step_index = STEP_BASE;
- /* Assign snap gizmo which is may be used as part of the tool. */
- {
- wmGizmoMap *gzmap = ipd->region->gizmo_map;
- wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, view3d_gzgt_placement_id) : NULL;
- if ((gzgroup != NULL) && gzgroup->gizmos.first) {
- ipd->snap_gizmo = gzgroup->gizmos.first;
- }
- }
-
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "primitive_type");
if (RNA_property_is_set(op->ptr, prop)) {
@@ -618,8 +742,6 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
plane_from_point_normal_v3(
ipd->step[0].plane, ipd->scene->cursor.location, ipd->matrix_orient[ipd->orient_axis]);
- const float mval_fl[2] = {UNPACK2(event->mval)};
-
const bool is_snap_found = ipd->snap_gizmo ?
idp_snap_point_from_gizmo(ipd->snap_gizmo, ipd->co_src) :
false;
@@ -826,7 +948,7 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
view3d_interactive_add_exit(C, op);
return OPERATOR_CANCELLED;
}
- else if (event->type == MOUSEMOVE) {
+ if (event->type == MOUSEMOVE) {
do_cursor_update = true;
}
@@ -1102,6 +1224,25 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
RNA_def_property_enum_items(prop, origin_items);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ static const EnumPropertyItem plane_orientation_items[] = {
+ {PLACE_ORIENT_SURFACE,
+ "SURFACE",
+ ICON_SNAP_NORMAL,
+ "Surface",
+ "Use the surface normal (the transform orientation as a fallback)"},
+ {PLACE_ORIENT_DEFAULT,
+ "DEFAULT",
+ ICON_ORIENTATION_GLOBAL,
+ "Default",
+ "Use the current transform orientation"},
+ {0, NULL, 0, NULL, NULL},
+ };
+ prop = RNA_def_property(ot->srna, "plane_orientation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Orientation", "The initial depth used when placing the cursor");
+ RNA_def_property_enum_default(prop, PLACE_ORIENT_SURFACE);
+ RNA_def_property_enum_items(prop, plane_orientation_items);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
/* When not accessed via a tool. */
prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index f4ec9a22520..c10a88af146 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -303,12 +303,12 @@ eV3DProjStatus ED_view3d_project_float_object(const ARegion *region,
float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
{
- return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
+ return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
}
float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[3])
{
- return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize;
+ return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize;
}
/**
@@ -316,7 +316,7 @@ float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[
*/
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip)
{
- float zfac = mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co);
+ float zfac = mul_project_m4_v3_zfac(rv3d->persmat, co);
if (r_flip) {
*r_flip = (zfac < 0.0f);
@@ -483,11 +483,11 @@ void ED_view3d_global_to_vector(const RegionView3D *rv3d, const float coord[3],
p1[3] = 1.0f;
copy_v3_v3(p2, p1);
p2[3] = 1.0f;
- mul_m4_v4((float(*)[4])rv3d->viewmat, p2);
+ mul_m4_v4(rv3d->viewmat, p2);
mul_v3_fl(p2, 2.0f);
- mul_m4_v4((float(*)[4])rv3d->viewinv, p2);
+ mul_m4_v4(rv3d->viewinv, p2);
sub_v3_v3v3(vec, p1, p2);
}
@@ -749,25 +749,26 @@ bool ED_view3d_win_to_segment_clipped(struct Depsgraph *depsgraph,
return true;
}
-/* Utility functions for projection
- * ******************************** */
+/* -------------------------------------------------------------------- */
+/** \name Utility functions for projection
+ * \{ */
-void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float pmat[4][4])
+void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float r_pmat[4][4])
{
float vmat[4][4];
- mul_m4_m4m4(vmat, (float(*)[4])rv3d->viewmat, ob->obmat);
- mul_m4_m4m4(pmat, (float(*)[4])rv3d->winmat, vmat);
+ mul_m4_m4m4(vmat, rv3d->viewmat, ob->obmat);
+ mul_m4_m4m4(r_pmat, rv3d->winmat, vmat);
}
void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d,
- float obmat[4][4],
- float pmat[4][4])
+ const float obmat[4][4],
+ float r_pmat[4][4])
{
float vmat[4][4];
- mul_m4_m4m4(vmat, (float(*)[4])rv3d->viewmat, obmat);
- mul_m4_m4m4(pmat, (float(*)[4])rv3d->winmat, vmat);
+ mul_m4_m4m4(vmat, rv3d->viewmat, obmat);
+ mul_m4_m4m4(r_pmat, rv3d->winmat, vmat);
}
/**
@@ -791,3 +792,5 @@ bool ED_view3d_unproject(
return GPU_matrix_unproject(region_co, rv3d->viewmat, rv3d->winmat, viewport, world);
}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 9e235d72f26..9490c807989 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -97,7 +97,6 @@
#include "UI_interface.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "DEG_depsgraph.h"
@@ -1398,9 +1397,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
if (changed_multi) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
return OPERATOR_PASS_THROUGH;
}
@@ -1542,9 +1539,7 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_select_menu(wmOperatorType *ot)
@@ -1576,7 +1571,7 @@ void VIEW3D_OT_select_menu(wmOperatorType *ot)
static Base *object_mouse_select_menu(bContext *C,
ViewContext *vc,
- uint *buffer,
+ const uint *buffer,
int hits,
const int mval[2],
bool extend,
@@ -1630,37 +1625,34 @@ static Base *object_mouse_select_menu(bContext *C,
BLI_linklist_free(linklist, NULL);
return base;
}
- else {
- /* UI, full in static array values that we later use in an enum function */
- LinkNode *node;
- int i;
- memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
+ /* UI, full in static array values that we later use in an enum function */
+ LinkNode *node;
+ int i;
- for (node = linklist, i = 0; node; node = node->next, i++) {
- Base *base = node->link;
- Object *ob = base->object;
- const char *name = ob->id.name + 2;
+ memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data));
- BLI_strncpy(object_mouse_select_menu_data[i].idname, name, MAX_ID_NAME - 2);
- object_mouse_select_menu_data[i].icon = UI_icon_from_id(&ob->id);
- }
+ for (node = linklist, i = 0; node; node = node->next, i++) {
+ Base *base = node->link;
+ Object *ob = base->object;
+ const char *name = ob->id.name + 2;
- {
- wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_select_menu", false);
- PointerRNA ptr;
+ BLI_strncpy(object_mouse_select_menu_data[i].idname, name, MAX_ID_NAME - 2);
+ object_mouse_select_menu_data[i].icon = UI_icon_from_id(&ob->id);
+ }
- WM_operator_properties_create_ptr(&ptr, ot);
- RNA_boolean_set(&ptr, "extend", extend);
- RNA_boolean_set(&ptr, "deselect", deselect);
- RNA_boolean_set(&ptr, "toggle", toggle);
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
- WM_operator_properties_free(&ptr);
- }
+ wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_select_menu", false);
+ PointerRNA ptr;
- BLI_linklist_free(linklist, NULL);
- return NULL;
- }
+ WM_operator_properties_create_ptr(&ptr, ot);
+ RNA_boolean_set(&ptr, "extend", extend);
+ RNA_boolean_set(&ptr, "deselect", deselect);
+ RNA_boolean_set(&ptr, "toggle", toggle);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
+ WM_operator_properties_free(&ptr);
+
+ BLI_linklist_free(linklist, NULL);
+ return NULL;
}
static bool selectbuffer_has_bones(const uint *buffer, const uint hits)
@@ -2120,7 +2112,7 @@ static bool ed_object_select_pick(bContext *C,
if (hits > 0) {
/* note: bundles are handling in the same way as bones */
- const bool has_bones = selectbuffer_has_bones(buffer, hits);
+ const bool has_bones = object ? false : selectbuffer_has_bones(buffer, hits);
/* note; shift+alt goes to group-flush-selecting */
if (enumerate) {
@@ -2504,9 +2496,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
}
- else {
- return OPERATOR_PASS_THROUGH; /* nothing selected, just passthrough */
- }
+ return OPERATOR_PASS_THROUGH; /* nothing selected, just passthrough */
}
static int view3d_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -3116,12 +3106,10 @@ static int opengl_bone_select_buffer_cmp(const void *sel_a_p, const void *sel_b_
if (sel_a < sel_b) {
return -1;
}
- else if (sel_a > sel_b) {
+ if (sel_a > sel_b) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const eSelectOp sel_op)
@@ -3347,12 +3335,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
FOREACH_OBJECT_IN_MODE_END;
}
else { /* No edit-mode, unified for bones and objects. */
- if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) {
- /* XXX, this is not selection, could be it's own operator. */
- changed_multi = ED_sculpt_mask_box_select(
- C, &vc, &rect, sel_op == SEL_OP_ADD ? true : false);
- }
- else if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
+ if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
changed_multi = do_paintface_box_select(&vc, wm_userdata, &rect, sel_op);
}
else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) {
@@ -3380,9 +3363,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
if (changed_multi) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_select_box(wmOperatorType *ot)
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 91b2971585d..265cb04c7b2 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -869,9 +869,7 @@ static int snap_curs_to_sel_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
@@ -921,9 +919,7 @@ static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 15d6a43d105..4e73a2be17e 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -113,9 +113,7 @@ Camera *ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d)
if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) {
return v3d->camera->data;
}
- else {
- return NULL;
- }
+ return NULL;
}
void ED_view3d_dist_range_get(const View3D *v3d, float r_dist_range[2])
@@ -222,7 +220,7 @@ void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *region)
}
/**
- * Use instead of: ``bglPolygonOffset(rv3d->dist, ...)`` see bug [#37727]
+ * Use instead of: ``GPU_polygon_offset(rv3d->dist, ...)`` see bug [#37727]
*/
void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
{
@@ -243,7 +241,7 @@ void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
}
}
- bglPolygonOffset(viewdist, dist);
+ GPU_polygon_offset(viewdist, dist);
}
bool ED_view3d_context_activate(bContext *C)
@@ -337,7 +335,7 @@ void ED_view3d_clipping_calc(
*
* \{ */
-static bool view3d_boundbox_clip_m4(const BoundBox *bb, float persmatob[4][4])
+static bool view3d_boundbox_clip_m4(const BoundBox *bb, const float persmatob[4][4])
{
int a, flag = -1, fl;
@@ -602,9 +600,7 @@ bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionV
return true;
}
- else {
- return false;
- }
+ return false;
}
bool ED_view3d_camera_autokey(const Scene *scene,
@@ -639,9 +635,7 @@ bool ED_view3d_camera_autokey(const Scene *scene,
return true;
}
- else {
- return false;
- }
+ return false;
}
/**
@@ -673,9 +667,7 @@ bool ED_view3d_camera_lock_autokey(View3D *v3d,
return ED_view3d_camera_autokey(scene, id_key, C, do_rotate, do_translate);
}
- else {
- return false;
- }
+ return false;
}
/** \} */
@@ -1017,9 +1009,7 @@ bool ED_view3d_autodist(Depsgraph *depsgraph,
ED_view3d_win_to_3d_int(v3d, region, fallback_depth_pt, mval, mouse_worldloc);
return true;
}
- else {
- return false;
- }
+ return false;
}
void ED_view3d_autodist_init(Depsgraph *depsgraph, ARegion *region, View3D *v3d, int mode)
@@ -1038,8 +1028,11 @@ void ED_view3d_autodist_init(Depsgraph *depsgraph, ARegion *region, View3D *v3d,
}
/* no 4x4 sampling, run #ED_view3d_autodist_init first */
-bool ED_view3d_autodist_simple(
- ARegion *region, const int mval[2], float mouse_worldloc[3], int margin, float *force_depth)
+bool ED_view3d_autodist_simple(ARegion *region,
+ const int mval[2],
+ float mouse_worldloc[3],
+ int margin,
+ const float *force_depth)
{
float depth;
@@ -1086,9 +1079,7 @@ static bool depth_segment_cb(int x, int y, void *userData)
data->depth = depth;
return 0;
}
- else {
- return 1;
- }
+ return 1;
}
bool ED_view3d_autodist_depth_seg(
@@ -1252,7 +1243,9 @@ float ED_view3d_radius_to_dist(const View3D *v3d,
* \param fallback_dist: The distance to use if the object is too near or in front of \a ofs.
* \returns A newly calculated distance or the fallback.
*/
-float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float fallback_dist)
+float ED_view3d_offset_distance(const float mat[4][4],
+ const float ofs[3],
+ const float fallback_dist)
{
float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f};
@@ -1383,16 +1376,14 @@ static float view3d_quat_axis[6][4][4] = {
};
-bool ED_view3d_quat_from_axis_view(const char view, const char view_axis_roll, float quat[4])
+bool ED_view3d_quat_from_axis_view(const char view, const char view_axis_roll, float r_quat[4])
{
BLI_assert(view_axis_roll <= RV3D_VIEW_AXIS_ROLL_270);
if (RV3D_VIEW_IS_AXIS(view)) {
- copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT][view_axis_roll]);
+ copy_qt_qt(r_quat, view3d_quat_axis[view - RV3D_VIEW_FRONT][view_axis_roll]);
return true;
}
- else {
- return false;
- }
+ return false;
}
bool ED_view3d_quat_to_axis_view(const float quat[4],
@@ -1472,7 +1463,7 @@ bool ED_view3d_lock(RegionView3D *rv3d)
* \param quat: The view rotation, quaternion normally from RegionView3D.viewquat.
* \param dist: The view distance from ofs, normally from RegionView3D.dist.
*/
-void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], float *dist)
+void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], const float *dist)
{
float nmat[3][3];
@@ -1575,10 +1566,9 @@ float ED_view3d_depth_read_cached(const ViewContext *vc, const int mval[2])
if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) {
return vd->depths[y * vd->w + x];
}
- else {
- BLI_assert(1.0 <= vd->depth_range[1]);
- return 1.0f;
- }
+
+ BLI_assert(1.0 <= vd->depth_range[1]);
+ return 1.0f;
}
bool ED_view3d_depth_read_cached_normal(const ViewContext *vc,
@@ -1633,9 +1623,7 @@ bool ED_view3d_depth_read_cached_normal(const ViewContext *vc,
if (normalize_v3(r_normal) != 0.0f) {
return true;
}
- else {
- return false;
- }
+ return false;
}
bool ED_view3d_depth_unproject(const ARegion *region,
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 3fc990160d2..ff9673a4262 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -50,7 +50,6 @@
#include "UI_resources.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "GPU_select.h"
#include "GPU_state.h"
@@ -568,9 +567,7 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, camera_ob);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_camera_to_view_selected(wmOperatorType *ot)
@@ -1106,10 +1103,6 @@ int view3d_opengl_select(ViewContext *vc,
GPU_depth_test(true);
}
- if (RV3D_CLIPPING_ENABLED(vc->v3d, vc->rv3d)) {
- ED_view3d_clipping_set(vc->rv3d);
- }
-
/* If in xray mode, we select the wires in priority. */
if (XRAY_ACTIVE(v3d) && use_nearest) {
/* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
@@ -1175,10 +1168,6 @@ int view3d_opengl_select(ViewContext *vc,
GPU_depth_test(false);
}
- if (RV3D_CLIPPING_ENABLED(v3d, vc->rv3d)) {
- ED_view3d_clipping_disable();
- }
-
DRW_opengl_context_disable();
finally:
@@ -1486,9 +1475,7 @@ static int localview_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
void VIEW3D_OT_localview(wmOperatorType *ot)
@@ -1538,10 +1525,9 @@ static int localview_remove_from_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
return OPERATOR_FINISHED;
}
- else {
- BKE_report(op->reports, RPT_ERROR, "No object selected");
- return OPERATOR_CANCELLED;
- }
+
+ BKE_report(op->reports, RPT_ERROR, "No object selected");
+ return OPERATOR_CANCELLED;
}
static bool localview_remove_from_poll(bContext *C)
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 50fa573423a..64167b83655 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -16,6 +16,11 @@
/** \file
* \ingroup spview3d
+ *
+ * Interactive walk navigation modal operator
+ * (similar to walking around in a first person game).
+ *
+ * \note Similar logic to `view3d_fly.c` changes here may apply there too.
*/
/* defines VIEW3D_OT_navigate - walk modal operator */
@@ -620,7 +625,7 @@ static int walkEnd(bContext *C, WalkInfo *walk)
if (walk->state == WALK_RUNNING) {
return OPERATOR_RUNNING_MODAL;
}
- else if (walk->state == WALK_CONFIRM) {
+ if (walk->state == WALK_CONFIRM) {
/* Needed for auto_keyframe. */
#ifdef WITH_INPUT_NDOF
if (walk->ndof) {
@@ -1295,19 +1300,6 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
sub_v3_v3v3(dvec, cur_loc, new_loc);
}
- if (rv3d->persp == RV3D_CAMOB) {
- Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control);
- if (lock_ob->protectflag & OB_LOCK_LOCX) {
- dvec[0] = 0.0f;
- }
- if (lock_ob->protectflag & OB_LOCK_LOCY) {
- dvec[1] = 0.0f;
- }
- if (lock_ob->protectflag & OB_LOCK_LOCZ) {
- dvec[2] = 0.0f;
- }
- }
-
/* scale the movement to the scene size */
mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
add_v3_v3(rv3d->ofs, dvec_tmp);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index eb60273fc79..76cce5e725f 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -673,10 +673,10 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
if (t->spacetype != SPACE_VIEW3D) {
return false;
}
- else if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) {
+ if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) {
return false;
}
- else if (!validSnap(t)) {
+ if (!validSnap(t)) {
return false;
}
break;
@@ -1417,9 +1417,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
if (handled || t->redraw) {
return 0;
}
- else {
- return OPERATOR_PASS_THROUGH;
- }
+ return OPERATOR_PASS_THROUGH;
}
bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 2bda04ad811..1917d9463f4 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -21,8 +21,7 @@
* \ingroup edtransform
*/
-#ifndef __TRANSFORM_H__
-#define __TRANSFORM_H__
+#pragma once
#include "ED_numinput.h"
#include "ED_transform.h"
@@ -81,6 +80,7 @@ typedef struct TransSnap {
bool snap_self;
bool peel;
bool snap_spatial_grid;
+ bool use_backface_culling;
char status;
/* Snapped Element Type (currently for objects only). */
char snapElem;
@@ -752,5 +752,3 @@ bool checkUseAxisMatrix(TransInfo *t);
*tc_end = (t)->data_container + (t)->data_container_len; \
th != tc_end; \
th++, i++)
-
-#endif
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 66b90eb159f..e15239f37d4 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -510,10 +510,12 @@ static void applyObjectConstraintVec(
else {
/* Specific TransData's space. */
copy_v3_v3(out, in);
- mul_m3_v3(t->spacemtx_inv, out);
- mul_m3_v3(td->axismtx, out);
- if (t->flag & T_EDIT) {
- mul_m3_v3(tc->mat3_unit, out);
+ if (t->con.mode & CON_APPLY) {
+ mul_m3_v3(t->spacemtx_inv, out);
+ mul_m3_v3(td->axismtx, out);
+ if (t->flag & T_EDIT) {
+ mul_m3_v3(tc->mat3_unit, out);
+ }
}
}
}
diff --git a/source/blender/editors/transform/transform_constraints.h b/source/blender/editors/transform/transform_constraints.h
index 282060af2c3..4c901842964 100644
--- a/source/blender/editors/transform/transform_constraints.h
+++ b/source/blender/editors/transform/transform_constraints.h
@@ -21,8 +21,7 @@
* \ingroup edtransform
*/
-#ifndef __TRANSFORM_CONSTRAINTS_H__
-#define __TRANSFORM_CONSTRAINTS_H__
+#pragma once
struct TransInfo;
@@ -49,5 +48,3 @@ int constraintModeToIndex(const TransInfo *t);
char constraintModeToChar(const TransInfo *t);
bool isLockConstraint(TransInfo *t);
int getConstraintSpaceDimension(TransInfo *t);
-
-#endif
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 5d1fd1543df..70004d27dfc 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -27,6 +27,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_kdtree.h"
+#include "BLI_linklist_stack.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
@@ -96,12 +97,10 @@ static int trans_data_compare_dist(const void *a, const void *b)
if (td_a->dist < td_b->dist) {
return -1;
}
- else if (td_a->dist > td_b->dist) {
+ if (td_a->dist > td_b->dist) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
static int trans_data_compare_rdist(const void *a, const void *b)
@@ -112,12 +111,10 @@ static int trans_data_compare_rdist(const void *a, const void *b)
if (td_a->rdist < td_b->rdist) {
return -1;
}
- else if (td_a->rdist > td_b->rdist) {
+ if (td_a->rdist > td_b->rdist) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
static void sort_trans_data_dist_container(const TransInfo *t, TransDataContainer *tc)
@@ -413,59 +410,66 @@ void transform_autoik_update(TransInfo *t, short mode)
/** \name Curve Surface
* \{ */
-void calc_distanceCurveVerts(TransData *head, TransData *tail)
+void calc_distanceCurveVerts(TransData *head, TransData *tail, bool cyclic)
{
- TransData *td, *td_near = NULL;
+ TransData *td;
+ BLI_LINKSTACK_DECLARE(queue, TransData *);
+ BLI_LINKSTACK_INIT(queue);
for (td = head; td <= tail; td++) {
if (td->flag & TD_SELECTED) {
- td_near = td;
td->dist = 0.0f;
+ BLI_LINKSTACK_PUSH(queue, td);
+ }
+ else {
+ td->dist = FLT_MAX;
+ }
+ }
+
+ while ((td = BLI_LINKSTACK_POP(queue))) {
+ float dist;
+ float vec[3];
+
+ TransData *next_td = NULL;
+
+ if (td + 1 <= tail) {
+ next_td = td + 1;
+ }
+ else if (cyclic) {
+ next_td = head;
}
- else if (td_near) {
- float dist;
- float vec[3];
- sub_v3_v3v3(vec, td_near->center, td->center);
+ if (next_td != NULL && !(next_td->flag & TD_NOTCONNECTED)) {
+ sub_v3_v3v3(vec, next_td->center, td->center);
mul_m3_v3(head->mtx, vec);
- dist = len_v3(vec);
+ dist = len_v3(vec) + td->dist;
- if (dist < (td - 1)->dist) {
- td->dist = (td - 1)->dist;
- }
- else {
- td->dist = dist;
+ if (dist < next_td->dist) {
+ next_td->dist = dist;
+ BLI_LINKSTACK_PUSH(queue, next_td);
}
}
- else {
- td->dist = FLT_MAX;
- td->flag |= TD_NOTCONNECTED;
+
+ next_td = NULL;
+
+ if (td - 1 >= head) {
+ next_td = td - 1;
}
- }
- td_near = NULL;
- for (td = tail; td >= head; td--) {
- if (td->flag & TD_SELECTED) {
- td_near = td;
- td->dist = 0.0f;
+ else if (cyclic) {
+ next_td = tail;
}
- else if (td_near) {
- float dist;
- float vec[3];
- sub_v3_v3v3(vec, td_near->center, td->center);
+ if (next_td != NULL && !(next_td->flag & TD_NOTCONNECTED)) {
+ sub_v3_v3v3(vec, next_td->center, td->center);
mul_m3_v3(head->mtx, vec);
- dist = len_v3(vec);
+ dist = len_v3(vec) + td->dist;
- if (td->flag & TD_NOTCONNECTED || dist < td->dist || (td + 1)->dist < td->dist) {
- td->flag &= ~TD_NOTCONNECTED;
- if (dist < (td + 1)->dist) {
- td->dist = (td + 1)->dist;
- }
- else {
- td->dist = dist;
- }
+ if (dist < next_td->dist) {
+ next_td->dist = dist;
+ BLI_LINKSTACK_PUSH(queue, next_td);
}
}
}
+ BLI_LINKSTACK_FREE(queue);
}
/* Utility function for getting the handle data from bezier's */
@@ -610,9 +614,7 @@ bool FrameOnMouseSide(char side, float frame, float cframe)
if (side == 'R') {
return (frame >= cframe);
}
- else {
- return (frame <= cframe);
- }
+ return (frame <= cframe);
}
/** \} */
@@ -670,7 +672,7 @@ void posttrans_fcurve_clean(FCurve *fcu, const int sel_flag, const bool use_hand
found = true;
break;
}
- else if (rk->frame < bezt->vec[1][0]) {
+ if (rk->frame < bezt->vec[1][0]) {
/* Terminate early if have passed the supposed insertion point? */
break;
}
@@ -696,11 +698,10 @@ void posttrans_fcurve_clean(FCurve *fcu, const int sel_flag, const bool use_hand
}
return;
}
- else {
- /* Compute the average values for each retained keyframe */
- LISTBASE_FOREACH (tRetainedKeyframe *, rk, &retained_keys) {
- rk->val = rk->val / (float)rk->tot_count;
- }
+
+ /* Compute the average values for each retained keyframe */
+ LISTBASE_FOREACH (tRetainedKeyframe *, rk, &retained_keys) {
+ rk->val = rk->val / (float)rk->tot_count;
}
/* 2) Delete all keyframes duplicating the "retained keys" found above
@@ -925,13 +926,13 @@ int special_transform_moving(TransInfo *t)
if (t->spacetype == SPACE_SEQ) {
return G_TRANSFORM_SEQ;
}
- else if (t->spacetype == SPACE_GRAPH) {
+ if (t->spacetype == SPACE_GRAPH) {
return G_TRANSFORM_FCURVES;
}
- else if ((t->flag & T_EDIT) || (t->flag & T_POSE)) {
+ if ((t->flag & T_EDIT) || (t->flag & T_POSE)) {
return G_TRANSFORM_EDIT;
}
- else if (t->flag & (T_OBJECT | T_TEXTURE)) {
+ if (t->flag & (T_OBJECT | T_TEXTURE)) {
return G_TRANSFORM_OBJ;
}
@@ -1277,6 +1278,9 @@ void createTransData(bContext *C, TransInfo *t)
set_prop_dist(t, false);
}
}
+ else if (convert_type == TC_MESH_UV && t->flag & T_PROP_CONNECTED) {
+ /* Already calculated by uv_set_connectivity_distance. */
+ }
else if (convert_type == TC_CURVE_VERTS && t->obedit_type == OB_CURVE) {
set_prop_dist(t, false);
}
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index f7eea286983..b753572ea7b 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -22,8 +22,7 @@
* \brief conversion and adaptation of different datablocks to a common struct.
*/
-#ifndef __TRANSFORM_CONVERT_H__
-#define __TRANSFORM_CONVERT_H__
+#pragma once
struct BezTriple;
struct FCurve;
@@ -47,7 +46,7 @@ bool clipUVTransform(TransInfo *t, float vec[2], const bool resize);
void clipUVData(TransInfo *t);
/* transform_convert_mesh.c */
-void trans_mesh_customdata_correction_init(TransInfo *t);
+void mesh_customdatacorrect_init(TransInfo *t);
/* transform_convert_sequencer.c */
int transform_convert_sequencer_get_snap_bound(TransInfo *t);
@@ -87,7 +86,7 @@ void transform_around_single_fallback_ex(TransInfo *t, int data_len_all);
void transform_around_single_fallback(TransInfo *t);
void posttrans_fcurve_clean(struct FCurve *fcu, const int sel_flag, const bool use_handle);
bool constraints_list_needinv(TransInfo *t, ListBase *list);
-void calc_distanceCurveVerts(TransData *head, TransData *tail);
+void calc_distanceCurveVerts(TransData *head, TransData *tail, bool cyclic);
struct TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt);
char transform_convert_frame_side_dir_get(TransInfo *t, float cframe);
bool FrameOnMouseSide(char side, float frame, float cframe);
@@ -189,4 +188,3 @@ void special_aftertrans_update__sequencer(bContext *C, TransInfo *t);
void createTransTrackingData(bContext *C, TransInfo *t);
void recalcData_tracking(TransInfo *t);
void special_aftertrans_update__movieclip(bContext *C, TransInfo *t);
-#endif
diff --git a/source/blender/editors/transform/transform_convert_action.c b/source/blender/editors/transform/transform_convert_action.c
index b9292aa151c..40e60544642 100644
--- a/source/blender/editors/transform/transform_convert_action.c
+++ b/source/blender/editors/transform/transform_convert_action.c
@@ -84,9 +84,7 @@ static int count_fcurve_keys(FCurve *fcu, char side, float cfra, bool is_prop_ed
if (is_prop_edit && count > 0) {
return count_all;
}
- else {
- return count;
- }
+ return count;
}
/* fully select selected beztriples, but only include if it's on the right side of cfra */
@@ -112,9 +110,7 @@ static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra, bool is_p
if (is_prop_edit && count > 0) {
return count_all;
}
- else {
- return count;
- }
+ return count;
}
/* fully select selected beztriples, but only include if it's on the right side of cfra */
@@ -141,9 +137,7 @@ static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra, boo
if (is_prop_edit && count > 0) {
return count_all;
}
- else {
- return count;
- }
+ return count;
}
/* This function assigns the information to transdata */
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index f721ed0b866..9885c8fc3a6 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -115,7 +115,9 @@ static void autokeyframe_pose(
ToolSettings *ts = scene->toolsettings;
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
ListBase nla_cache = {NULL, NULL};
- float cfra = (float)CFRA;
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
eInsertKeyFlags flag = 0;
/* flag is initialized from UserPref keyframing settings
@@ -146,7 +148,8 @@ static void autokeyframe_pose(
/* only insert into active keyingset? */
if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (active_ks)) {
/* run the active Keying Set on the current datasource */
- ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
/* only insert into available channels? */
else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
@@ -169,7 +172,7 @@ static void autokeyframe_pose(
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path,
fcu->array_index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
&nla_cache,
flag);
@@ -220,21 +223,25 @@ static void autokeyframe_pose(
if (do_loc) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_rot) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_scale) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
}
/* insert keyframe in all (transform) channels */
else {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
/* free temp info */
diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c
index 37e37072ed7..65b2c9f9382 100644
--- a/source/blender/editors/transform/transform_convert_curve.c
+++ b/source/blender/editors/transform/transform_convert_curve.c
@@ -350,12 +350,14 @@ void createTransCurveVerts(TransInfo *t)
(void)hdata; /* quiet warning */
}
else if (is_prop_edit && head != tail) {
- calc_distanceCurveVerts(head, tail - 1);
- head = tail;
+ tail->flag |= TD_NOTCONNECTED;
+ td++;
+ tail++;
}
}
if (is_prop_edit && head != tail) {
- calc_distanceCurveVerts(head, tail - 1);
+ bool cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0;
+ calc_distanceCurveVerts(head, tail - 1, cyclic);
}
/* TODO - in the case of tilt and radius we can also avoid allocating the
@@ -425,12 +427,14 @@ void createTransCurveVerts(TransInfo *t)
}
}
else if (is_prop_edit && head != tail) {
- calc_distanceCurveVerts(head, tail - 1);
- head = tail;
+ tail->flag |= TD_NOTCONNECTED;
+ td++;
+ tail++;
}
}
if (is_prop_edit && head != tail) {
- calc_distanceCurveVerts(head, tail - 1);
+ bool cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0;
+ calc_distanceCurveVerts(head, tail - 1, cyclic);
}
}
}
diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c
index 22261b9bbd8..84885dd8c49 100644
--- a/source/blender/editors/transform/transform_convert_gpencil.c
+++ b/source/blender/editors/transform/transform_convert_gpencil.c
@@ -104,7 +104,7 @@ void createTransGPencil(bContext *C, TransInfo *t)
/* initialize falloff curve */
if (is_multiedit) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_falloff);
}
/* First Pass: Count the number of data-points required for the strokes,
@@ -354,7 +354,7 @@ void createTransGPencil(bContext *C, TransInfo *t)
/* March over these points, and calculate the proportional editing distances */
if (is_prop_edit && (head != tail)) {
- calc_distanceCurveVerts(head, tail - 1);
+ calc_distanceCurveVerts(head, tail - 1, false);
}
}
}
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 5e27fd3c4ce..6f447997fb0 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -28,6 +28,7 @@
#include "BLI_alloca.h"
#include "BLI_bitmap.h"
+#include "BLI_ghash.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
@@ -50,6 +51,8 @@
/* Own include. */
#include "transform_convert.h"
+#define USE_FACE_SUBSTITUTE
+
/* -------------------------------------------------------------------- */
/** \name Island Creation
*
@@ -469,7 +472,7 @@ static void editmesh_mirror_data_calc(BMEditMesh *em,
BMIter iter;
int i, flag, totvert = bm->totvert;
- vert_map = MEM_mallocN(totvert * sizeof(*vert_map), __func__);
+ vert_map = MEM_callocN(totvert * sizeof(*vert_map), __func__);
float select_sum[3] = {0};
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
@@ -495,7 +498,8 @@ static void editmesh_mirror_data_calc(BMEditMesh *em,
uint mirror_elem_len = 0;
int *index[3] = {NULL, NULL, NULL};
- bool test_selected_only = use_select && (mirror_axis[0] + mirror_axis[1] + mirror_axis[2]) == 1;
+ bool is_single_mirror_axis = (mirror_axis[0] + mirror_axis[1] + mirror_axis[2]) == 1;
+ bool test_selected_only = use_select && is_single_mirror_axis;
for (int a = 0; a < 3; a++) {
if (!mirror_axis[a]) {
continue;
@@ -520,13 +524,23 @@ static void editmesh_mirror_data_calc(BMEditMesh *em,
if (!is_in_quadrant_v3(eve->co, quadrant, TRANSFORM_MAXDIST_MIRROR)) {
continue;
}
+ if (vert_map[i_mirr].flag != 0) {
+ /* One mirror per element.
+ * It can happen when vertices occupy the same position. */
+ continue;
+ }
vert_map[i_mirr] = (struct MirrorDataVert){i, flag};
mirror_elem_len++;
}
}
- if (mirror_elem_len) {
+ if (!mirror_elem_len) {
+ MEM_freeN(vert_map);
+ vert_map = NULL;
+ }
+ else if (!is_single_mirror_axis) {
+ /* Adjustment for elements that are mirrors of mirrored elements. */
for (int a = 0; a < 3; a++) {
if (!mirror_axis[a]) {
continue;
@@ -548,10 +562,6 @@ static void editmesh_mirror_data_calc(BMEditMesh *em,
}
}
}
- else {
- MEM_freeN(vert_map);
- vert_map = NULL;
- }
MEM_SAFE_FREE(index[0]);
MEM_SAFE_FREE(index[1]);
@@ -830,101 +840,100 @@ void createTransEditVerts(TransInfo *t)
if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
continue;
}
- else {
- int island_index = -1;
- if (island_data.island_vert_map) {
- const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a;
- island_index = island_data.island_vert_map[connected_index];
- }
- if (mirror_data.vert_map && mirror_data.vert_map[a].index != -1) {
- int elem_index = mirror_data.vert_map[a].index;
- BMVert *v_src = BM_vert_at_index(bm, elem_index);
+ int island_index = -1;
+ if (island_data.island_vert_map) {
+ const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a;
+ island_index = island_data.island_vert_map[connected_index];
+ }
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- mirror_data.vert_map[a].flag |= TD_SELECTED;
- }
+ if (mirror_data.vert_map && mirror_data.vert_map[a].index != -1) {
+ int elem_index = mirror_data.vert_map[a].index;
+ BMVert *v_src = BM_vert_at_index(bm, elem_index);
+
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ mirror_data.vert_map[a].flag |= TD_SELECTED;
+ }
- td_mirror->extra = eve;
- td_mirror->loc = eve->co;
- copy_v3_v3(td_mirror->iloc, eve->co);
- td_mirror->flag = mirror_data.vert_map[a].flag;
- td_mirror->loc_src = v_src->co;
- transdata_center_get(&island_data, island_index, td_mirror->iloc, td_mirror->center);
+ td_mirror->extra = eve;
+ td_mirror->loc = eve->co;
+ copy_v3_v3(td_mirror->iloc, eve->co);
+ td_mirror->flag = mirror_data.vert_map[a].flag;
+ td_mirror->loc_src = v_src->co;
+ transdata_center_get(&island_data, island_index, td_mirror->iloc, td_mirror->center);
- td_mirror++;
+ td_mirror++;
+ }
+ else if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ float *bweight = (cd_vert_bweight_offset != -1) ?
+ BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) :
+ NULL;
+
+ /* Do not use the island center in case we are using islands
+ * only to get axis for snap/rotate to normal... */
+ VertsToTransData(t, tob, tx, em, eve, bweight, &island_data, island_index);
+ if (tx) {
+ tx++;
}
- else if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- float *bweight = (cd_vert_bweight_offset != -1) ?
- BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) :
- NULL;
-
- /* Do not use the island center in case we are using islands
- * only to get axis for snap/rotate to normal... */
- VertsToTransData(t, tob, tx, em, eve, bweight, &island_data, island_index);
- if (tx) {
- tx++;
- }
- /* selected */
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- tob->flag |= TD_SELECTED;
- }
+ /* selected */
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ tob->flag |= TD_SELECTED;
+ }
- if (prop_mode) {
- if (prop_mode & T_PROP_CONNECTED) {
- tob->dist = dists[a];
- }
- else {
- tob->flag |= TD_NOTCONNECTED;
- tob->dist = FLT_MAX;
- }
+ if (prop_mode) {
+ if (prop_mode & T_PROP_CONNECTED) {
+ tob->dist = dists[a];
}
+ else {
+ tob->flag |= TD_NOTCONNECTED;
+ tob->dist = FLT_MAX;
+ }
+ }
- /* CrazySpace */
- const bool use_quats = quats && BM_elem_flag_test(eve, BM_ELEM_TAG);
- if (use_quats || defmats) {
- float mat[3][3], qmat[3][3], imat[3][3];
+ /* CrazySpace */
+ const bool use_quats = quats && BM_elem_flag_test(eve, BM_ELEM_TAG);
+ if (use_quats || defmats) {
+ float mat[3][3], qmat[3][3], imat[3][3];
- /* Use both or either quat and defmat correction. */
- if (use_quats) {
- quat_to_mat3(qmat, quats[BM_elem_index_get(eve)]);
+ /* Use both or either quat and defmat correction. */
+ if (use_quats) {
+ quat_to_mat3(qmat, quats[BM_elem_index_get(eve)]);
- if (defmats) {
- mul_m3_series(mat, defmats[a], qmat, mtx);
- }
- else {
- mul_m3_m3m3(mat, mtx, qmat);
- }
+ if (defmats) {
+ mul_m3_series(mat, defmats[a], qmat, mtx);
}
else {
- mul_m3_m3m3(mat, mtx, defmats[a]);
+ mul_m3_m3m3(mat, mtx, qmat);
}
-
- invert_m3_m3(imat, mat);
-
- copy_m3_m3(tob->smtx, imat);
- copy_m3_m3(tob->mtx, mat);
}
else {
- copy_m3_m3(tob->smtx, smtx);
- copy_m3_m3(tob->mtx, mtx);
+ mul_m3_m3m3(mat, mtx, defmats[a]);
}
- if (tc->use_mirror_axis_any) {
- if (tc->use_mirror_axis_x && fabsf(tob->loc[0]) < TRANSFORM_MAXDIST_MIRROR) {
- tob->flag |= TD_MIRROR_EDGE_X;
- }
- if (tc->use_mirror_axis_y && fabsf(tob->loc[1]) < TRANSFORM_MAXDIST_MIRROR) {
- tob->flag |= TD_MIRROR_EDGE_Y;
- }
- if (tc->use_mirror_axis_z && fabsf(tob->loc[2]) < TRANSFORM_MAXDIST_MIRROR) {
- tob->flag |= TD_MIRROR_EDGE_Z;
- }
- }
+ invert_m3_m3(imat, mat);
- tob++;
+ copy_m3_m3(tob->smtx, imat);
+ copy_m3_m3(tob->mtx, mat);
}
+ else {
+ copy_m3_m3(tob->smtx, smtx);
+ copy_m3_m3(tob->mtx, mtx);
+ }
+
+ if (tc->use_mirror_axis_any) {
+ if (tc->use_mirror_axis_x && fabsf(tob->loc[0]) < TRANSFORM_MAXDIST_MIRROR) {
+ tob->flag |= TD_MIRROR_EDGE_X;
+ }
+ if (tc->use_mirror_axis_y && fabsf(tob->loc[1]) < TRANSFORM_MAXDIST_MIRROR) {
+ tob->flag |= TD_MIRROR_EDGE_Y;
+ }
+ if (tc->use_mirror_axis_z && fabsf(tob->loc[2]) < TRANSFORM_MAXDIST_MIRROR) {
+ tob->flag |= TD_MIRROR_EDGE_Z;
+ }
+ }
+
+ tob++;
}
}
@@ -958,41 +967,44 @@ void createTransEditVerts(TransInfo *t)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name CustomData Layer Correction (for meshes)
+/** \name CustomData Layer Correction
*
* \{ */
-struct TransCustomDataLayerVert {
- BMVert *v;
- float co_orig_3d[3];
+struct TransCustomDataMergeGroup {
+ /** map {BMVert: TransCustomDataLayerVert} */
struct LinkNode **cd_loop_groups;
};
struct TransCustomDataLayer {
BMesh *bm;
+ struct MemArena *arena;
- int cd_loop_mdisp_offset;
-
- /** map {BMVert: TransCustomDataLayerVert} */
- struct GHash *origverts;
struct GHash *origfaces;
struct BMesh *bm_origfaces;
- struct MemArena *arena;
- /** Number of math BMLoop layers. */
- int layer_math_map_num;
- /** Array size of 'layer_math_map_num'
- * maps TransCustomDataLayerVert.cd_group index to absolute CustomData layer index */
- int *layer_math_map;
-
- /* Array with all elements transformed. */
- struct TransCustomDataLayerVert *data;
- int data_len;
+ /* Special handle for multi-resolution. */
+ int cd_loop_mdisp_offset;
+
+ /* Optionally merge custom-data groups (this keeps UVs connected for example). */
+ struct {
+ /** map {BMVert: TransDataBasic} */
+ struct GHash *origverts;
+ struct TransCustomDataMergeGroup *data;
+ int data_len;
+ /** Array size of 'layer_math_map_len'
+ * maps #TransCustomDataLayerVert.cd_group index to absolute #CustomData layer index */
+ int *customdatalayer_map;
+ /** Number of math BMLoop layers. */
+ int customdatalayer_map_len;
+ } merge_group;
+
+ bool use_merge_group;
};
-static void trans_mesh_customdata_free_cb(struct TransInfo *UNUSED(t),
- struct TransDataContainer *UNUSED(tc),
- struct TransCustomData *custom_data)
+static void mesh_customdatacorrect_free_cb(struct TransInfo *UNUSED(t),
+ struct TransDataContainer *UNUSED(tc),
+ struct TransCustomData *custom_data)
{
struct TransCustomDataLayer *tcld = custom_data->data;
bmesh_edit_end(tcld->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
@@ -1003,94 +1015,208 @@ static void trans_mesh_customdata_free_cb(struct TransInfo *UNUSED(t),
if (tcld->origfaces) {
BLI_ghash_free(tcld->origfaces, NULL, NULL);
}
- if (tcld->origverts) {
- BLI_ghash_free(tcld->origverts, NULL, NULL);
+ if (tcld->merge_group.origverts) {
+ BLI_ghash_free(tcld->merge_group.origverts, NULL, NULL);
}
if (tcld->arena) {
BLI_memarena_free(tcld->arena);
}
- if (tcld->layer_math_map) {
- MEM_freeN(tcld->layer_math_map);
+ if (tcld->merge_group.customdatalayer_map) {
+ MEM_freeN(tcld->merge_group.customdatalayer_map);
}
MEM_freeN(tcld);
custom_data->data = NULL;
}
-static void create_trans_vert_customdata_layer(BMVert *v,
- struct TransCustomDataLayer *tcld,
- struct TransCustomDataLayerVert *r_tcld_vert)
+#ifdef USE_FACE_SUBSTITUTE
+
+# define FACE_SUBSTITUTE_INDEX INT_MIN
+
+/**
+ * Search for a neighboring face with area and preferably without selected vertex.
+ * Used to replace area-less faces in custom-data correction.
+ */
+static BMFace *mesh_customdatacorrect_find_best_face_substitute(BMFace *f)
{
+ BMFace *best_face = NULL;
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ BMLoop *l_radial_next = l->radial_next;
+ BMFace *f_test = l_radial_next->f;
+ if (f_test == f) {
+ continue;
+ }
+ if (is_zero_v3(f_test->no)) {
+ continue;
+ }
+
+ /* Check the loops edge isn't selected. */
+ if (!BM_elem_flag_test(l_radial_next->v, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(l_radial_next->next->v, BM_ELEM_SELECT)) {
+ /* Prefer edges with unselected vertices.
+ * Useful for extrude. */
+ best_face = f_test;
+ break;
+ }
+ if (best_face == NULL) {
+ best_face = f_test;
+ }
+ }
+ return best_face;
+}
+
+static void mesh_customdatacorrect_face_substitute_set(struct TransCustomDataLayer *tcld,
+ BMFace *f,
+ BMFace *f_copy)
+{
+ BLI_assert(is_zero_v3(f->no));
BMesh *bm = tcld->bm;
+ /* It is impossible to calculate the loops weights of a face without area.
+ * Find a substitute. */
+ BMFace *f_substitute = mesh_customdatacorrect_find_best_face_substitute(f);
+ if (f_substitute) {
+ /* Copy the custom-data from the substitute face. */
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_loop_interp_from_face(bm, l_iter, f_substitute, false, false);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* Use the substitute face as the reference during the transformation. */
+ BMFace *f_substitute_copy = BM_face_copy(tcld->bm_origfaces, bm, f_substitute, true, true);
+
+ /* Hack: reference substitute face in `f_copy->no`.
+ * `tcld->origfaces` is already used to restore the initial value. */
+ BM_elem_index_set(f_copy, FACE_SUBSTITUTE_INDEX);
+ *((BMFace **)&f_copy->no[0]) = f_substitute_copy;
+ }
+}
+
+static BMFace *mesh_customdatacorrect_face_substitute_get(BMFace *f_copy)
+{
+ BLI_assert(BM_elem_index_get(f_copy) == FACE_SUBSTITUTE_INDEX);
+ return *((BMFace **)&f_copy->no[0]);
+}
+
+#endif /* USE_FACE_SUBSTITUTE */
+
+static void mesh_customdatacorrect_init_vert(struct TransCustomDataLayer *tcld,
+ struct TransDataBasic *td,
+ const int index)
+{
+ BMesh *bm = tcld->bm;
+ BMVert *v = td->extra;
BMIter liter;
int j, l_num;
float *loop_weights;
- /* copy face data */
// BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, v);
l_num = liter.count;
- loop_weights = BLI_array_alloca(loop_weights, l_num);
+ loop_weights = tcld->use_merge_group ? BLI_array_alloca(loop_weights, l_num) : NULL;
for (j = 0; j < l_num; j++) {
BMLoop *l = BM_iter_step(&liter);
BMLoop *l_prev, *l_next;
+
+ /* Generic custom-data correction. Copy face data. */
void **val_p;
if (!BLI_ghash_ensure_p(tcld->origfaces, l->f, &val_p)) {
BMFace *f_copy = BM_face_copy(tcld->bm_origfaces, bm, l->f, true, true);
*val_p = f_copy;
+#ifdef USE_FACE_SUBSTITUTE
+ if (is_zero_v3(l->f->no)) {
+ mesh_customdatacorrect_face_substitute_set(tcld, l->f, f_copy);
+ }
+#endif
}
- if ((l_prev = BM_loop_find_prev_nodouble(l, l->next, FLT_EPSILON)) &&
- (l_next = BM_loop_find_next_nodouble(l, l_prev, FLT_EPSILON))) {
- loop_weights[j] = angle_v3v3v3(l_prev->v->co, l->v->co, l_next->v->co);
- }
- else {
- loop_weights[j] = 0.0f;
+ if (tcld->use_merge_group) {
+ if ((l_prev = BM_loop_find_prev_nodouble(l, l->next, FLT_EPSILON)) &&
+ (l_next = BM_loop_find_next_nodouble(l, l_prev, FLT_EPSILON))) {
+ loop_weights[j] = angle_v3v3v3(l_prev->v->co, l->v->co, l_next->v->co);
+ }
+ else {
+ loop_weights[j] = 0.0f;
+ }
}
}
- /* store cd_loop_groups */
- if (tcld->layer_math_map_num && (l_num != 0)) {
- r_tcld_vert->cd_loop_groups = BLI_memarena_alloc(tcld->arena,
- tcld->layer_math_map_num * sizeof(void *));
- for (j = 0; j < tcld->layer_math_map_num; j++) {
- const int layer_nr = tcld->layer_math_map[j];
- r_tcld_vert->cd_loop_groups[j] = BM_vert_loop_groups_data_layer_create(
- bm, v, layer_nr, loop_weights, tcld->arena);
+ if (tcld->use_merge_group) {
+ /* Store cd_loop_groups. */
+ struct TransCustomDataMergeGroup *merge_data = &tcld->merge_group.data[index];
+ if (l_num != 0) {
+ merge_data->cd_loop_groups = BLI_memarena_alloc(
+ tcld->arena, tcld->merge_group.customdatalayer_map_len * sizeof(void *));
+ for (j = 0; j < tcld->merge_group.customdatalayer_map_len; j++) {
+ const int layer_nr = tcld->merge_group.customdatalayer_map[j];
+ merge_data->cd_loop_groups[j] = BM_vert_loop_groups_data_layer_create(
+ bm, v, layer_nr, loop_weights, tcld->arena);
+ }
}
+ else {
+ merge_data->cd_loop_groups = NULL;
+ }
+
+ BLI_ghash_insert(tcld->merge_group.origverts, v, td);
}
- else {
- r_tcld_vert->cd_loop_groups = NULL;
- }
+}
+
+static void mesh_customdatacorrect_init_container_generic(TransDataContainer *UNUSED(tc),
+ struct TransCustomDataLayer *tcld)
+{
+ BMesh *bm = tcld->bm;
+
+ struct GHash *origfaces = BLI_ghash_ptr_new(__func__);
+ struct BMesh *bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default,
+ &((struct BMeshCreateParams){
+ .use_toolflags = false,
+ }));
- r_tcld_vert->v = v;
- copy_v3_v3(r_tcld_vert->co_orig_3d, v->co);
- BLI_ghash_insert(tcld->origverts, v, r_tcld_vert);
+ /* We need to have matching custom-data. */
+ BM_mesh_copy_init_customdata(bm_origfaces, bm, NULL);
+ tcld->origfaces = origfaces;
+ tcld->bm_origfaces = bm_origfaces;
+
+ bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+ tcld->cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
}
-static void trans_mesh_customdata_correction_init_container(TransInfo *t, TransDataContainer *tc)
+static void mesh_customdatacorrect_init_container_merge_group(TransDataContainer *tc,
+ struct TransCustomDataLayer *tcld)
{
- if (tc->custom.type.data) {
- /* Custom data correction has initiated before. */
- BLI_assert(tc->custom.type.free_cb == trans_mesh_customdata_free_cb);
- return;
+ BMesh *bm = tcld->bm;
+ BLI_assert(CustomData_has_math(&bm->ldata));
+
+ /* TODO: We don't need `layer_math_map` when there are no loops linked
+ * to one of the sliding vertices. */
+
+ /* Over allocate, only 'math' layers are indexed. */
+ int *customdatalayer_map = MEM_mallocN(sizeof(int) * bm->ldata.totlayer, __func__);
+ int layer_math_map_len = 0;
+ for (int i = 0; i < bm->ldata.totlayer; i++) {
+ if (CustomData_layer_has_math(&bm->ldata, i)) {
+ customdatalayer_map[layer_math_map_len++] = i;
+ }
}
+ BLI_assert(layer_math_map_len != 0);
+
+ tcld->merge_group.data_len = tc->data_len + tc->data_mirror_len;
+ tcld->merge_group.customdatalayer_map = customdatalayer_map;
+ tcld->merge_group.customdatalayer_map_len = layer_math_map_len;
+ tcld->merge_group.origverts = BLI_ghash_ptr_new_ex(__func__, tcld->merge_group.data_len);
+ tcld->merge_group.data = BLI_memarena_alloc(
+ tcld->arena, tcld->merge_group.data_len * sizeof(*tcld->merge_group.data));
+}
- if (!ELEM(t->mode,
- TFM_TRANSLATION,
- TFM_ROTATION,
- TFM_RESIZE,
- TFM_TOSPHERE,
- TFM_SHEAR,
- TFM_BEND,
- TFM_SHRINKFATTEN,
- TFM_TRACKBALL,
- TFM_PUSHPULL,
- TFM_ALIGN,
- TFM_EDGE_SLIDE,
- TFM_VERT_SLIDE)) {
- /* Currently only modes that change the position of vertices are supported. */
- return;
+static void mesh_customdatacorrect_init_container(TransDataContainer *tc,
+ const bool use_merge_group)
+{
+ if (tc->custom.type.data) {
+ /* The custom-data correction has been initiated before.
+ * Free since some modes have different settings. */
+ mesh_customdatacorrect_free_cb(NULL, tc, &tc->custom.type);
}
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
@@ -1099,89 +1225,79 @@ static void trans_mesh_customdata_correction_init_container(TransInfo *t, TransD
if (bm->shapenr > 1) {
/* Don't do this at all for non-basis shape keys, too easy to
* accidentally break uv maps or vertex colors then */
- /* create copies of faces for customdata projection. */
+ /* create copies of faces for custom-data projection. */
return;
}
-
- const bool has_layer_math = CustomData_has_math(&bm->ldata);
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- if (!has_layer_math && (cd_loop_mdisp_offset == -1)) {
+ if (!CustomData_has_math(&bm->ldata) && !CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
+ /* There is no custom-data to correct. */
return;
}
- bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+ struct TransCustomDataLayer *tcld = MEM_callocN(sizeof(*tcld), __func__);
+ tcld->bm = bm;
+ tcld->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- struct GHash *origfaces = BLI_ghash_ptr_new(__func__);
- struct BMesh *bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default,
- &((struct BMeshCreateParams){
- .use_toolflags = false,
- }));
+ /* Init `cd_loop_mdisp_offset` to -1 to avoid problems with a valid index. */
+ tcld->cd_loop_mdisp_offset = -1;
+ tcld->use_merge_group = use_merge_group;
- /* we need to have matching customdata */
- BM_mesh_copy_init_customdata(bm_origfaces, bm, NULL);
+ mesh_customdatacorrect_init_container_generic(tc, tcld);
- int *layer_math_map = NULL;
- int layer_math_map_len = 0;
- {
- /* TODO: We don't need `sod->layer_math_map` when there are no loops linked
- * to one of the sliding vertices. */
- if (has_layer_math) {
- /* over alloc, only 'math' layers are indexed */
- layer_math_map = MEM_mallocN(bm->ldata.totlayer * sizeof(int), __func__);
- for (int i = 0; i < bm->ldata.totlayer; i++) {
- if (CustomData_layer_has_math(&bm->ldata, i)) {
- layer_math_map[layer_math_map_len++] = i;
- }
- }
- BLI_assert(layer_math_map_len != 0);
- }
+ if (tcld->use_merge_group) {
+ mesh_customdatacorrect_init_container_merge_group(tc, tcld);
}
- struct TransCustomDataLayer *tcld = MEM_mallocN(sizeof(*tcld), __func__);
- int data_len = tc->data_len + tc->data_mirror_len;
-
- tcld->bm = bm;
- tcld->origfaces = origfaces;
- tcld->bm_origfaces = bm_origfaces;
- tcld->cd_loop_mdisp_offset = cd_loop_mdisp_offset;
- tcld->layer_math_map = layer_math_map;
- tcld->layer_math_map_num = layer_math_map_len;
- tcld->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- tcld->origverts = BLI_ghash_ptr_new_ex(__func__, data_len);
- tcld->data = BLI_memarena_alloc(tcld->arena, data_len * sizeof(*tcld->data));
- tcld->data_len = data_len;
-
{
/* Setup Verts. */
- struct TransCustomDataLayerVert *tcld_vert_iter = &tcld->data[0];
+ int i = 0;
TransData *tob = tc->data;
- for (int i = tc->data_len; i--; tob++, tcld_vert_iter++) {
- BMVert *v = tob->extra;
- create_trans_vert_customdata_layer(v, tcld, tcld_vert_iter);
+ for (int j = tc->data_len; j--; tob++, i++) {
+ mesh_customdatacorrect_init_vert(tcld, (TransDataBasic *)tob, i);
}
TransDataMirror *td_mirror = tc->data_mirror;
- for (int i = tc->data_mirror_len; i--; td_mirror++, tcld_vert_iter++) {
- BMVert *v = td_mirror->extra;
- create_trans_vert_customdata_layer(v, tcld, tcld_vert_iter);
+ for (int j = tc->data_mirror_len; j--; td_mirror++, i++) {
+ mesh_customdatacorrect_init_vert(tcld, (TransDataBasic *)td_mirror, i);
}
}
tc->custom.type.data = tcld;
- tc->custom.type.free_cb = trans_mesh_customdata_free_cb;
+ tc->custom.type.free_cb = mesh_customdatacorrect_free_cb;
}
-void trans_mesh_customdata_correction_init(TransInfo *t)
+void mesh_customdatacorrect_init(TransInfo *t)
{
- const char uvcalc_correct_flag = ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) ?
- UVCALC_TRANSFORM_CORRECT_SLIDE :
- UVCALC_TRANSFORM_CORRECT;
-
- if (t->settings->uvcalc_flag & uvcalc_correct_flag) {
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- trans_mesh_customdata_correction_init_container(t, tc);
+ bool use_merge_group = false;
+ if (ELEM(t->mode, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
+ if (!(t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT_SLIDE)) {
+ /* No custom-data correction. */
+ return;
}
+ use_merge_group = true;
+ }
+ else if (ELEM(t->mode,
+ TFM_TRANSLATION,
+ TFM_ROTATION,
+ TFM_RESIZE,
+ TFM_TOSPHERE,
+ TFM_SHEAR,
+ TFM_BEND,
+ TFM_SHRINKFATTEN,
+ TFM_TRACKBALL,
+ TFM_PUSHPULL,
+ TFM_ALIGN)) {
+ {
+ if (!(t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
+ /* No custom-data correction. */
+ return;
+ }
+ use_merge_group = (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT_KEEP_CONNECTED) != 0;
+ }
+ }
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ mesh_customdatacorrect_init_container(tc, use_merge_group);
}
}
@@ -1190,23 +1306,24 @@ void trans_mesh_customdata_correction_init(TransInfo *t)
*/
static const float *trans_vert_orig_co_get(struct TransCustomDataLayer *tcld, BMVert *v)
{
- struct TransCustomDataLayerVert *tcld_vert = BLI_ghash_lookup(tcld->origverts, v);
- return tcld_vert ? tcld_vert->co_orig_3d : v->co;
+ TransDataBasic *td = BLI_ghash_lookup(tcld->merge_group.origverts, v);
+ return td ? td->iloc : v->co;
}
-static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLayer *tcld,
- struct TransCustomDataLayerVert *tcld_vert,
- bool is_final)
+static void mesh_customdatacorrect_apply_vert(struct TransCustomDataLayer *tcld,
+ struct TransDataBasic *td,
+ struct TransCustomDataMergeGroup *merge_data,
+ bool do_loop_mdisps)
{
BMesh *bm = tcld->bm;
- BMVert *v = tcld_vert->v;
- const float *co_orig_3d = tcld_vert->co_orig_3d;
+ BMVert *v = td->extra;
+ const float *co_orig_3d = td->iloc;
BMIter liter;
int j, l_num;
float *loop_weights;
const bool is_moved = (len_squared_v3v3(v->co, co_orig_3d) > FLT_EPSILON);
- const bool do_loop_weight = is_moved && tcld->layer_math_map_num;
+ const bool do_loop_weight = is_moved && tcld->merge_group.customdatalayer_map_len;
const float *v_proj_axis = v->no;
/* original (l->prev, l, l->next) projections for each loop ('l' remains unchanged) */
float v_proj[3][3];
@@ -1225,6 +1342,14 @@ static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLa
f_copy = BLI_ghash_lookup(tcld->origfaces, l->f);
+#ifdef USE_FACE_SUBSTITUTE
+ /* In some faces it is not possible to calculate interpolation,
+ * so we use a substitute. */
+ if (BM_elem_index_get(f_copy) == FACE_SUBSTITUTE_INDEX) {
+ f_copy = mesh_customdatacorrect_face_substitute_get(f_copy);
+ }
+#endif
+
/* only loop data, no vertex data since that contains shape keys,
* and we do not want to mess up other shape keys */
BM_loop_interp_from_face(bm, l, f_copy, false, false);
@@ -1276,17 +1401,20 @@ static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLa
}
}
- struct LinkNode **cd_loop_groups = tcld_vert->cd_loop_groups;
- if (tcld->layer_math_map_num && cd_loop_groups) {
- if (do_loop_weight) {
- for (j = 0; j < tcld->layer_math_map_num; j++) {
- BM_vert_loop_groups_data_layer_merge_weights(
- bm, cd_loop_groups[j], tcld->layer_math_map[j], loop_weights);
+ if (tcld->use_merge_group) {
+ struct LinkNode **cd_loop_groups = merge_data->cd_loop_groups;
+ if (tcld->merge_group.customdatalayer_map_len && cd_loop_groups) {
+ if (do_loop_weight) {
+ for (j = 0; j < tcld->merge_group.customdatalayer_map_len; j++) {
+ BM_vert_loop_groups_data_layer_merge_weights(
+ bm, cd_loop_groups[j], tcld->merge_group.customdatalayer_map[j], loop_weights);
+ }
}
- }
- else {
- for (j = 0; j < tcld->layer_math_map_num; j++) {
- BM_vert_loop_groups_data_layer_merge(bm, cd_loop_groups[j], tcld->layer_math_map[j]);
+ else {
+ for (j = 0; j < tcld->merge_group.customdatalayer_map_len; j++) {
+ BM_vert_loop_groups_data_layer_merge(
+ bm, cd_loop_groups[j], tcld->merge_group.customdatalayer_map[j]);
+ }
}
}
}
@@ -1296,8 +1424,8 @@ static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLa
* Interpolate from every other loop (not ideal)
* However values will only be taken from loops which overlap other mdisps.
* */
- const bool do_loop_mdisps = is_moved && is_final && (tcld->cd_loop_mdisp_offset != -1);
- if (do_loop_mdisps) {
+ const bool update_loop_mdisps = is_moved && do_loop_mdisps && (tcld->cd_loop_mdisp_offset != -1);
+ if (update_loop_mdisps) {
float(*faces_center)[3] = BLI_array_alloca(faces_center, l_num);
BMLoop *l;
@@ -1326,19 +1454,63 @@ static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLa
}
}
-static void trans_mesh_customdata_correction_apply(struct TransDataContainer *tc, bool is_final)
+static void mesh_customdatacorrect_apply(TransInfo *t, bool is_final)
{
- struct TransCustomDataLayer *tcld = tc->custom.type.data;
- if (!tcld) {
- return;
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ if (!tc->custom.type.data) {
+ continue;
+ }
+ struct TransCustomDataLayer *tcld = tc->custom.type.data;
+ const bool use_merge_group = tcld->use_merge_group;
+
+ struct TransCustomDataMergeGroup *merge_data = tcld->merge_group.data;
+ TransData *tob = tc->data;
+ for (int i = tc->data_len; i--; tob++) {
+ mesh_customdatacorrect_apply_vert(tcld, (TransDataBasic *)tob, merge_data, is_final);
+
+ if (use_merge_group) {
+ merge_data++;
+ }
+ }
+
+ TransDataMirror *td_mirror = tc->data_mirror;
+ for (int i = tc->data_mirror_len; i--; td_mirror++) {
+ mesh_customdatacorrect_apply_vert(tcld, (TransDataBasic *)td_mirror, merge_data, is_final);
+
+ if (use_merge_group) {
+ merge_data++;
+ }
+ }
}
+}
- const bool has_mdisps = (tcld->cd_loop_mdisp_offset != -1);
- struct TransCustomDataLayerVert *tcld_vert_iter = &tcld->data[0];
+static void mesh_customdatacorrect_restore(struct TransInfo *t)
+{
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ struct TransCustomDataLayer *tcld = tc->custom.type.data;
+ if (!tcld) {
+ continue;
+ }
- for (int i = tcld->data_len; i--; tcld_vert_iter++) {
- if (tcld_vert_iter->cd_loop_groups || has_mdisps) {
- trans_mesh_customdata_correction_apply_vert(tcld, tcld_vert_iter, is_final);
+ BMesh *bm = tcld->bm;
+ BMesh *bm_copy = tcld->bm_origfaces;
+
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, tcld->origfaces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BMFace *f_copy = BLI_ghashIterator_getValue(&gh_iter);
+ BLI_assert(f->len == f_copy->len);
+
+ BMLoop *l_iter, *l_first, *l_copy;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ l_copy = BM_FACE_FIRST_LOOP(f_copy);
+ do {
+ /* TODO: Restore only the elements that transform. */
+ BM_elem_attrs_copy(bm_copy, bm, l_copy, l_iter);
+ l_copy = l_copy->next;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ BM_elem_attrs_copy_ex(bm_copy, bm, f_copy, f, BM_ELEM_SELECT, CD_MASK_NORMAL);
}
}
}
@@ -1389,8 +1561,9 @@ static void transform_apply_to_mirror(TransInfo *t)
void recalcData_mesh(TransInfo *t)
{
+ bool is_cancelling = t->state == TRANS_CANCEL;
/* mirror modifier clipping? */
- if (t->state != TRANS_CANCEL) {
+ if (!is_cancelling) {
/* apply clipping after so we never project past the clip plane [#25423] */
applyProject(t);
clipMirrorModifier(t);
@@ -1398,11 +1571,14 @@ void recalcData_mesh(TransInfo *t)
if ((t->flag & T_NO_MIRROR) == 0 && (t->options & CTX_NO_MIRROR) == 0) {
transform_apply_to_mirror(t);
}
+
+ mesh_customdatacorrect_apply(t, false);
+ }
+ else {
+ mesh_customdatacorrect_restore(t);
}
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- trans_mesh_customdata_correction_apply(tc, false);
-
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
EDBM_mesh_normals_update(em);
@@ -1417,16 +1593,14 @@ void recalcData_mesh(TransInfo *t)
void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
{
- const bool canceled = (t->state == TRANS_CANCEL);
- const bool use_automerge = !canceled && (t->flag & (T_AUTOMERGE | T_AUTOSPLIT)) != 0;
+ const bool is_cancelling = (t->state == TRANS_CANCEL);
+ const bool use_automerge = !is_cancelling && (t->flag & (T_AUTOMERGE | T_AUTOSPLIT)) != 0;
- if (TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.type.data != NULL) {
+ if (!is_cancelling && ELEM(t->mode, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
/* Handle multires re-projection, done
* on transform completion since it's
* really slow -joeedh. */
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- trans_mesh_customdata_correction_apply(tc, !canceled);
- }
+ mesh_customdatacorrect_apply(t, true);
}
if (use_automerge) {
diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c
index 41c09cd8ea2..632769c167e 100644
--- a/source/blender/editors/transform/transform_convert_mesh_uv.c
+++ b/source/blender/editors/transform/transform_convert_mesh_uv.c
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_bitmap.h"
+#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BKE_context.h"
@@ -51,12 +52,13 @@ static void UVsToTransData(const float aspect[2],
TransData2D *td2d,
float *uv,
const float *center,
+ float calc_dist,
bool selected)
{
- /* uv coords are scaled by aspects. this is needed for rotations and
- * proportional editing to be consistent with the stretched uv coords
- * that are displayed. this also means that for display and numinput,
- * and when the uv coords are flushed, these are converted each time */
+ /* UV coords are scaled by aspects. this is needed for rotations and
+ * proportional editing to be consistent with the stretched UV coords
+ * that are displayed. this also means that for display and number-input,
+ * and when the UV coords are flushed, these are converted each time. */
td2d->loc[0] = uv[0] * aspect[0];
td2d->loc[1] = uv[1] * aspect[1];
td2d->loc[2] = 0.0f;
@@ -79,12 +81,175 @@ static void UVsToTransData(const float aspect[2],
td->dist = 0.0;
}
else {
- td->dist = FLT_MAX;
+ td->dist = calc_dist;
}
unit_m3(td->mtx);
unit_m3(td->smtx);
}
+/**
+ * \param dists: Store the closest connected distance to selected vertices.
+ */
+static void uv_set_connectivity_distance(BMesh *bm, float *dists, const float aspect[2])
+{
+ /* Mostly copied from #editmesh_set_connectivity_distance. */
+ BLI_LINKSTACK_DECLARE(queue, BMLoop *);
+
+ /* Any BM_ELEM_TAG'd loop is added to 'queue_next', this makes sure that we don't add things
+ * twice. */
+ BLI_LINKSTACK_DECLARE(queue_next, BMLoop *);
+
+ BLI_LINKSTACK_INIT(queue);
+ BLI_LINKSTACK_INIT(queue_next);
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ BMIter fiter, liter;
+ BMVert *f;
+ BMLoop *l;
+
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ /* Visible faces was tagged in #createTransUVs. */
+ if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
+ continue;
+ }
+
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ float dist;
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+
+ bool uv_vert_sel = luv->flag & MLOOPUV_VERTSEL;
+
+ if (uv_vert_sel) {
+ BLI_LINKSTACK_PUSH(queue, l);
+ dist = 0.0f;
+ }
+ else {
+ dist = FLT_MAX;
+ }
+
+ /* Make sure all loops are in a clean tag state. */
+ BLI_assert(BM_elem_flag_test(l, BM_ELEM_TAG) == 0);
+
+ int loop_idx = BM_elem_index_get(l);
+
+ dists[loop_idx] = dist;
+ }
+ }
+
+ /* Need to be very careful of feedback loops here, store previous dist's to avoid feedback. */
+ float *dists_prev = MEM_dupallocN(dists);
+
+ do {
+ while ((l = BLI_LINKSTACK_POP(queue))) {
+ BLI_assert(dists[BM_elem_index_get(l)] != FLT_MAX);
+
+ BMLoop *l_other, *l_connected;
+ BMIter l_connected_iter;
+
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float l_uv[2];
+
+ copy_v2_v2(l_uv, luv->uv);
+ mul_v2_v2(l_uv, aspect);
+
+ BM_ITER_ELEM (l_other, &liter, l->f, BM_LOOPS_OF_FACE) {
+ if (l_other == l) {
+ continue;
+ }
+ float other_uv[2], edge_vec[2];
+ MLoopUV *luv_other = BM_ELEM_CD_GET_VOID_P(l_other, cd_loop_uv_offset);
+
+ copy_v2_v2(other_uv, luv_other->uv);
+ mul_v2_v2(other_uv, aspect);
+
+ sub_v2_v2v2(edge_vec, l_uv, other_uv);
+
+ const int i = BM_elem_index_get(l);
+ const int i_other = BM_elem_index_get(l_other);
+ float dist = len_v2(edge_vec) + dists_prev[i];
+
+ if (dist < dists[i_other]) {
+ dists[i_other] = dist;
+ }
+ else {
+ /* The face loop already has a shorter path to it. */
+ continue;
+ }
+
+ bool other_vert_sel, connected_vert_sel;
+
+ other_vert_sel = luv_other->flag & MLOOPUV_VERTSEL;
+
+ BM_ITER_ELEM (l_connected, &l_connected_iter, l_other->v, BM_LOOPS_OF_VERT) {
+ if (l_connected == l_other) {
+ continue;
+ }
+ /* Visible faces was tagged in #createTransUVs. */
+ if (!BM_elem_flag_test(l_connected->f, BM_ELEM_TAG)) {
+ continue;
+ }
+
+ MLoopUV *luv_connected = BM_ELEM_CD_GET_VOID_P(l_connected, cd_loop_uv_offset);
+ connected_vert_sel = luv_connected->flag & MLOOPUV_VERTSEL;
+
+ /* Check if this loop is connected in UV space.
+ * If the uv loops share the same selection state (if not, they are not connected as
+ * they have been ripped or other edit commands have separated them). */
+ bool connected = other_vert_sel == connected_vert_sel &&
+ equals_v2v2(luv_other->uv, luv_connected->uv);
+ if (!connected) {
+ continue;
+ }
+
+ /* The loop vert is occupying the same space, so it has the same distance. */
+ const int i_connected = BM_elem_index_get(l_connected);
+ dists[i_connected] = dist;
+
+ if (BM_elem_flag_test(l_connected, BM_ELEM_TAG) == 0) {
+ BM_elem_flag_enable(l_connected, BM_ELEM_TAG);
+ BLI_LINKSTACK_PUSH(queue_next, l_connected);
+ }
+ }
+ }
+ }
+
+ /* Clear elem flags for the next loop. */
+ for (LinkNode *lnk = queue_next; lnk; lnk = lnk->next) {
+ BMLoop *l_link = lnk->link;
+ const int i = BM_elem_index_get(l_link);
+
+ BM_elem_flag_disable(l_link, BM_ELEM_TAG);
+
+ /* Store all new dist values. */
+ dists_prev[i] = dists[i];
+ }
+
+ BLI_LINKSTACK_SWAP(queue, queue_next);
+
+ } while (BLI_LINKSTACK_SIZE(queue));
+
+#ifndef NDEBUG
+ /* Check that we didn't leave any loops tagged */
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ /* Visible faces was tagged in #createTransUVs. */
+ if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
+ continue;
+ }
+
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ BLI_assert(BM_elem_flag_test(l, BM_ELEM_TAG) == 0);
+ }
+ }
+#endif
+
+ BLI_LINKSTACK_FREE(queue);
+ BLI_LINKSTACK_FREE(queue_next);
+
+ MEM_freeN(dists_prev);
+}
+
void createTransUVs(bContext *C, TransInfo *t)
{
SpaceImage *sima = CTX_wm_space_image(C);
@@ -103,12 +268,11 @@ void createTransUVs(bContext *C, TransInfo *t)
BMFace *efa;
BMIter iter, liter;
UvElementMap *elementmap = NULL;
- BLI_bitmap *island_enabled = NULL;
struct {
float co[2];
int co_num;
} *island_center = NULL;
- int count = 0, countsel = 0, count_rejected = 0;
+ int count = 0, countsel = 0;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
if (!ED_space_image_show_uvedit(sima, tc->obedit)) {
@@ -116,22 +280,15 @@ void createTransUVs(bContext *C, TransInfo *t)
}
/* count */
- if (is_prop_connected || is_island_center) {
+ if (is_island_center) {
/* create element map with island information */
const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0;
- const bool use_uvsel = !is_prop_connected;
- elementmap = BM_uv_element_map_create(em->bm, scene, use_facesel, use_uvsel, false, true);
+ elementmap = BM_uv_element_map_create(em->bm, scene, use_facesel, true, false, true);
if (elementmap == NULL) {
continue;
}
- if (is_prop_connected) {
- island_enabled = BLI_BITMAP_NEW(elementmap->totalIslands, "TransIslandData(UV Editing)");
- }
-
- if (is_island_center) {
- island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__);
- }
+ island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__);
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -147,20 +304,14 @@ void createTransUVs(bContext *C, TransInfo *t)
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
countsel++;
- if (is_prop_connected || island_center) {
+ if (island_center) {
UvElement *element = BM_uv_element_get(elementmap, efa, l);
- if (is_prop_connected) {
- BLI_BITMAP_ENABLE(island_enabled, element->island);
- }
-
- if (is_island_center) {
- if (element->flag == false) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- add_v2_v2(island_center[element->island].co, luv->uv);
- island_center[element->island].co_num++;
- element->flag = true;
- }
+ if (element->flag == false) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ add_v2_v2(island_center[element->island].co, luv->uv);
+ island_center[element->island].co_num++;
+ element->flag = true;
}
}
}
@@ -198,6 +349,14 @@ void createTransUVs(bContext *C, TransInfo *t)
td = tc->data;
td2d = tc->data_2d;
+ float *prop_dists = NULL;
+
+ if (is_prop_connected) {
+ prop_dists = MEM_callocN(em->bm->totloop * sizeof(float), "TransObPropDists(UV Editing)");
+
+ uv_set_connectivity_distance(em->bm, prop_dists, t->aspect);
+ }
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BMLoop *l;
@@ -209,52 +368,41 @@ void createTransUVs(bContext *C, TransInfo *t)
const bool selected = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
MLoopUV *luv;
const float *center = NULL;
+ float prop_distance = FLT_MAX;
if (!is_prop_edit && !selected) {
continue;
}
- if (is_prop_connected || is_island_center) {
+ if (is_prop_connected) {
+ const int idx = BM_elem_index_get(l);
+ prop_distance = prop_dists[idx];
+ }
+
+ if (is_island_center) {
UvElement *element = BM_uv_element_get(elementmap, efa, l);
if (element) {
- if (is_prop_connected) {
- if (!BLI_BITMAP_TEST(island_enabled, element->island)) {
- count_rejected++;
- continue;
- }
- }
-
- if (is_island_center) {
- center = island_center[element->island].co;
- }
+ center = island_center[element->island].co;
}
}
- BM_elem_flag_enable(l, BM_ELEM_TAG);
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, selected);
+ UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, prop_distance, selected);
}
}
- if (is_prop_connected) {
- tc->data_len -= count_rejected;
- }
-
if (sima->flag & SI_LIVE_UNWRAP) {
ED_uvedit_live_unwrap_begin(t->scene, tc->obedit);
}
finally:
- if (is_prop_connected || is_island_center) {
+ if (is_prop_connected) {
+ MEM_freeN(prop_dists);
+ }
+ if (is_island_center) {
BM_uv_element_map_free(elementmap);
- if (is_prop_connected) {
- MEM_freeN(island_enabled);
- }
-
- if (island_center) {
- MEM_freeN(island_center);
- }
+ MEM_freeN(island_center);
}
}
}
diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c
index 92ed477eb25..2e92b4e5c09 100644
--- a/source/blender/editors/transform/transform_convert_object.c
+++ b/source/blender/editors/transform/transform_convert_object.c
@@ -794,7 +794,9 @@ static void autokeyframe_object(
ToolSettings *ts = scene->toolsettings;
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
ListBase dsources = {NULL, NULL};
- float cfra = (float)CFRA; // xxx this will do for now
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
eInsertKeyFlags flag = 0;
/* Get flags used for inserting keyframes. */
@@ -808,7 +810,8 @@ static void autokeyframe_object(
* NOTE: we assume here that the active Keying Set
* does not need to have its iterator overridden.
*/
- ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
AnimData *adt = ob->adt;
@@ -824,7 +827,7 @@ static void autokeyframe_object(
(fcu->grp ? fcu->grp->name : NULL),
fcu->rna_path,
fcu->array_index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
&nla_cache,
flag);
@@ -872,21 +875,25 @@ static void autokeyframe_object(
/* insert keyframes for the affected sets of channels using the builtin KeyingSets found */
if (do_loc) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_rot) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_scale) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
}
/* insert keyframe in all (transform) channels */
else {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
/* free temp info */
diff --git a/source/blender/editors/transform/transform_convert_paintcurve.c b/source/blender/editors/transform/transform_convert_paintcurve.c
index 4dbe57fc143..47859896673 100644
--- a/source/blender/editors/transform/transform_convert_paintcurve.c
+++ b/source/blender/editors/transform/transform_convert_paintcurve.c
@@ -154,13 +154,11 @@ void createTransPaintCurveVerts(bContext *C, TransInfo *t)
total += 3;
continue;
}
- else {
- if (pcp->bez.f1 & SELECT) {
- total++;
- }
- if (pcp->bez.f3 & SELECT) {
- total++;
- }
+ if (pcp->bez.f1 & SELECT) {
+ total++;
+ }
+ if (pcp->bez.f3 & SELECT) {
+ total++;
}
}
}
diff --git a/source/blender/editors/transform/transform_convert_particle.c b/source/blender/editors/transform/transform_convert_particle.c
index 3fa722d14cf..fbe9c07ebe9 100644
--- a/source/blender/editors/transform/transform_convert_particle.c
+++ b/source/blender/editors/transform/transform_convert_particle.c
@@ -183,7 +183,7 @@ void createTransParticleVerts(bContext *C, TransInfo *t)
tail++;
}
if (is_prop_edit && head != tail) {
- calc_distanceCurveVerts(head, tail - 1);
+ calc_distanceCurveVerts(head, tail - 1, false);
}
}
}
diff --git a/source/blender/editors/transform/transform_data.h b/source/blender/editors/transform/transform_data.h
index 48ed9ecf34b..bca6a99e35a 100644
--- a/source/blender/editors/transform/transform_data.h
+++ b/source/blender/editors/transform/transform_data.h
@@ -21,8 +21,7 @@
* \ingroup edtransform
*/
-#ifndef __TRANSFORM_DATA_H__
-#define __TRANSFORM_DATA_H__
+#pragma once
struct bConstraint;
struct Object;
@@ -193,5 +192,3 @@ enum {
/* Hard min/max for proportional size. */
#define T_PROP_SIZE_MIN 1e-6f
#define T_PROP_SIZE_MAX 1e12f
-
-#endif
diff --git a/source/blender/editors/transform/transform_draw_cursors.h b/source/blender/editors/transform/transform_draw_cursors.h
index e7696bad5a7..0f626c9039b 100644
--- a/source/blender/editors/transform/transform_draw_cursors.h
+++ b/source/blender/editors/transform/transform_draw_cursors.h
@@ -21,11 +21,8 @@
* \ingroup edtransform
*/
-#ifndef __TRANSFORM_DRAW_CURSORS_H__
-#define __TRANSFORM_DRAW_CURSORS_H__
+#pragma once
/* Callbacks for #WM_paint_cursor_activate */
bool transform_draw_cursor_poll(struct bContext *C);
void transform_draw_cursor_draw(struct bContext *C, int x, int y, void *customdata);
-
-#endif /* __TRANSFORM_DRAW_CURSORS_H__ */
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index cce6ef1f3bd..8f590d87f4c 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1116,7 +1116,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
if (t->spacetype != SPACE_VIEW3D) {
return false;
}
- else if (tc->obedit) {
+ if (tc->obedit) {
if (ED_object_calc_active_center_for_editmode(tc->obedit, select_only, r_center)) {
mul_m4_v3(tc->obedit->obmat, r_center);
return true;
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 078020e932e..9c8d99d0d24 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -124,8 +124,8 @@ static void InputVerticalRatio(TransInfo *t, MouseInput *mi, const double mval[2
{
const int winy = t->region ? t->region->winy : 1;
- /* Flip so dragging up increases (matching viewport zoom). */
- output[0] = ((mval[1] - mi->imval[1]) / winy) * -2.0f;
+ /* Dragging up increases (matching viewport zoom). */
+ output[0] = ((mval[1] - mi->imval[1]) / winy) * 2.0f;
}
/** Callback for #INPUT_VERTICAL_ABSOLUTE */
@@ -139,8 +139,8 @@ static void InputVerticalAbsolute(TransInfo *t,
InputVector(t, mi, mval, vec);
project_v3_v3v3(vec, vec, t->viewinv[1]);
- /* Flip so dragging up increases (matching viewport zoom). */
- output[0] = dot_v3v3(t->viewinv[1], vec) * -2.0f;
+ /* Dragging up increases (matching viewport zoom). */
+ output[0] = dot_v3v3(t->viewinv[1], vec) * 2.0f;
}
/** Callback for #INPUT_CUSTOM_RATIO_FLIP */
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index 831ea90b4e4..38d49ab5efd 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -448,21 +448,20 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* scale val and reset size */
return; // TODO: fix this case
}
- else {
- /* Reset val if SINGLESIZE but using a constraint */
- if (td->flag & TD_SINGLESIZE) {
- return;
- }
- /* separate out sign to apply back later */
- for (i = 0; i < 3; i++) {
- size_sign[i] = signf(td->ext->size[i]);
- size_abs[i] = fabsf(td->ext->size[i]);
- }
+ /* Reset val if SINGLESIZE but using a constraint */
+ if (td->flag & TD_SINGLESIZE) {
+ return;
+ }
- size_to_mat4(cob.matrix, size_abs);
+ /* separate out sign to apply back later */
+ for (i = 0; i < 3; i++) {
+ size_sign[i] = signf(td->ext->size[i]);
+ size_abs[i] = fabsf(td->ext->size[i]);
}
+ size_to_mat4(cob.matrix, size_abs);
+
/* Evaluate valid constraints */
for (con = td->con; con; con = con->next) {
/* only consider constraint if enabled */
@@ -508,16 +507,15 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
/* scale val and reset size */
return; // TODO: fix this case
}
- else {
- /* Reset val if SINGLESIZE but using a constraint */
- if (td->flag & TD_SINGLESIZE) {
- return;
- }
- /* extrace scale from matrix and apply back sign */
- mat4_to_size(td->ext->size, cob.matrix);
- mul_v3_v3(td->ext->size, size_sign);
+ /* Reset val if SINGLESIZE but using a constraint */
+ if (td->flag & TD_SINGLESIZE) {
+ return;
}
+
+ /* extrace scale from matrix and apply back sign */
+ mat4_to_size(td->ext->size, cob.matrix);
+ mul_v3_v3(td->ext->size, size_sign);
}
}
@@ -1274,7 +1272,7 @@ void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
if (t->data_type == TC_MESH_VERTS) {
/* Init Custom Data correction.
* Ideally this should be called when creating the TransData. */
- trans_mesh_customdata_correction_init(t);
+ mesh_customdatacorrect_init(t);
}
/* TODO(germano): Some of these operations change the `t->mode`.
diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h
index 5cda8e3063a..51aca7d551c 100644
--- a/source/blender/editors/transform/transform_mode.h
+++ b/source/blender/editors/transform/transform_mode.h
@@ -22,8 +22,7 @@
* \brief transform modes used by different operators.
*/
-#ifndef __TRANSFORM_MODE_H__
-#define __TRANSFORM_MODE_H__
+#pragma once
struct AnimData;
struct bContext;
@@ -156,4 +155,3 @@ void initTranslation(TransInfo *t);
void drawVertSlide(TransInfo *t);
void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp);
void initVertSlide(TransInfo *t);
-#endif
diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c
index 750962047db..4a648a77fe1 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -281,15 +281,14 @@ static BMLoop *get_next_loop(
copy_v3_v3(r_slide_vec, vec_accum);
return l;
}
- else {
- /* accumulate the normalized edge vector,
- * normalize so some edges don't skew the result */
- float tvec[3];
- sub_v3_v3v3(tvec, BM_edge_other_vert(l->e, v)->co, v->co);
- vec_accum_len += normalize_v3(tvec);
- add_v3_v3(vec_accum, tvec);
- i += 1;
- }
+
+ /* accumulate the normalized edge vector,
+ * normalize so some edges don't skew the result */
+ float tvec[3];
+ sub_v3_v3v3(tvec, BM_edge_other_vert(l->e, v)->co, v->co);
+ vec_accum_len += normalize_v3(tvec);
+ add_v3_v3(vec_accum, tvec);
+ i += 1;
if (BM_loop_other_edge_loop(l, v)->e == e_next) {
if (i) {
diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c
index fa33c1550e7..e508a1fa4c2 100644
--- a/source/blender/editors/transform/transform_mode_shear.c
+++ b/source/blender/editors/transform/transform_mode_shear.c
@@ -164,7 +164,7 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
- const float *center, *co;
+ const float *center;
if (td->flag & TD_SKIP) {
continue;
}
@@ -178,19 +178,15 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
if (is_local_center) {
center = td->center;
- co = td->loc;
}
else {
center = tc->center_local;
- co = td->center;
}
- sub_v3_v3v3(vec, co, center);
-
+ sub_v3_v3v3(vec, td->iloc, center);
mul_m3_v3(tmat, vec);
-
add_v3_v3(vec, center);
- sub_v3_v3(vec, co);
+ sub_v3_v3(vec, td->iloc);
if (t->options & CTX_GPENCIL_STROKES) {
/* grease pencil multiframe falloff */
diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c
index 78d3efa0d69..6302bc96330 100644
--- a/source/blender/editors/transform/transform_mode_shrink_fatten.c
+++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c
@@ -54,13 +54,13 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
char str[UI_MAX_DRAW_STR];
size_t ofs = 0;
- distance = -t->values[0];
+ distance = t->values[0];
snapGridIncrement(t, &distance);
applyNumInput(&t->num, &distance);
- t->values_final[0] = -distance;
+ t->values_final[0] = distance;
/* header print for NumInput */
ofs += BLI_strncpy_rlen(str + ofs, TIP_("Shrink/Fatten:"), sizeof(str) - ofs);
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index aee05197f10..c083e1654dc 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -68,15 +68,27 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
}
else {
float dvec[3];
-
- copy_v3_v3(dvec, vec);
- applyAspectRatio(t, dvec);
+ if (!(t->flag & T_2D_EDIT) && t->con.mode & CON_APPLY) {
+ int i = 0;
+ zero_v3(dvec);
+ if (t->con.mode & CON_AXIS0) {
+ dvec[i++] = vec[0];
+ }
+ if (t->con.mode & CON_AXIS1) {
+ dvec[i++] = vec[1];
+ }
+ if (t->con.mode & CON_AXIS2) {
+ dvec[i++] = vec[2];
+ }
+ }
+ else {
+ copy_v3_v3(dvec, vec);
+ applyAspectRatio(t, dvec);
+ }
dist = len_v3(vec);
if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) {
- int i;
-
- for (i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
bUnit_AsString2(&tvec[NUM_STR_REP_LEN * i],
NUM_STR_REP_LEN,
dvec[i] * t->scene->unit.scale_length,
diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c
index 9e810b9c629..b396317ba7c 100644
--- a/source/blender/editors/transform/transform_mode_vert_slide.c
+++ b/source/blender/editors/transform/transform_mode_vert_slide.c
@@ -500,6 +500,10 @@ static void doVertSlide(TransInfo *t, float perc)
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
VertSlideData *sld = tc->custom.mode.data;
+ if (sld == NULL) {
+ continue;
+ }
+
TransDataVertSlideVert *svlist = sld->sv, *sv;
int i;
@@ -597,7 +601,7 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
t->values_final[0] = final;
/* header string */
- ofs += BLI_strncpy_rlen(str + ofs, TIP_("Vert Slide: "), sizeof(str) - ofs);
+ ofs += BLI_strncpy_rlen(str + ofs, TIP_("Vertex Slide: "), sizeof(str) - ofs);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c, &t->scene->unit);
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index f86bcc41bee..ab9548ad52e 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -516,22 +516,19 @@ static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if ((event == NULL) && RNA_struct_property_is_set(op->ptr, "value")) {
return transform_exec(C, op);
}
- else {
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
- op->flag |= OP_IS_MODAL_GRAB_CURSOR; // XXX maybe we want this with the gizmo only?
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
- /* Use when modal input has some transformation to begin with. */
- {
- TransInfo *t = op->customdata;
- if (UNLIKELY(!is_zero_v4(t->values_modal_offset))) {
- transformApply(C, t);
- }
- }
+ op->flag |= OP_IS_MODAL_GRAB_CURSOR; // XXX maybe we want this with the gizmo only?
- return OPERATOR_RUNNING_MODAL;
+ /* Use when modal input has some transformation to begin with. */
+ TransInfo *t = op->customdata;
+ if (UNLIKELY(!is_zero_v4(t->values_modal_offset))) {
+ transformApply(C, t);
}
+
+ return OPERATOR_RUNNING_MODAL;
}
static bool transform_poll_property(const bContext *UNUSED(C),
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 493b52495db..e805743e6bb 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -467,14 +467,14 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
return V3D_ORIENT_GLOBAL;
}
case V3D_ORIENT_GIMBAL: {
- if (gimbal_axis(ob, r_mat)) {
+ if (ob && gimbal_axis(ob, r_mat)) {
return V3D_ORIENT_GIMBAL;
}
/* if not gimbal, fall through to normal */
ATTR_FALLTHROUGH;
}
case V3D_ORIENT_NORMAL: {
- if (obedit || ob->mode & OB_MODE_POSE) {
+ if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
ED_getTransformOrientationMatrix(C, r_mat, pivot_point);
return V3D_ORIENT_NORMAL;
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 2943c3cb8ea..a700dd320b7 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -37,6 +37,7 @@
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_object.h"
+#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "RNA_access.h"
@@ -100,6 +101,24 @@ int BIF_snappingSupported(Object *obedit)
}
#endif
+static bool snap_use_backface_culling(const TransInfo *t)
+{
+ BLI_assert(t->spacetype == SPACE_VIEW3D);
+ View3D *v3d = t->view;
+ if ((v3d->shading.type == OB_SOLID) && (v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING)) {
+ return true;
+ }
+ if (v3d->shading.type == OB_RENDER &&
+ (t->scene->display.shading.flag & V3D_SHADING_BACKFACE_CULLING) &&
+ BKE_scene_uses_blender_workbench(t->scene)) {
+ return true;
+ }
+ if (t->settings->snap_flag & SCE_SNAP_BACKFACE_CULLING) {
+ return true;
+ }
+ return false;
+}
+
bool validSnap(const TransInfo *t)
{
return (t->tsnap.status & (POINT_INIT | TARGET_INIT)) == (POINT_INIT | TARGET_INIT) ||
@@ -315,8 +334,7 @@ void applyProject(TransInfo *t)
.snap_select = t->tsnap.modeSelect,
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
.use_occlusion_test = false,
- .use_backface_culling = (t->scene->toolsettings->snap_flag &
- SCE_SNAP_BACKFACE_CULLING) != 0,
+ .use_backface_culling = t->tsnap.use_backface_culling,
},
mval_fl,
NULL,
@@ -601,6 +619,7 @@ static void initSnappingMode(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D) {
if (t->tsnap.object_context == NULL) {
+ t->tsnap.use_backface_culling = snap_use_backface_culling(t);
t->tsnap.object_context = ED_transform_snap_object_context_create_view3d(
t->scene, 0, t->region, t->view);
@@ -1120,13 +1139,12 @@ short snapObjectsTransform(
return ED_transform_snap_object_project_view3d_ex(
t->tsnap.object_context,
t->depsgraph,
- t->scene->toolsettings->snap_mode,
+ t->settings->snap_mode,
&(const struct SnapObjectParams){
.snap_select = t->tsnap.modeSelect,
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
- .use_occlusion_test = t->scene->toolsettings->snap_mode != SCE_SNAP_MODE_FACE,
- .use_backface_culling = (t->scene->toolsettings->snap_flag &
- SCE_SNAP_BACKFACE_CULLING) != 0,
+ .use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE,
+ .use_backface_culling = t->tsnap.use_backface_culling,
},
mval,
target,
diff --git a/source/blender/editors/transform/transform_snap.h b/source/blender/editors/transform/transform_snap.h
index 688661bc2cb..b97a9dc882c 100644
--- a/source/blender/editors/transform/transform_snap.h
+++ b/source/blender/editors/transform/transform_snap.h
@@ -18,8 +18,7 @@
* \ingroup editors
*/
-#ifndef __TRANSFORM_SNAP_H__
-#define __TRANSFORM_SNAP_H__
+#pragma once
#define SNAP_MIN_DISTANCE 30
@@ -88,5 +87,3 @@ eRedrawFlag updateSelectedSnapPoint(TransInfo *t);
void removeSnapPoint(TransInfo *t);
float transform_snap_distance_len_squared_fn(TransInfo *t, const float p1[3], const float p2[3]);
-
-#endif /* __TRANSFORM_SNAP_H__ */
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 4198b4c02a3..eb14c5bec28 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -1014,12 +1014,11 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
dt->r_hit_list);
break;
}
- else {
- BMEditMesh *em = BKE_editmesh_from_object(ob);
- if (em->mesh_eval_final) {
- me = em->mesh_eval_final;
- use_hide = true;
- }
+
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ if (em->mesh_eval_final) {
+ me = em->mesh_eval_final;
+ use_hide = true;
}
}
retval = raycastMesh(sctx,
@@ -1107,11 +1106,13 @@ static bool raycastObjects(SnapObjectContext *sctx,
const float ray_start[3],
const float ray_dir[3],
/* read/write args */
- float *ray_depth,
+ /* Parameters below cannot be const, because they are assigned to a
+ * non-const variable (readability-non-const-parameter). */
+ float *ray_depth /* NOLINT */,
/* return args */
- float r_loc[3],
- float r_no[3],
- int *r_index,
+ float r_loc[3] /* NOLINT */,
+ float r_no[3] /* NOLINT */,
+ int *r_index /* NOLINT */,
Object **r_ob,
float r_obmat[4][4],
ListBase *r_hit_list)
@@ -1275,7 +1276,7 @@ static bool test_projected_edge_dist(const struct DistProjectedAABBPrecalc *prec
float r_co[3])
{
float near_co[3], lambda;
- if (!isect_ray_seg_v3(precalc->ray_origin, precalc->ray_direction, va, vb, &lambda)) {
+ if (!isect_ray_line_v3(precalc->ray_origin, precalc->ray_direction, va, vb, &lambda)) {
copy_v3_v3(near_co, va);
}
else {
@@ -1667,11 +1668,11 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
};
float lambda;
- if (!isect_ray_seg_v3(neasrest_precalc.ray_origin,
- neasrest_precalc.ray_direction,
- v_pair[0],
- v_pair[1],
- &lambda)) {
+ if (!isect_ray_line_v3(neasrest_precalc.ray_origin,
+ neasrest_precalc.ray_direction,
+ v_pair[0],
+ v_pair[1],
+ &lambda)) {
/* do nothing */
}
else {
@@ -2689,11 +2690,10 @@ static void snap_obj_fn(SnapObjectContext *sctx,
dt->r_index);
break;
}
- else {
- BMEditMesh *em = BKE_editmesh_from_object(ob);
- if (em->mesh_eval_final) {
- me = em->mesh_eval_final;
- }
+
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ if (em->mesh_eval_final) {
+ me = em->mesh_eval_final;
}
}
else if (ob->dt == OB_BOUNDBOX) {
@@ -2791,11 +2791,13 @@ static short snapObjectsRay(SnapObjectContext *sctx,
SnapData *snapdata,
const struct SnapObjectParams *params,
/* read/write args */
- float *dist_px,
+ /* Parameters below cannot be const, because they are assigned to a
+ * non-const variable (readability-non-const-parameter). */
+ float *dist_px /* NOLINT */,
/* return args */
- float r_loc[3],
- float r_no[3],
- int *r_index,
+ float r_loc[3] /* NOLINT */,
+ float r_no[3] /* NOLINT */,
+ int *r_index /* NOLINT */,
Object **r_ob,
float r_obmat[4][4])
{
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 6633e1c427c..50e0bb1f1c2 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -98,6 +98,14 @@ void ED_undo_push(bContext *C, const char *str)
if (steps <= 0) {
return;
}
+ if (G.background) {
+ /* Python developers may have explicitly created the undo stack in background mode,
+ * otherwise allow it to be NULL, see: T60934.
+ * Otherwise it must never be NULL, even when undo is disabled. */
+ if (wm->undo_stack == NULL) {
+ return;
+ }
+ }
/* Only apply limit if this is the last undo step. */
if (wm->undo_stack->step_active && (wm->undo_stack->step_active->next == NULL)) {
@@ -360,7 +368,7 @@ bool ED_undo_is_legacy_compatible_for_property(struct bContext *C, ID *id)
CLOG_INFO(&LOG, 1, "skipping undo for paint-mode");
return false;
}
- else if (obact->mode & OB_MODE_EDIT) {
+ if (obact->mode & OB_MODE_EDIT) {
if ((id == NULL) || (obact->data == NULL) ||
(GS(id->name) != GS(((ID *)obact->data)->name))) {
/* No undo push on id type mismatch in edit-mode. */
diff --git a/source/blender/editors/undo/undo_intern.h b/source/blender/editors/undo/undo_intern.h
index 8184e7bfbdc..660f1a5b57d 100644
--- a/source/blender/editors/undo/undo_intern.h
+++ b/source/blender/editors/undo/undo_intern.h
@@ -18,8 +18,7 @@
* \ingroup edundo
*/
-#ifndef __UNDO_INTERN_H__
-#define __UNDO_INTERN_H__
+#pragma once
/* internal exports only */
@@ -27,5 +26,3 @@ struct UndoType;
/* memfile_undo.c */
void ED_memfile_undosys_type(struct UndoType *ut);
-
-#endif /* __UNDO_INTERN_H__ */
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 17a90d10ca7..207606c2dcd 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -63,7 +63,6 @@ set(SRC
../include/ED_keyframes_edit.h
../include/ED_keyframing.h
../include/ED_lattice.h
- ../include/ED_logic.h
../include/ED_markers.h
../include/ED_mask.h
../include/ED_mball.h
@@ -96,6 +95,7 @@ set(SRC
../include/ED_util_imbuf.h
../include/ED_uvedit.h
../include/ED_view3d.h
+ ../include/ED_view3d_offscreen.h
../include/UI_icons.h
../include/UI_interface.h
../include/UI_interface_icons.h
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index af387e4f7c2..93762e6500c 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -58,7 +58,6 @@
#include "DEG_depsgraph.h"
#include "ED_armature.h"
-#include "ED_buttons.h"
#include "ED_image.h"
#include "ED_mesh.h"
#include "ED_node.h"
@@ -123,10 +122,10 @@ void ED_editors_init(bContext *C)
if (mode == OB_MODE_OBJECT) {
continue;
}
- else if (BKE_object_has_mode_data(ob, mode)) {
+ if (BKE_object_has_mode_data(ob, mode)) {
continue;
}
- else if (ob->type == OB_GPENCIL) {
+ if (ob->type == OB_GPENCIL) {
/* For multi-edit mode we may already have mode data (grease pencil does not need it).
* However we may have a non-active object stuck in a grease-pencil edit mode. */
if (ob != obact) {
diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c
index 132a63a8249..3e85342e0d7 100644
--- a/source/blender/editors/util/ed_util_imbuf.c
+++ b/source/blender/editors/util/ed_util_imbuf.c
@@ -447,15 +447,16 @@ void ED_imbuf_sample_draw(const bContext *C, ARegion *region, void *arg_info)
(float[2]){event->x - region->winrct.xmin, event->y - region->winrct.ymin},
(float)(info->sample_size / 2.0f) * sima->zoom);
- glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(GL_XOR);
+ GPU_logic_op_xor_set(true);
+
GPU_line_width(1.0f);
imm_draw_box_wire_2d(pos,
(float)sample_rect_fl.xmin,
(float)sample_rect_fl.ymin,
(float)sample_rect_fl.xmax,
(float)sample_rect_fl.ymax);
- glDisable(GL_COLOR_LOGIC_OP);
+
+ GPU_logic_op_xor_set(false);
immUnbindProgram();
}
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index be1319c37dd..384da6fb931 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -26,6 +26,8 @@
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
+#include "BLT_translation.h"
+
#include "BKE_context.h"
#include "BKE_scene.h"
#include "BKE_unit.h"
@@ -239,13 +241,12 @@ bool applyNumInput(NumInput *n, float *vec)
#endif
return true;
}
- else {
- /* Else, we set the 'org' values for numinput! */
- for (j = 0; j <= n->idx_max; j++) {
- n->val[j] = n->val_org[j] = vec[j];
- }
- return false;
+
+ /* Else, we set the 'org' values for numinput! */
+ for (j = 0; j <= n->idx_max; j++) {
+ n->val[j] = n->val_org[j] = vec[j];
}
+ return false;
}
static void value_to_editstr(NumInput *n, int idx)
@@ -278,8 +279,12 @@ static bool editstr_insert_at_cursor(NumInput *n, const char *buf, const int buf
return true;
}
-bool user_string_to_number(
- bContext *C, const char *str, const UnitSettings *unit, int type, double *r_value)
+bool user_string_to_number(bContext *C,
+ const char *str,
+ const UnitSettings *unit,
+ int type,
+ const char *error_prefix,
+ double *r_value)
{
#ifdef WITH_PYTHON
double unit_scale = BKE_scene_unit_scale(unit, type, 1.0);
@@ -289,14 +294,14 @@ bool user_string_to_number(
bUnit_ReplaceString(
str_unit_convert, sizeof(str_unit_convert), str, unit_scale, unit->system, type);
- return BPY_execute_string_as_number(C, NULL, str_unit_convert, true, r_value);
- }
- else {
- int success = BPY_execute_string_as_number(C, NULL, str, true, r_value);
- *r_value *= bUnit_PreferredInputUnitScalar(unit, type);
- *r_value /= unit_scale;
- return success;
+ return BPY_execute_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value);
}
+
+ int success = BPY_execute_string_as_number(C, NULL, str, error_prefix, r_value);
+ *r_value *= bUnit_PreferredInputUnitScalar(unit, type);
+ *r_value /= unit_scale;
+ return success;
+
#else
UNUSED_VARS(C, unit, type);
*r_value = atof(str);
@@ -309,12 +314,10 @@ static bool editstr_is_simple_numinput(const char ascii)
if (ascii >= '0' && ascii <= '9') {
return true;
}
- else if (ascii == '.') {
+ if (ascii == '.') {
return true;
}
- else {
- return false;
- }
+ return false;
}
bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
@@ -348,7 +351,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
n->val_flag[idx] |= NUM_EDITED;
return true;
}
- else if (event->ctrl) {
+ if (event->ctrl) {
n->flag &= ~NUM_EDIT_FULL;
return true;
}
@@ -576,7 +579,8 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
Scene *sce = CTX_data_scene(C);
double val;
- int success = user_string_to_number(C, n->str, &sce->unit, n->unit_type[idx], &val);
+ int success = user_string_to_number(
+ C, n->str, &sce->unit, n->unit_type[idx], IFACE_("Numeric input evaluation"), &val);
if (success) {
n->val[idx] = (float)val;
diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt
index b40b82c50fb..a39234561c2 100644
--- a/source/blender/editors/uvedit/CMakeLists.txt
+++ b/source/blender/editors/uvedit/CMakeLists.txt
@@ -40,6 +40,8 @@ set(SRC
uvedit_draw.c
uvedit_ops.c
uvedit_parametrizer.c
+ uvedit_path.c
+ uvedit_rip.c
uvedit_select.c
uvedit_smart_stitch.c
uvedit_unwrap_ops.c
@@ -49,6 +51,7 @@ set(SRC
)
set(LIB
+ bf_bmesh
)
if(WITH_INTERNATIONAL)
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 28c55813a3b..df8d3cfb8db 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -86,16 +86,12 @@ static int draw_uvs_face_check(const ToolSettings *ts)
if (ts->selectmode == SCE_SELECT_FACE) {
return 2;
}
- else if (ts->selectmode & SCE_SELECT_FACE) {
+ if (ts->selectmode & SCE_SELECT_FACE) {
return 1;
}
- else {
- return 0;
- }
- }
- else {
- return (ts->uv_selectmode == UV_SELECT_FACE);
+ return 0;
}
+ return (ts->uv_selectmode == UV_SELECT_FACE);
}
/* ------------------------- */
@@ -412,21 +408,16 @@ static void draw_uvs(SpaceImage *sima,
{
/* We could modify the vbo's data filling
* instead of modifying the provoking vert. */
- glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
+ GPU_provoking_vertex(GPU_VERTEX_FIRST);
UI_GetThemeColor3fv(TH_EDGE_SELECT, col2);
col2[3] = overlay_alpha;
- float dash_width = (sima->dt_uv & SI_UVDT_DASH) ? (4.0f * UI_DPI_FAC) : 9999.0f;
+ const float dash_width = (sima->dt_uv == SI_UVDT_DASH) ? (4.0f * UI_DPI_FAC) : 9999.0f;
eGPUBuiltinShader shader = (interpedges) ? GPU_SHADER_2D_UV_EDGES_SMOOTH :
GPU_SHADER_2D_UV_EDGES;
-
-#ifndef __APPLE__
- GPU_batch_program_set_builtin(batch->edges, shader);
-#endif
-
- if (sima->dt_uv == SI_UVDT_OUTLINE) {
#ifdef __APPLE__
+ if (sima->dt_uv == SI_UVDT_OUTLINE) {
/* Apple drivers do not support wide line. This is a workaround awaiting the 2D view
* refactor. Limiting to OSX since this will slow down the drawing. (see T76806) */
GPU_batch_program_set_builtin(batch->edges, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
@@ -440,7 +431,13 @@ static void draw_uvs(SpaceImage *sima,
GPU_batch_uniform_2fv(batch->edges, "viewportSize", &viewport[2]);
GPU_batch_draw(batch->edges);
-#else
+ }
+#endif
+
+ GPU_batch_program_set_builtin(batch->edges, shader);
+
+ if (sima->dt_uv == SI_UVDT_OUTLINE) {
+#ifndef __APPLE__
/* Black Outline. */
GPU_line_width(3.0f);
GPU_batch_uniform_4f(batch->edges, "edgeColor", 0.0f, 0.0f, 0.0f, overlay_alpha);
@@ -467,7 +464,7 @@ static void draw_uvs(SpaceImage *sima,
GPU_batch_draw(batch->edges);
GPU_depth_test(false);
- glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
+ GPU_provoking_vertex(GPU_VERTEX_LAST);
}
if (sima->flag & SI_SMOOTH_UV) {
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 31384d6df17..7455004ccb8 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -21,8 +21,7 @@
* \ingroup eduv
*/
-#ifndef __UVEDIT_INTERN_H__
-#define __UVEDIT_INTERN_H__
+#pragma once
struct BMFace;
struct BMLoop;
@@ -88,6 +87,15 @@ bool uv_find_nearest_face_multi(struct Scene *scene,
const float co[2],
struct UvNearestHit *hit_final);
+BMLoop *uv_find_nearest_loop_from_vert(struct Scene *scene,
+ struct Object *obedit,
+ struct BMVert *v,
+ const float co[2]);
+BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene,
+ struct Object *obedit,
+ struct BMEdge *e,
+ const float co[2]);
+
/* utility tool functions */
void uvedit_live_unwrap_update(struct SpaceImage *sima,
@@ -106,7 +114,13 @@ void UV_OT_pack_islands(struct wmOperatorType *ot);
void UV_OT_reset(struct wmOperatorType *ot);
void UV_OT_sphere_project(struct wmOperatorType *ot);
void UV_OT_unwrap(struct wmOperatorType *ot);
+void UV_OT_rip(struct wmOperatorType *ot);
void UV_OT_stitch(struct wmOperatorType *ot);
+void UV_OT_smart_project(struct wmOperatorType *ot);
+
+/* uvedit_path.c */
+void UV_OT_shortest_path_pick(struct wmOperatorType *ot);
+void UV_OT_shortest_path_select(struct wmOperatorType *ot);
/* uvedit_select.c */
@@ -121,6 +135,7 @@ const float *uvedit_first_selected_uv_from_vertex(struct Scene *scene,
void UV_OT_select_all(struct wmOperatorType *ot);
void UV_OT_select(struct wmOperatorType *ot);
void UV_OT_select_loop(struct wmOperatorType *ot);
+void UV_OT_select_edge_ring(struct wmOperatorType *ot);
void UV_OT_select_linked(struct wmOperatorType *ot);
void UV_OT_select_linked_pick(struct wmOperatorType *ot);
void UV_OT_select_split(struct wmOperatorType *ot);
@@ -131,5 +146,3 @@ void UV_OT_select_circle(struct wmOperatorType *ot);
void UV_OT_select_more(struct wmOperatorType *ot);
void UV_OT_select_less(struct wmOperatorType *ot);
void UV_OT_select_overlap(struct wmOperatorType *ot);
-
-#endif /* __UVEDIT_INTERN_H__ */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 652d07f02db..956c094c19b 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -998,9 +998,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
if (RNA_boolean_get(op->ptr, "use_unselected")) {
return uv_remove_doubles_to_unselected(C, op);
}
- else {
- return uv_remove_doubles_to_selected(C, op);
- }
+ return uv_remove_doubles_to_selected(C, op);
}
static void UV_OT_remove_doubles(wmOperatorType *ot)
@@ -1845,7 +1843,6 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
const bool mark_seams = RNA_boolean_get(op->ptr, "mark_seams");
const bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp");
bool changed_multi = false;
@@ -1886,23 +1883,10 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
continue;
}
- const MLoopUV *luv_curr = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l_iter->next, cd_loop_uv_offset);
-
bool mark = false;
BMLoop *l_other = l_iter->radial_next;
do {
- const MLoopUV *luv_other_curr = BM_ELEM_CD_GET_VOID_P(l_other, cd_loop_uv_offset);
- const MLoopUV *luv_other_next = BM_ELEM_CD_GET_VOID_P(l_other->next, cd_loop_uv_offset);
- if (l_iter->v != l_other->v) {
- SWAP(const MLoopUV *, luv_other_curr, luv_other_next);
- }
-
- if (!compare_ff(luv_curr->uv[0], luv_other_curr->uv[0], limit[0]) ||
- !compare_ff(luv_curr->uv[1], luv_other_curr->uv[1], limit[1]) ||
-
- !compare_ff(luv_next->uv[0], luv_other_next->uv[0], limit[0]) ||
- !compare_ff(luv_next->uv[1], luv_other_next->uv[1], limit[1])) {
+ if (!BM_loop_uv_share_edge_check(l_iter, l_other, cd_loop_uv_offset)) {
mark = true;
break;
}
@@ -2073,6 +2057,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_select_all);
WM_operatortype_append(UV_OT_select);
WM_operatortype_append(UV_OT_select_loop);
+ WM_operatortype_append(UV_OT_select_edge_ring);
WM_operatortype_append(UV_OT_select_linked);
WM_operatortype_append(UV_OT_select_linked_pick);
WM_operatortype_append(UV_OT_select_split);
@@ -2089,7 +2074,10 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_align);
+ WM_operatortype_append(UV_OT_rip);
WM_operatortype_append(UV_OT_stitch);
+ WM_operatortype_append(UV_OT_shortest_path_pick);
+ WM_operatortype_append(UV_OT_shortest_path_select);
WM_operatortype_append(UV_OT_seams_from_islands);
WM_operatortype_append(UV_OT_mark_seam);
@@ -2106,6 +2094,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_reset);
WM_operatortype_append(UV_OT_sphere_project);
WM_operatortype_append(UV_OT_unwrap);
+ WM_operatortype_append(UV_OT_smart_project);
WM_operatortype_append(UV_OT_reveal);
WM_operatortype_append(UV_OT_hide);
@@ -2113,6 +2102,21 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_cursor_set);
}
+void ED_operatormacros_uvedit(void)
+{
+ wmOperatorType *ot;
+ wmOperatorTypeMacro *otmacro;
+
+ ot = WM_operatortype_append_macro("UV_OT_rip_move",
+ "UV Rip Move",
+ "Unstitch UV's and move the result",
+ OPTYPE_UNDO | OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "UV_OT_rip");
+ otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+ RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
+ RNA_boolean_set(otmacro->ptr, "mirror", false);
+}
+
void ED_keymap_uvedit(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index da8e0efa522..a4ee9a294fe 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -321,7 +321,7 @@ static PHashLink *phash_lookup(PHash *ph, PHashKey key)
if (link->key == key) {
return link;
}
- else if (PHASH_hash(ph, link->key) != hash) {
+ if (PHASH_hash(ph, link->key) != hash) {
return NULL;
}
}
@@ -337,7 +337,7 @@ static PHashLink *phash_next(PHash *ph, PHashKey key, PHashLink *link)
if (link->key == key) {
return link;
}
- else if (PHASH_hash(ph, link->key) != hash) {
+ if (PHASH_hash(ph, link->key) != hash) {
return NULL;
}
}
@@ -372,12 +372,10 @@ static float p_vec_angle(const float v1[3], const float v2[3], const float v3[3]
if (dot <= -1.0f) {
return (float)M_PI;
}
- else if (dot >= 1.0f) {
+ if (dot >= 1.0f) {
return 0.0f;
}
- else {
- return acosf(dot);
- }
+ return acosf(dot);
}
static float p_vec2_angle(const float v1[2], const float v2[2], const float v3[2])
@@ -489,7 +487,7 @@ static void p_chart_uv_scale_xy(PChart *chart, float x, float y)
}
}
-static void p_chart_uv_translate(PChart *chart, float trans[2])
+static void p_chart_uv_translate(PChart *chart, const float trans[2])
{
PVert *v;
@@ -790,9 +788,7 @@ static PVert *p_vert_lookup(PHandle *handle, PHashKey key, const float co[3], PE
if (v) {
return v;
}
- else {
- return p_vert_add(handle, key, co, e);
- }
+ return p_vert_add(handle, key, co, e);
}
static PVert *p_vert_copy(PChart *chart, PVert *v)
@@ -809,7 +805,7 @@ static PVert *p_vert_copy(PChart *chart, PVert *v)
return nv;
}
-static PEdge *p_edge_lookup(PHandle *handle, PHashKey *vkeys)
+static PEdge *p_edge_lookup(PHandle *handle, const PHashKey *vkeys)
{
PHashKey key = PHASH_edge(vkeys[0], vkeys[1]);
PEdge *e = (PEdge *)phash_lookup(handle->hash_edges, key);
@@ -818,7 +814,7 @@ static PEdge *p_edge_lookup(PHandle *handle, PHashKey *vkeys)
if ((e->vert->u.key == vkeys[0]) && (e->next->vert->u.key == vkeys[1])) {
return e;
}
- else if ((e->vert->u.key == vkeys[1]) && (e->next->vert->u.key == vkeys[0])) {
+ if ((e->vert->u.key == vkeys[1]) && (e->next->vert->u.key == vkeys[0])) {
return e;
}
@@ -1150,14 +1146,14 @@ static PFace *p_face_add(PHandle *handle)
static PFace *p_face_add_construct(PHandle *handle,
ParamKey key,
- ParamKey *vkeys,
+ const ParamKey *vkeys,
float *co[4],
float *uv[4],
int i1,
int i2,
int i3,
- ParamBool *pin,
- ParamBool *select)
+ const ParamBool *pin,
+ const ParamBool *select)
{
PFace *f = p_face_add(handle);
PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next;
@@ -3353,11 +3349,10 @@ static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
p_chart_lscm_load_solution(chart);
return P_TRUE;
}
- else {
- for (v = chart->verts; v; v = v->nextlink) {
- v->uv[0] = 0.0f;
- v->uv[1] = 0.0f;
- }
+
+ for (v = chart->verts; v; v = v->nextlink) {
+ v->uv[0] = 0.0f;
+ v->uv[1] = 0.0f;
}
return P_FALSE;
@@ -3542,20 +3537,16 @@ static int p_compare_geometric_uv(const void *a, const void *b)
if (v1->uv[0] < v2->uv[0]) {
return -1;
}
- else if (v1->uv[0] == v2->uv[0]) {
+ if (v1->uv[0] == v2->uv[0]) {
if (v1->uv[1] < v2->uv[1]) {
return -1;
}
- else if (v1->uv[1] == v2->uv[1]) {
+ if (v1->uv[1] == v2->uv[1]) {
return 0;
}
- else {
- return 1;
- }
- }
- else {
return 1;
}
+ return 1;
}
static PBool p_chart_convex_hull(PChart *chart, PVert ***r_verts, int *r_nverts, int *r_right)
@@ -3935,14 +3926,11 @@ static PBool p_node_intersect(SmoothNode *node, float co[2])
return P_FALSE;
}
- else {
- if (co[node->axis] < node->split) {
- return p_node_intersect(node->c1, co);
- }
- else {
- return p_node_intersect(node->c2, co);
- }
+
+ if (co[node->axis] < node->split) {
+ return p_node_intersect(node->c1, co);
}
+ return p_node_intersect(node->c2, co);
}
/* smoothing */
@@ -3955,12 +3943,10 @@ static int p_compare_float(const void *a_, const void *b_)
if (a < b) {
return -1;
}
- else if (a == b) {
+ if (a == b) {
return 0;
}
- else {
- return 1;
- }
+ return 1;
}
static float p_smooth_median_edge_length(PChart *chart)
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.h b/source/blender/editors/uvedit/uvedit_parametrizer.h
index 53188ea42bb..ee1eb4f63bf 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.h
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __UVEDIT_PARAMETRIZER_H__
-#define __UVEDIT_PARAMETRIZER_H__
+#pragma once
/** \file
* \ingroup eduv
@@ -109,5 +108,3 @@ void param_flush_restore(ParamHandle *handle);
#ifdef __cplusplus
}
#endif
-
-#endif /*__UVEDIT_PARAMETRIZER_H__*/
diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c
new file mode 100644
index 00000000000..546aad078aa
--- /dev/null
+++ b/source/blender/editors/uvedit/uvedit_path.c
@@ -0,0 +1,873 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup eduv
+ *
+ * \note The logic in this file closely follows editmesh_path.c
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "BLI_linklist.h"
+#include "DNA_windowmanager_types.h"
+#include "MEM_guardedalloc.h"
+
+#include "BLI_ghash.h"
+#include "BLI_linklist_stack.h"
+#include "BLI_math.h"
+#include "BLI_math_vector.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_image_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_editmesh.h"
+#include "BKE_layer.h"
+#include "BKE_mesh.h"
+#include "BKE_report.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "ED_screen.h"
+#include "ED_transform.h"
+#include "ED_uvedit.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_view2d.h"
+
+#include "intern/bmesh_marking.h"
+#include "uvedit_intern.h"
+
+#include "bmesh_tools.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Local Utilities
+ * \{ */
+
+/**
+ * Support edge-path using vert-path calculation code.
+ *
+ * Cheat! Pick 2 closest loops and do vertex path,
+ * in practices only obscure/contrived cases will make give noticeably worse behavior.
+ *
+ * While the code below is a bit awkward, it's significantly less overhead than
+ * adding full edge selection which is nearly the same as vertex path in the case of UV's.
+ *
+ * \param use_nearest: When false use the post distant pair of loops,
+ * use when filling a region as we want both verts from each edge to be included in the region.
+ */
+static void bm_loop_calc_vert_pair_from_edge_pair(const bool use_nearest,
+ const int cd_loop_uv_offset,
+ const float aspect_y,
+ BMElem **ele_src_p,
+ BMElem **ele_dst_p,
+ BMElem **r_ele_dst_final)
+{
+ BMLoop *l_src = (BMLoop *)*ele_src_p;
+ BMLoop *l_dst = (BMLoop *)*ele_dst_p;
+
+ const MLoopUV *luv_src_v1 = BM_ELEM_CD_GET_VOID_P(l_src, cd_loop_uv_offset);
+ const MLoopUV *luv_src_v2 = BM_ELEM_CD_GET_VOID_P(l_src->next, cd_loop_uv_offset);
+ const MLoopUV *luv_dst_v1 = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_uv_offset);
+ const MLoopUV *luv_dst_v2 = BM_ELEM_CD_GET_VOID_P(l_dst->next, cd_loop_uv_offset);
+
+ const float uv_src_v1[2] = {luv_src_v1->uv[0], luv_src_v1->uv[1] / aspect_y};
+ const float uv_src_v2[2] = {luv_src_v2->uv[0], luv_src_v2->uv[1] / aspect_y};
+ const float uv_dst_v1[2] = {luv_dst_v1->uv[0], luv_dst_v1->uv[1] / aspect_y};
+ const float uv_dst_v2[2] = {luv_dst_v2->uv[0], luv_dst_v2->uv[1] / aspect_y};
+
+ struct {
+ int src_index;
+ int dst_index;
+ float len_sq;
+ } tests[4] = {
+ {0, 0, len_squared_v2v2(uv_src_v1, uv_dst_v1)},
+ {0, 1, len_squared_v2v2(uv_src_v1, uv_dst_v2)},
+ {1, 0, len_squared_v2v2(uv_src_v2, uv_dst_v1)},
+ {1, 1, len_squared_v2v2(uv_src_v2, uv_dst_v2)},
+ };
+ int i_best = 0;
+ for (int i = 1; i < ARRAY_SIZE(tests); i++) {
+ if (use_nearest) {
+ if (tests[i].len_sq < tests[i_best].len_sq) {
+ i_best = i;
+ }
+ }
+ else {
+ if (tests[i].len_sq > tests[i_best].len_sq) {
+ i_best = i;
+ }
+ }
+ }
+
+ *ele_src_p = (BMElem *)(tests[i_best].src_index ? l_src->next : l_src);
+ *ele_dst_p = (BMElem *)(tests[i_best].dst_index ? l_dst->next : l_dst);
+
+ /* Ensure the edge is selected, not just the vertices up until we hit it. */
+ *r_ele_dst_final = (BMElem *)(tests[i_best].dst_index ? l_dst : l_dst->next);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Path Select Struct & Properties
+ * \{ */
+
+struct PathSelectParams {
+ /** ensure the active element is the last selected item (handy for picking) */
+ bool track_active;
+ bool use_topology_distance;
+ bool use_face_step;
+ bool use_fill;
+ struct CheckerIntervalParams interval_params;
+};
+
+struct UserData_UV {
+ Scene *scene;
+ BMEditMesh *em;
+ uint cd_loop_uv_offset;
+};
+
+static void path_select_properties(wmOperatorType *ot)
+{
+ RNA_def_boolean(ot->srna,
+ "use_face_step",
+ false,
+ "Face Stepping",
+ "Traverse connected faces (includes diagonals and edge-rings)");
+ RNA_def_boolean(ot->srna,
+ "use_topology_distance",
+ false,
+ "Topology Distance",
+ "Find the minimum number of steps, ignoring spatial distance");
+ RNA_def_boolean(ot->srna,
+ "use_fill",
+ false,
+ "Fill Region",
+ "Select all paths between the source/destination elements");
+
+ WM_operator_properties_checker_interval(ot, true);
+}
+
+static void path_select_params_from_op(wmOperator *op, struct PathSelectParams *op_params)
+{
+ op_params->track_active = false;
+ op_params->use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
+ op_params->use_fill = RNA_boolean_get(op->ptr, "use_fill");
+ op_params->use_topology_distance = RNA_boolean_get(op->ptr, "use_topology_distance");
+ WM_operator_properties_checker_interval_from_op(op, &op_params->interval_params);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Vert Path
+ * \{ */
+
+/* callbacks */
+static bool looptag_filter_cb(BMLoop *l, void *user_data_v)
+{
+ struct UserData_UV *user_data = user_data_v;
+ return uvedit_face_visible_test(user_data->scene, l->f);
+}
+static bool looptag_test_cb(BMLoop *l, void *user_data_v)
+{
+ /* All connected loops are selected or we return false. */
+ struct UserData_UV *user_data = user_data_v;
+ const Scene *scene = user_data->scene;
+ const uint cd_loop_uv_offset = user_data->cd_loop_uv_offset;
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ BMIter iter;
+ BMLoop *l_iter;
+ BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) {
+ if (looptag_filter_cb(l_iter, user_data)) {
+ const MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
+ if (equals_v2v2(luv->uv, luv_iter->uv)) {
+ if (!uvedit_uv_select_test(scene, l_iter, cd_loop_uv_offset)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+static void looptag_set_cb(BMLoop *l, bool val, void *user_data_v)
+{
+ struct UserData_UV *user_data = user_data_v;
+ const Scene *scene = user_data->scene;
+ BMEditMesh *em = user_data->em;
+ const uint cd_loop_uv_offset = user_data->cd_loop_uv_offset;
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ BMIter iter;
+ BMLoop *l_iter;
+ BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) {
+ if (looptag_filter_cb(l_iter, user_data)) {
+ MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
+ if (equals_v2v2(luv->uv, luv_iter->uv)) {
+ uvedit_uv_select_set(scene, em, l_iter, val, false, cd_loop_uv_offset);
+ }
+ }
+ }
+}
+
+static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
+ Object *obedit,
+ const struct PathSelectParams *op_params,
+ BMLoop *l_src,
+ BMLoop *l_dst,
+ const float aspect_y,
+ const int cd_loop_uv_offset)
+{
+ const char uv_selectmode = ED_uvedit_select_mode_get(scene);
+ const bool use_fake_edge_select = (uv_selectmode & UV_SELECT_EDGE);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ int flush = 0;
+
+ /* Variables to use when `use_fake_edge_select` is set. */
+ struct {
+ BMLoop *l_dst_activate;
+ BMLoop *l_dst_add_to_path;
+ } fake_edge_select = {NULL};
+
+ if (use_fake_edge_select) {
+ fake_edge_select.l_dst_activate = l_dst;
+
+ /* Use most distant when doing region selection.
+ * without this we get dangling edges outside the region. */
+ bool use_neaerst = (op_params->use_fill == false);
+ BMElem *ele_src = (BMElem *)l_src;
+ BMElem *ele_dst = (BMElem *)l_dst;
+ BMElem *ele_dst_final = NULL;
+ bm_loop_calc_vert_pair_from_edge_pair(
+ use_neaerst, cd_loop_uv_offset, aspect_y, &ele_src, &ele_dst, &ele_dst_final);
+
+ if (op_params->use_fill == false) {
+ /* Always activate the item under the cursor. */
+ fake_edge_select.l_dst_add_to_path = (BMLoop *)ele_dst_final;
+ }
+
+ l_src = (BMLoop *)ele_src;
+ l_dst = (BMLoop *)ele_dst;
+ }
+
+ struct UserData_UV user_data = {
+ .scene = scene,
+ .em = em,
+ .cd_loop_uv_offset = cd_loop_uv_offset,
+ };
+
+ const struct BMCalcPathUVParams params = {
+ .use_topology_distance = op_params->use_topology_distance,
+ .use_step_face = op_params->use_face_step,
+ .aspect_y = aspect_y,
+ .cd_loop_uv_offset = cd_loop_uv_offset,
+ };
+
+ LinkNode *path = NULL;
+ bool is_path_ordered = false;
+
+ if (l_src != l_dst) {
+ if (op_params->use_fill) {
+ path = BM_mesh_calc_path_uv_region_vert(bm,
+ (BMElem *)l_src,
+ (BMElem *)l_dst,
+ params.cd_loop_uv_offset,
+ looptag_filter_cb,
+ &user_data);
+ }
+ else {
+ is_path_ordered = true;
+ path = BM_mesh_calc_path_uv_vert(bm, l_src, l_dst, &params, looptag_filter_cb, &user_data);
+ }
+ }
+
+ BMLoop *l_dst_last = l_dst;
+
+ if (path) {
+ if (use_fake_edge_select) {
+ if ((fake_edge_select.l_dst_add_to_path != NULL) &&
+ (BLI_linklist_index(path, fake_edge_select.l_dst_add_to_path) == -1)) {
+ /* Append, this isn't optimal compared to #BLI_linklist_append, it's a one-off lookup. */
+ LinkNode *path_last = BLI_linklist_find_last(path);
+ BLI_linklist_insert_after(&path_last, fake_edge_select.l_dst_add_to_path);
+ BLI_assert(BLI_linklist_find_last(path)->link == fake_edge_select.l_dst_add_to_path);
+ }
+ }
+
+ /* toggle the flag */
+ bool all_set = true;
+ LinkNode *node = path;
+ do {
+ if (!looptag_test_cb((BMLoop *)node->link, &user_data)) {
+ all_set = false;
+ break;
+ }
+ } while ((node = node->next));
+
+ int depth = -1;
+ node = path;
+ do {
+ if ((is_path_ordered == false) ||
+ WM_operator_properties_checker_interval_test(&op_params->interval_params, depth)) {
+ looptag_set_cb((BMLoop *)node->link, !all_set, &user_data);
+ if (is_path_ordered) {
+ l_dst_last = node->link;
+ }
+ }
+ } while ((void)depth++, (node = node->next));
+
+ BLI_linklist_free(path, NULL);
+ flush = all_set ? -1 : 1;
+ }
+ else {
+ const bool is_act = !looptag_test_cb(l_dst, &user_data);
+ looptag_set_cb(l_dst, is_act, &user_data); /* switch the face option */
+ }
+
+ if (op_params->track_active) {
+ /* Fake edge selection. */
+ if (use_fake_edge_select) {
+ BMLoop *l_dst_activate = fake_edge_select.l_dst_activate;
+ /* TODO(campbell): Search for an active loop attached to 'l_dst'.
+ * when `BLI_linklist_index(path, l_dst_activate) == -1`
+ * In practice this rarely happens though. */
+ ED_uvedit_active_edge_loop_set(bm, l_dst_activate);
+ }
+ else {
+ ED_uvedit_active_vert_loop_set(bm, l_dst_last);
+ }
+ }
+ return flush;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Face Path
+ * \{ */
+
+/* callbacks */
+static bool facetag_filter_cb(BMFace *f, void *user_data_v)
+{
+ struct UserData_UV *user_data = user_data_v;
+ return uvedit_face_visible_test(user_data->scene, f);
+}
+static bool facetag_test_cb(BMFace *f, void *user_data_v)
+{
+ /* All connected loops are selected or we return false. */
+ struct UserData_UV *user_data = user_data_v;
+ const Scene *scene = user_data->scene;
+ const uint cd_loop_uv_offset = user_data->cd_loop_uv_offset;
+ BMIter iter;
+ BMLoop *l_iter;
+ BM_ITER_ELEM (l_iter, &iter, f, BM_LOOPS_OF_FACE) {
+ if (!uvedit_uv_select_test(scene, l_iter, cd_loop_uv_offset)) {
+ return false;
+ }
+ }
+ return true;
+}
+static void facetag_set_cb(BMFace *f, bool val, void *user_data_v)
+{
+ struct UserData_UV *user_data = user_data_v;
+ const Scene *scene = user_data->scene;
+ BMEditMesh *em = user_data->em;
+ const uint cd_loop_uv_offset = user_data->cd_loop_uv_offset;
+ uvedit_face_select_set(scene, em, f, val, false, cd_loop_uv_offset);
+}
+
+static int mouse_mesh_uv_shortest_path_face(Scene *scene,
+ Object *obedit,
+ const struct PathSelectParams *op_params,
+ BMFace *f_src,
+ BMFace *f_dst,
+ const float aspect_y,
+ const int cd_loop_uv_offset)
+{
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ int flush = 0;
+
+ struct UserData_UV user_data = {
+ .scene = scene,
+ .em = em,
+ .cd_loop_uv_offset = cd_loop_uv_offset,
+ };
+
+ const struct BMCalcPathUVParams params = {
+ .use_topology_distance = op_params->use_topology_distance,
+ .use_step_face = op_params->use_face_step,
+ .aspect_y = aspect_y,
+ .cd_loop_uv_offset = cd_loop_uv_offset,
+ };
+
+ LinkNode *path = NULL;
+ bool is_path_ordered = false;
+
+ if (f_src != f_dst) {
+ if (op_params->use_fill) {
+ path = BM_mesh_calc_path_uv_region_face(bm,
+ (BMElem *)f_src,
+ (BMElem *)f_dst,
+ params.cd_loop_uv_offset,
+ facetag_filter_cb,
+ &user_data);
+ }
+ else {
+ is_path_ordered = true;
+ path = BM_mesh_calc_path_uv_face(bm, f_src, f_dst, &params, facetag_filter_cb, &user_data);
+ }
+ }
+
+ BMFace *f_dst_last = f_dst;
+
+ if (path) {
+ /* toggle the flag */
+ bool all_set = true;
+ LinkNode *node = path;
+ do {
+ if (!facetag_test_cb((BMFace *)node->link, &user_data)) {
+ all_set = false;
+ break;
+ }
+ } while ((node = node->next));
+
+ int depth = -1;
+ node = path;
+ do {
+ if ((is_path_ordered == false) ||
+ WM_operator_properties_checker_interval_test(&op_params->interval_params, depth)) {
+ facetag_set_cb((BMFace *)node->link, !all_set, &user_data);
+ if (is_path_ordered) {
+ f_dst_last = node->link;
+ }
+ }
+ } while ((void)depth++, (node = node->next));
+
+ BLI_linklist_free(path, NULL);
+ flush = all_set ? -1 : 1;
+ }
+ else {
+ const bool is_act = !facetag_test_cb(f_dst, &user_data);
+ facetag_set_cb(f_dst, is_act, &user_data); /* switch the face option */
+ }
+
+ if (op_params->track_active) {
+ /* Unlike other types, we can track active without it being selected. */
+ BM_mesh_active_face_set(bm, f_dst_last);
+ }
+ return flush;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Main Operator for vert/edge/face tag
+ * \{ */
+
+static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op);
+
+static bool uv_shortest_path_pick_ex(Scene *scene,
+ Depsgraph *depsgraph,
+ Object *obedit,
+ const struct PathSelectParams *op_params,
+ BMElem *ele_src,
+ BMElem *ele_dst,
+ const float aspect_y,
+ const int cd_loop_uv_offset)
+{
+ const ToolSettings *ts = scene->toolsettings;
+ const char uv_selectmode = ED_uvedit_select_mode_get(scene);
+ bool ok = false;
+ int flush = 0;
+
+ if (ELEM(NULL, ele_src, ele_dst) || (ele_src->head.htype != ele_dst->head.htype)) {
+ /* pass */
+ }
+ else if (ele_src->head.htype == BM_FACE) {
+ flush = mouse_mesh_uv_shortest_path_face(scene,
+ obedit,
+ op_params,
+ (BMFace *)ele_src,
+ (BMFace *)ele_dst,
+ aspect_y,
+ cd_loop_uv_offset);
+ ok = true;
+ }
+ else if (ele_src->head.htype == BM_LOOP) {
+ flush = mouse_mesh_uv_shortest_path_vert(scene,
+ obedit,
+ op_params,
+ (BMLoop *)ele_src,
+ (BMLoop *)ele_dst,
+ aspect_y,
+ cd_loop_uv_offset);
+ ok = true;
+ }
+
+ if (ok) {
+ if (flush != 0) {
+ const bool select = (flush == 1);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (uv_selectmode & UV_SELECT_EDGE) {
+ /* Special case as we don't use true edge selection,
+ * flush the selection from the vertices. */
+ BM_mesh_select_mode_flush_ex(em->bm, SCE_SELECT_VERTEX);
+ }
+ }
+ ED_uvedit_select_sync_flush(scene->toolsettings, em, select);
+ }
+
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ }
+ else {
+ Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
+ BKE_mesh_batch_cache_dirty_tag(obedit_eval->data, BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT);
+ }
+ /* Only for region redraw. */
+ WM_main_add_notifier(NC_GEOM | ND_SELECT, obedit->data);
+ }
+
+ return ok;
+}
+
+static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Scene *scene = CTX_data_scene(C);
+ const ToolSettings *ts = scene->toolsettings;
+ const char uv_selectmode = ED_uvedit_select_mode_get(scene);
+
+ /* We could support this, it needs further testing. */
+ if (RNA_struct_property_is_set(op->ptr, "index")) {
+ return uv_shortest_path_pick_exec(C, op);
+ }
+
+ struct PathSelectParams op_params;
+ path_select_params_from_op(op, &op_params);
+
+ /* Set false if we support edge tagging. */
+ op_params.track_active = true;
+
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+
+ float co[2];
+
+ const ARegion *region = CTX_wm_region(C);
+
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+ float aspect_y;
+ {
+ float aspx, aspy;
+ ED_uvedit_get_aspect(obedit, &aspx, &aspy);
+ aspect_y = aspx / aspy;
+ }
+
+ UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
+
+ BMElem *ele_src = NULL, *ele_dst = NULL;
+
+ if (uv_selectmode == UV_SELECT_FACE) {
+ UvNearestHit hit = UV_NEAREST_HIT_INIT;
+ if (!uv_find_nearest_face(scene, obedit, co, &hit)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BMFace *f_src = BM_mesh_active_face_get(bm, false, false);
+ /* Check selection? */
+
+ ele_src = (BMElem *)f_src;
+ ele_dst = (BMElem *)hit.efa;
+ }
+
+ else if (uv_selectmode & UV_SELECT_EDGE) {
+ UvNearestHit hit = UV_NEAREST_HIT_INIT;
+ if (!uv_find_nearest_edge(scene, obedit, co, &hit)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BMLoop *l_src = NULL;
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ BMEdge *e_src = BM_mesh_active_edge_get(bm);
+ if (e_src != NULL) {
+ l_src = uv_find_nearest_loop_from_edge(scene, obedit, e_src, co);
+ }
+ }
+ else {
+ l_src = ED_uvedit_active_edge_loop_get(bm);
+ if (l_src != NULL) {
+ if ((!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset)) &&
+ (!uvedit_uv_select_test(scene, l_src->next, cd_loop_uv_offset))) {
+ l_src = NULL;
+ }
+ ele_src = (BMElem *)l_src;
+ }
+ }
+ ele_src = (BMElem *)l_src;
+ ele_dst = (BMElem *)hit.l;
+ }
+ else {
+ UvNearestHit hit = UV_NEAREST_HIT_INIT;
+ if (!uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BMLoop *l_src = NULL;
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ BMVert *v_src = BM_mesh_active_vert_get(bm);
+ if (v_src != NULL) {
+ l_src = uv_find_nearest_loop_from_vert(scene, obedit, v_src, co);
+ }
+ }
+ else {
+ l_src = ED_uvedit_active_vert_loop_get(bm);
+ if (l_src != NULL) {
+ if (!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset)) {
+ l_src = NULL;
+ }
+ }
+ }
+ ele_src = (BMElem *)l_src;
+ ele_dst = (BMElem *)hit.l;
+ }
+
+ if (ele_src == NULL || ele_dst == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ uv_shortest_path_pick_ex(
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset);
+
+ /* To support redo. */
+ int index;
+ if (uv_selectmode & UV_SELECT_FACE) {
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
+ index = BM_elem_index_get(ele_dst);
+ }
+ else if (uv_selectmode & UV_SELECT_EDGE) {
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+ index = BM_elem_index_get(ele_dst);
+ }
+ else {
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+ index = BM_elem_index_get(ele_dst);
+ }
+ RNA_int_set(op->ptr, "index", index);
+
+ return OPERATOR_FINISHED;
+}
+
+static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op)
+{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ const char uv_selectmode = ED_uvedit_select_mode_get(scene);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+ float aspect_y;
+ {
+ float aspx, aspy;
+ ED_uvedit_get_aspect(obedit, &aspx, &aspy);
+ aspect_y = aspx / aspy;
+ }
+
+ const int index = RNA_int_get(op->ptr, "index");
+
+ BMElem *ele_src, *ele_dst;
+
+ if (uv_selectmode & UV_SELECT_FACE) {
+ if (index < 0 || index >= bm->totface) {
+ return OPERATOR_CANCELLED;
+ }
+ if (!(ele_src = (BMElem *)BM_mesh_active_face_get(bm, false, false)) ||
+ !(ele_dst = (BMElem *)BM_face_at_index_find_or_table(bm, index))) {
+ return OPERATOR_CANCELLED;
+ }
+ }
+ else if (uv_selectmode & UV_SELECT_EDGE) {
+ if (index < 0 || index >= bm->totloop) {
+ return OPERATOR_CANCELLED;
+ }
+ if (!(ele_src = (BMElem *)ED_uvedit_active_edge_loop_get(bm)) ||
+ !(ele_dst = (BMElem *)BM_loop_at_index_find(bm, index))) {
+ return OPERATOR_CANCELLED;
+ }
+ }
+ else {
+ if (index < 0 || index >= bm->totloop) {
+ return OPERATOR_CANCELLED;
+ }
+ if (!(ele_src = (BMElem *)ED_uvedit_active_vert_loop_get(bm)) ||
+ !(ele_dst = (BMElem *)BM_loop_at_index_find(bm, index))) {
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ struct PathSelectParams op_params;
+ path_select_params_from_op(op, &op_params);
+ op_params.track_active = true;
+
+ if (!uv_shortest_path_pick_ex(
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void UV_OT_shortest_path_pick(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Pick Shortest Path";
+ ot->idname = "UV_OT_shortest_path_pick";
+ ot->description = "Select shortest path between two selections";
+
+ /* api callbacks */
+ ot->invoke = uv_shortest_path_pick_invoke;
+ ot->exec = uv_shortest_path_pick_exec;
+ ot->poll = ED_operator_uvedit;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ path_select_properties(ot);
+
+ /* use for redo */
+ prop = RNA_def_int(ot->srna, "index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Path Between Existing Selection
+ * \{ */
+
+static int uv_shortest_path_select_exec(bContext *C, wmOperator *op)
+{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ const char uv_selectmode = ED_uvedit_select_mode_get(scene);
+ bool found_valid_elements = false;
+
+ float aspect_y;
+ {
+ Object *obedit = CTX_data_edit_object(C);
+ float aspx, aspy;
+ ED_uvedit_get_aspect(obedit, &aspx, &aspy);
+ aspect_y = aspx / aspy;
+ }
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ BMElem *ele_src = NULL, *ele_dst = NULL;
+
+ /* Find 2x elements. */
+ {
+ BMElem **ele_array = NULL;
+ int ele_array_len = 0;
+ if (uv_selectmode & UV_SELECT_FACE) {
+ ele_array = (BMElem **)ED_uvedit_selected_faces(scene, bm, 3, &ele_array_len);
+ }
+ else if (uv_selectmode & UV_SELECT_EDGE) {
+ ele_array = (BMElem **)ED_uvedit_selected_edges(scene, bm, 3, &ele_array_len);
+ }
+ else {
+ ele_array = (BMElem **)ED_uvedit_selected_verts(scene, bm, 3, &ele_array_len);
+ }
+
+ if (ele_array_len == 2) {
+ ele_src = ele_array[0];
+ ele_dst = ele_array[1];
+ }
+ MEM_freeN(ele_array);
+ }
+
+ if (ele_src && ele_dst) {
+ struct PathSelectParams op_params;
+ path_select_params_from_op(op, &op_params);
+
+ uv_shortest_path_pick_ex(
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset);
+
+ found_valid_elements = true;
+ }
+ }
+ MEM_freeN(objects);
+
+ if (!found_valid_elements) {
+ BKE_report(
+ op->reports, RPT_WARNING, "Path selection requires two matching elements to be selected");
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void UV_OT_shortest_path_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Shortest Path";
+ ot->idname = "UV_OT_shortest_path_select";
+ ot->description = "Selected shortest path between two vertices/edges/faces";
+
+ /* api callbacks */
+ ot->exec = uv_shortest_path_select_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ path_select_properties(ot);
+}
+
+/** \} */
diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c
new file mode 100644
index 00000000000..421e58b1cb5
--- /dev/null
+++ b/source/blender/editors/uvedit/uvedit_rip.c
@@ -0,0 +1,980 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup eduv
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_ghash.h"
+#include "BLI_linklist_stack.h"
+#include "BLI_math.h"
+#include "BLI_math_vector.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_image_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_editmesh.h"
+#include "BKE_layer.h"
+#include "BKE_report.h"
+
+#include "DEG_depsgraph.h"
+
+#include "ED_screen.h"
+#include "ED_transform.h"
+#include "ED_uvedit.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_view2d.h"
+
+#include "uvedit_intern.h"
+
+/* -------------------------------------------------------------------- */
+/** \name UV Loop Rip Data Struct
+ * \{ */
+
+/** Unordered loop data, stored in #BMLoop.head.index. */
+typedef struct ULData {
+ /** When this UV is selected as well as the next UV. */
+ uint is_select_edge : 1;
+ /**
+ * When only this UV is selected and none of the other UV's
+ * around the connected fan are attached to an edge.
+ *
+ * In this case there is no need to detect contiguous loops,
+ * each isolated case is handled on it's own, no need to walk over selected edges.
+ *
+ * \note This flag isn't flushed to other loops which could also have this enabled.
+ * Currently it's not necessary since we can start off on any one of these loops,
+ * then walk onto the other loops around the uv-fan, without having the flag to be
+ * set on all loops.
+ */
+ uint is_select_vert_single : 1;
+ /** This could be a face-tag. */
+ uint is_select_all : 1;
+ /** Use when building the rip-pairs stack. */
+ uint in_stack : 1;
+ /** Set once this has been added into a #UVRipPairs. */
+ uint in_rip_pairs : 1;
+ /** The side this loop is part of. */
+ uint side : 1;
+ /**
+ * Paranoid check to ensure we don't enter eternal loop swapping sides,
+ * this could happen with float precision error, making a swap to measure as slightly better
+ * depending on the order of addition.
+ */
+ uint side_was_swapped : 1;
+} ULData;
+
+/** Ensure this fits in an int (loop index). */
+BLI_STATIC_ASSERT(sizeof(ULData) <= sizeof(int), "");
+
+BLI_INLINE ULData *UL(BMLoop *l)
+{
+ return (ULData *)&l->head.index;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Utilities
+ * \{ */
+
+static BMLoop *bm_loop_find_other_radial_loop_with_visible_face(BMLoop *l_src,
+ const int cd_loop_uv_offset)
+{
+ BMLoop *l_other = NULL;
+ BMLoop *l_iter = l_src->radial_next;
+ if (l_iter != l_src) {
+ do {
+ if (BM_elem_flag_test(l_iter->f, BM_ELEM_TAG) && UL(l_iter)->is_select_edge &&
+ BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset)) {
+ /* Check UV's are contiguous. */
+ if (l_other == NULL) {
+ l_other = l_iter;
+ }
+ else {
+ /* Only use when there is a single alternative. */
+ l_other = NULL;
+ break;
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l_src);
+ }
+ return l_other;
+}
+
+static BMLoop *bm_loop_find_other_fan_loop_with_visible_face(BMLoop *l_src,
+ BMVert *v_src,
+ const int cd_loop_uv_offset)
+{
+ BLI_assert(BM_vert_in_edge(l_src->e, v_src));
+ BMLoop *l_other = NULL;
+ BMLoop *l_iter = l_src->radial_next;
+ if (l_iter != l_src) {
+ do {
+ if (BM_elem_flag_test(l_iter->f, BM_ELEM_TAG) &&
+ BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset)) {
+ /* Check UV's are contiguous. */
+ if (l_other == NULL) {
+ l_other = l_iter;
+ }
+ else {
+ /* Only use when there is a single alternative. */
+ l_other = NULL;
+ break;
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l_src);
+ }
+ if (l_other != NULL) {
+ if (l_other->v == v_src) {
+ /* do nothing. */
+ }
+ else if (l_other->next->v == v_src) {
+ l_other = l_other->next;
+ }
+ else if (l_other->prev->v == v_src) {
+ l_other = l_other->prev;
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ return l_other;
+}
+
+/**
+ * A version of #BM_vert_step_fan_loop that checks UV's.
+ */
+static BMLoop *bm_vert_step_fan_loop_uv(BMLoop *l, BMEdge **e_step, const int cd_loop_uv_offset)
+{
+ BMEdge *e_prev = *e_step;
+ BMLoop *l_next;
+ if (l->e == e_prev) {
+ l_next = l->prev;
+ }
+ else if (l->prev->e == e_prev) {
+ l_next = l;
+ }
+ else {
+ BLI_assert(0);
+ return NULL;
+ }
+
+ *e_step = l_next->e;
+
+ return bm_loop_find_other_fan_loop_with_visible_face(l_next, l->v, cd_loop_uv_offset);
+}
+
+static void bm_loop_uv_select_single_vert_validate(BMLoop *l_init, const int cd_loop_uv_offset)
+{
+ const MLoopUV *luv_init = BM_ELEM_CD_GET_VOID_P(l_init, cd_loop_uv_offset);
+ BMIter liter;
+ BMLoop *l;
+ bool is_single_vert = true;
+ BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_init->uv, luv->uv)) {
+ if (UL(l->prev)->is_select_edge || UL(l)->is_select_edge) {
+ is_single_vert = false;
+ break;
+ }
+ }
+ }
+ if (is_single_vert == false) {
+ BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) {
+ if (UL(l)->is_select_vert_single) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_init->uv, luv->uv)) {
+ UL(l)->is_select_vert_single = false;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * The corner return values calculate the angle between both loops,
+ * the edge values pick the closest to the either edge (ignoring the center).
+ *
+ * \param dir: Direction to calculate the angle to (normalized and aspect corrected).
+ */
+static void bm_loop_calc_uv_angle_from_dir(BMLoop *l,
+ const float dir[2],
+ const float aspect_y,
+ const int cd_loop_uv_offset,
+ float *r_corner_angle,
+ float *r_edge_angle,
+ int *r_edge_index)
+{
+ /* Calculate 3 directions, return the shortest angle. */
+ float dir_test[3][2];
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
+ const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+
+ sub_v2_v2v2(dir_test[0], luv->uv, luv_prev->uv);
+ sub_v2_v2v2(dir_test[2], luv->uv, luv_next->uv);
+ dir_test[0][1] /= aspect_y;
+ dir_test[2][1] /= aspect_y;
+
+ normalize_v2(dir_test[0]);
+ normalize_v2(dir_test[2]);
+
+ /* Calculate the orthogonal line (same as negating one, then adding). */
+ sub_v2_v2v2(dir_test[1], dir_test[0], dir_test[2]);
+ normalize_v2(dir_test[1]);
+
+ /* Rotate 90 degrees. */
+ SWAP(float, dir_test[1][0], dir_test[1][1]);
+ dir_test[1][1] *= -1.0f;
+
+ if (BM_face_uv_calc_cross(l->f, cd_loop_uv_offset) > 0.0f) {
+ negate_v2(dir_test[1]);
+ }
+
+ const float angles[3] = {
+ angle_v2v2(dir, dir_test[0]),
+ angle_v2v2(dir, dir_test[1]),
+ angle_v2v2(dir, dir_test[2]),
+ };
+
+ /* Set the corner values. */
+ *r_corner_angle = angles[1];
+
+ /* Set the edge values. */
+ if (angles[0] < angles[2]) {
+ *r_edge_angle = angles[0];
+ *r_edge_index = -1;
+ }
+ else {
+ *r_edge_angle = angles[2];
+ *r_edge_index = 1;
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Rip Single
+ * \{ */
+
+typedef struct UVRipSingle {
+ /** Walk around the selected UV point, store #BMLoop. */
+ GSet *loops;
+} UVRipSingle;
+
+/**
+ * Handle single loop, the following cases:
+ *
+ * - An isolated fan, without a shared UV edge to other fans which share the same coordinate,
+ * in this case we just need to pick the closest fan to \a co.
+ *
+ * - In the case of contiguous loops (part of the same fan).
+ * Rip away the loops connected to the closest edge.
+ *
+ * - In the case of 2 contiguous loops.
+ * Rip the closest loop away.
+ *
+ * \note This matches the behavior of edit-mesh rip tool.
+ */
+static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig,
+ const float co[2],
+ const float aspect_y,
+ const int cd_loop_uv_offset)
+{
+ UVRipSingle *rip = MEM_callocN(sizeof(*rip), __func__);
+ const float *co_center =
+ (((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_init_orig, cd_loop_uv_offset))->uv);
+ rip->loops = BLI_gset_ptr_new(__func__);
+
+ /* Track the closest loop, start walking from this so in the event we have multiple
+ * disconnected fans, we can rip away loops connected to this one. */
+ BMLoop *l_init = NULL;
+ BMLoop *l_init_edge = NULL;
+ float corner_angle_best = FLT_MAX;
+ float edge_angle_best = FLT_MAX;
+ int edge_index_best = 0; /* -1 or +1 (never center). */
+
+ /* Calculate the direction from the cursor with aspect correction. */
+ float dir_co[2];
+ sub_v2_v2v2(dir_co, co_center, co);
+ dir_co[1] /= aspect_y;
+ if (UNLIKELY(normalize_v2(dir_co) == 0.0)) {
+ dir_co[1] = 1.0f;
+ }
+
+ int uv_fan_count_all = 0;
+ {
+ BMIter liter;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, l_init_orig->v, BM_LOOPS_OF_VERT) {
+ if (BM_elem_flag_test(l->f, BM_ELEM_TAG)) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(co_center, luv->uv)) {
+ uv_fan_count_all += 1;
+ /* Clear at the same time. */
+ UL(l)->is_select_vert_single = true;
+ UL(l)->side = 0;
+ BLI_gset_add(rip->loops, l);
+
+ /* Update `l_init_close` */
+ float corner_angle_test;
+ float edge_angle_test;
+ int edge_index_test;
+ bm_loop_calc_uv_angle_from_dir(l,
+ dir_co,
+ aspect_y,
+ cd_loop_uv_offset,
+ &corner_angle_test,
+ &edge_angle_test,
+ &edge_index_test);
+ if ((corner_angle_best == FLT_MAX) || (corner_angle_test < corner_angle_best)) {
+ corner_angle_best = corner_angle_test;
+ l_init = l;
+ }
+
+ /* Trick so we don't consider concave corners further away than they should be. */
+ edge_angle_test = min_ff(corner_angle_test, edge_angle_test);
+
+ if ((edge_angle_best == FLT_MAX) || (edge_angle_test < edge_angle_best)) {
+ edge_angle_best = edge_angle_test;
+ edge_index_best = edge_index_test;
+ l_init_edge = l;
+ }
+ }
+ }
+ }
+ }
+
+ /* Walk around the `l_init` in both directions of the UV fan. */
+ int uv_fan_count_contiguous = 1;
+ UL(l_init)->side = 1;
+ for (int i = 0; i < 2; i += 1) {
+ BMEdge *e_prev = i ? l_init->e : l_init->prev->e;
+ BMLoop *l_iter = l_init;
+ while (((l_iter = bm_vert_step_fan_loop_uv(l_iter, &e_prev, cd_loop_uv_offset)) != l_init) &&
+ (l_iter != NULL) && (UL(l_iter)->side == 0)) {
+ uv_fan_count_contiguous += 1;
+ /* Keep. */
+ UL(l_iter)->side = 1;
+ }
+ /* May be useful to know if the fan is closed, currently it's not needed. */
+#if 0
+ if (l_iter == l_init) {
+ is_closed = true;
+ }
+#endif
+ }
+
+ if (uv_fan_count_contiguous != uv_fan_count_all) {
+ /* Simply rip off the current fan, all tagging is done. */
+ }
+ else {
+ GSetIterator gs_iter;
+ GSET_ITER (gs_iter, rip->loops) {
+ BMLoop *l = BLI_gsetIterator_getKey(&gs_iter);
+ UL(l)->side = 0;
+ }
+
+ if (uv_fan_count_contiguous <= 2) {
+ /* Simple case, rip away the closest loop. */
+ UL(l_init)->side = 1;
+ }
+ else {
+ /* Rip away from the closest edge. */
+ BMLoop *l_radial_init = (edge_index_best == -1) ? l_init_edge->prev : l_init_edge;
+ BMLoop *l_radial_iter = l_radial_init;
+ do {
+ if (BM_loop_uv_share_edge_check(l_radial_init, l_radial_iter, cd_loop_uv_offset)) {
+ BMLoop *l = (l_radial_iter->v == l_init->v) ? l_radial_iter : l_radial_iter->next;
+ BLI_assert(l->v == l_init->v);
+ /* Keep. */
+ UL(l)->side = 1;
+ }
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l_radial_init);
+ }
+ }
+
+ return rip;
+}
+
+static void uv_rip_single_free(UVRipSingle *rip)
+{
+ BLI_gset_free(rip->loops, NULL);
+ MEM_freeN(rip);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Rip Loop Pairs
+ * \{ */
+
+typedef struct UVRipPairs {
+ /** Walk along the UV selection, store #BMLoop. */
+ GSet *loops;
+} UVRipPairs;
+
+static void uv_rip_pairs_add(UVRipPairs *rip, BMLoop *l)
+{
+ ULData *ul = UL(l);
+ BLI_assert(!BLI_gset_haskey(rip->loops, l));
+ BLI_assert(ul->in_rip_pairs == false);
+ ul->in_rip_pairs = true;
+ BLI_gset_add(rip->loops, l);
+}
+
+static void uv_rip_pairs_remove(UVRipPairs *rip, BMLoop *l)
+{
+ ULData *ul = UL(l);
+ BLI_assert(BLI_gset_haskey(rip->loops, l));
+ BLI_assert(ul->in_rip_pairs == true);
+ ul->in_rip_pairs = false;
+ BLI_gset_remove(rip->loops, l, NULL);
+}
+
+/**
+ * \note While this isn't especially efficient,
+ * this is only needed for rip-pairs end-points (only two per contiguous selection loop).
+ */
+static float uv_rip_pairs_calc_uv_angle(BMLoop *l_init,
+ uint side,
+ const float aspect_y,
+ const int cd_loop_uv_offset)
+{
+ BMIter liter;
+ const MLoopUV *luv_init = BM_ELEM_CD_GET_VOID_P(l_init, cd_loop_uv_offset);
+ float angle_of_side = 0.0f;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) {
+ if (UL(l)->in_rip_pairs) {
+ if (UL(l)->side == side) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_init->uv, luv->uv)) {
+ const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
+ const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ float dir_prev[2], dir_next[2];
+ sub_v2_v2v2(dir_prev, luv_prev->uv, luv->uv);
+ sub_v2_v2v2(dir_next, luv_next->uv, luv->uv);
+ dir_prev[1] /= aspect_y;
+ dir_next[1] /= aspect_y;
+ const float luv_angle = angle_v2v2(dir_prev, dir_next);
+ if (LIKELY(isfinite(luv_angle))) {
+ angle_of_side += luv_angle;
+ }
+ }
+ }
+ }
+ }
+ return angle_of_side;
+}
+
+static int uv_rip_pairs_loop_count_on_side(BMLoop *l_init, uint side, const int cd_loop_uv_offset)
+{
+ const MLoopUV *luv_init = BM_ELEM_CD_GET_VOID_P(l_init, cd_loop_uv_offset);
+ int count = 0;
+ BMIter liter;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) {
+ if (UL(l)->in_rip_pairs) {
+ if (UL(l)->side == side) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_init->uv, luv->uv)) {
+ count += 1;
+ }
+ }
+ }
+ }
+ return count;
+}
+
+static bool uv_rip_pairs_loop_change_sides_test(BMLoop *l_switch,
+ BMLoop *l_target,
+ const float aspect_y,
+ const int cd_loop_uv_offset)
+{
+ const int side_a = UL(l_switch)->side;
+ const int side_b = UL(l_target)->side;
+
+ BLI_assert(UL(l_switch)->side != UL(l_target)->side);
+
+ /* First, check if this is a simple grid topology,
+ * in that case always choose the adjacent edge. */
+ const int count_a = uv_rip_pairs_loop_count_on_side(l_switch, side_a, cd_loop_uv_offset);
+ const int count_b = uv_rip_pairs_loop_count_on_side(l_target, side_b, cd_loop_uv_offset);
+ if (count_a + count_b == 4) {
+ return count_a > count_b;
+ }
+
+ const float angle_a_before = uv_rip_pairs_calc_uv_angle(
+ l_switch, side_a, aspect_y, cd_loop_uv_offset);
+ const float angle_b_before = uv_rip_pairs_calc_uv_angle(
+ l_target, side_b, aspect_y, cd_loop_uv_offset);
+
+ UL(l_switch)->side = side_b;
+
+ const float angle_a_after = uv_rip_pairs_calc_uv_angle(
+ l_switch, side_a, aspect_y, cd_loop_uv_offset);
+ const float angle_b_after = uv_rip_pairs_calc_uv_angle(
+ l_target, side_b, aspect_y, cd_loop_uv_offset);
+
+ UL(l_switch)->side = side_a;
+
+ return fabsf(angle_a_before - angle_b_before) > fabsf(angle_a_after - angle_b_after);
+}
+
+/**
+ * Create 2x sides of a UV rip-pairs, the result is unordered, supporting non-contiguous rails.
+ *
+ * \param l_init: A loop on a boundary which can be used to initialize flood-filling.
+ * This will always be added to the first side. Other loops will be added to the second side.
+ *
+ * \note We could have more than two sides, however in practice this almost never happens.
+ */
+static UVRipPairs *uv_rip_pairs_from_loop(BMLoop *l_init,
+ const float aspect_y,
+ const int cd_loop_uv_offset)
+{
+ UVRipPairs *rip = MEM_callocN(sizeof(*rip), __func__);
+ rip->loops = BLI_gset_ptr_new(__func__);
+
+ /* We can rely on this stack being small, as we're walking down two sides of an edge loop,
+ * so the stack wont be much larger than the total number of fans at any one vertex. */
+ BLI_SMALLSTACK_DECLARE(stack, BMLoop *);
+
+ /* Needed for cases when we walk onto loops which already have a side assigned,
+ * in this case we need to pick a better side (see #uv_rip_pairs_loop_change_sides_test)
+ * and put the loop back in the stack,
+ * which is needed in the case adjacent loops should also switch sides. */
+#define UV_SET_SIDE_AND_REMOVE_FROM_RAIL(loop, side_value) \
+ { \
+ BLI_assert(UL(loop)->side_was_swapped == false); \
+ BLI_assert(UL(loop)->side != side_value); \
+ if (!UL(loop)->in_stack) { \
+ BLI_SMALLSTACK_PUSH(stack, loop); \
+ UL(loop)->in_stack = true; \
+ } \
+ if (UL(loop)->in_rip_pairs) { \
+ uv_rip_pairs_remove(rip, loop); \
+ } \
+ UL(loop)->side = side_value; \
+ UL(loop)->side_was_swapped = true; \
+ }
+
+ /* Initialize the stack. */
+ BLI_SMALLSTACK_PUSH(stack, l_init);
+ UL(l_init)->in_stack = true;
+
+ BMLoop *l_step;
+ while ((l_step = BLI_SMALLSTACK_POP(stack))) {
+ int side = UL(l_step)->side;
+ UL(l_step)->in_stack = false;
+
+ /* Note that we could add all loops into the rip-pairs when adding into the stack,
+ * however this complicates removal, so add into the rip-pairs when popping from the stack. */
+ uv_rip_pairs_add(rip, l_step);
+
+ /* Add to the other side if it exists. */
+ if (UL(l_step)->is_select_edge) {
+ BMLoop *l_other = bm_loop_find_other_radial_loop_with_visible_face(l_step,
+ cd_loop_uv_offset);
+ if (l_other != NULL) {
+ if (!UL(l_other)->in_rip_pairs && !UL(l_other)->in_stack) {
+ BLI_SMALLSTACK_PUSH(stack, l_other);
+ UL(l_other)->in_stack = true;
+ UL(l_other)->side = !side;
+ }
+ else {
+ if (UL(l_other)->side == side) {
+ if (UL(l_other)->side_was_swapped == false) {
+ UV_SET_SIDE_AND_REMOVE_FROM_RAIL(l_other, !side);
+ }
+ }
+ }
+ }
+
+ /* Add the next loop along the edge on the same side. */
+ l_other = l_step->next;
+ if (!UL(l_other)->in_rip_pairs && !UL(l_other)->in_stack) {
+ BLI_SMALLSTACK_PUSH(stack, l_other);
+ UL(l_other)->in_stack = true;
+ UL(l_other)->side = side;
+ }
+ else {
+ if (UL(l_other)->side != side) {
+ if ((UL(l_other)->side_was_swapped == false) &&
+ uv_rip_pairs_loop_change_sides_test(l_other, l_step, aspect_y, cd_loop_uv_offset)) {
+ UV_SET_SIDE_AND_REMOVE_FROM_RAIL(l_other, side);
+ }
+ }
+ }
+ }
+
+ /* Walk over the fan of loops, starting from `l_step` in both directions. */
+ for (int i = 0; i < 2; i++) {
+ BMLoop *l_radial_first = i ? l_step : l_step->prev;
+ if (l_radial_first != l_radial_first->radial_next) {
+ BMEdge *e_radial = l_radial_first->e;
+ BMLoop *l_radial_iter = l_radial_first->radial_next;
+ do {
+ /* Not a boundary and visible. */
+ if (!UL(l_radial_iter)->is_select_edge &&
+ BM_elem_flag_test(l_radial_iter->f, BM_ELEM_TAG)) {
+ BMLoop *l_other = (l_radial_iter->v == l_step->v) ? l_radial_iter :
+ l_radial_iter->next;
+ BLI_assert(l_other->v == l_step->v);
+ if (BM_edge_uv_share_vert_check(e_radial, l_other, l_step, cd_loop_uv_offset)) {
+ if (!UL(l_other)->in_rip_pairs && !UL(l_other)->in_stack) {
+ BLI_SMALLSTACK_PUSH(stack, l_other);
+ UL(l_other)->in_stack = true;
+ UL(l_other)->side = side;
+ }
+ else {
+ if (UL(l_other)->side != side) {
+ if ((UL(l_other)->side_was_swapped == false) &&
+ uv_rip_pairs_loop_change_sides_test(
+ l_other, l_step, aspect_y, cd_loop_uv_offset)) {
+ UV_SET_SIDE_AND_REMOVE_FROM_RAIL(l_other, side);
+ }
+ }
+ }
+ }
+ }
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l_radial_first);
+ }
+ }
+ }
+
+#undef UV_SET_SIDE_AND_REMOVE_FROM_RAIL
+
+ return rip;
+}
+
+static void uv_rip_pairs_free(UVRipPairs *rip)
+{
+ BLI_gset_free(rip->loops, NULL);
+ MEM_freeN(rip);
+}
+
+/**
+ * This is an approximation, it's easily good enough for our purpose.
+ */
+static bool uv_rip_pairs_calc_center_and_direction(UVRipPairs *rip,
+ const int cd_loop_uv_offset,
+ float r_center[2],
+ float r_dir_side[2][2])
+{
+ zero_v2(r_center);
+ int center_total = 0;
+ int side_total[2] = {0, 0};
+
+ for (int i = 0; i < 2; i++) {
+ zero_v2(r_dir_side[i]);
+ }
+ GSetIterator gs_iter;
+ GSET_ITER (gs_iter, rip->loops) {
+ BMLoop *l = BLI_gsetIterator_getKey(&gs_iter);
+ int side = UL(l)->side;
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ add_v2_v2(r_center, luv->uv);
+
+ float dir[2];
+ if (!UL(l)->is_select_edge) {
+ const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ sub_v2_v2v2(dir, luv_next->uv, luv->uv);
+ add_v2_v2(r_dir_side[side], dir);
+ }
+ if (!UL(l->prev)->is_select_edge) {
+ const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
+ sub_v2_v2v2(dir, luv_prev->uv, luv->uv);
+ add_v2_v2(r_dir_side[side], dir);
+ }
+ side_total[side] += 1;
+ }
+ center_total += BLI_gset_len(rip->loops);
+
+ for (int i = 0; i < 2; i++) {
+ normalize_v2(r_dir_side[i]);
+ }
+ mul_v2_fl(r_center, 1.0f / center_total);
+
+ /* If only a single side is selected, don't handle this rip-pairs. */
+ return side_total[0] && side_total[1];
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Rip Main Function
+ * \{ */
+
+/**
+ * \return true when a change was made.
+ */
+static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const float aspect_y)
+{
+ Mesh *me = (Mesh *)obedit->data;
+ BMEditMesh *em = me->edit_mesh;
+ BMesh *bm = em->bm;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ BMFace *efa;
+ BMIter iter, liter;
+ BMLoop *l;
+
+ const ULData ul_clear = {0};
+
+ bool changed = false;
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_TAG, uvedit_face_visible_test(scene, efa));
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ ULData *ul = UL(l);
+ *ul = ul_clear;
+ }
+ }
+ bm->elem_index_dirty |= BM_LOOP;
+
+ bool is_select_all_any = false;
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ bool is_all = true;
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (luv->flag & MLOOPUV_VERTSEL) {
+ const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
+ const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ if (luv_next->flag & MLOOPUV_VERTSEL) {
+ UL(l)->is_select_edge = true;
+ }
+ else {
+ if ((luv_prev->flag & MLOOPUV_VERTSEL) == 0) {
+ /* #bm_loop_uv_select_single_vert_validate validates below. */
+ UL(l)->is_select_vert_single = true;
+ }
+ }
+ }
+ else {
+ is_all = false;
+ }
+ }
+ if (is_all) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ UL(l)->is_select_all = true;
+ }
+ is_select_all_any = true;
+ }
+ }
+ }
+
+ /* Remove #ULData.is_select_vert_single when connected to selected edges. */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ if (UL(l)->is_select_vert_single) {
+ bm_loop_uv_select_single_vert_validate(l, cd_loop_uv_offset);
+ }
+ }
+ }
+ }
+
+ /* Special case: if we have selected faces, isolated them.
+ * This isn't a rip, however it's useful for users as a quick way
+ * to detach the selection.
+ *
+ * We could also extract an edge loop from the boundary
+ * however in practice it's not that useful, see T78751. */
+ if (is_select_all_any) {
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ if (!UL(l)->is_select_all) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (luv->flag & MLOOPUV_VERTSEL) {
+ luv->flag &= ~MLOOPUV_VERTSEL;
+ changed = true;
+ }
+ }
+ }
+ }
+ return changed;
+ }
+
+ /* Extract loop pairs or single loops. */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ if (UL(l)->is_select_edge) {
+ if (!UL(l)->in_rip_pairs) {
+ UVRipPairs *rip = uv_rip_pairs_from_loop(l, aspect_y, cd_loop_uv_offset);
+ float center[2];
+ float dir_cursor[2];
+ float dir_side[2][2];
+ int side_from_cursor = -1;
+ if (uv_rip_pairs_calc_center_and_direction(rip, cd_loop_uv_offset, center, dir_side)) {
+ for (int i = 0; i < 2; i++) {
+ sub_v2_v2v2(dir_cursor, center, co);
+ normalize_v2(dir_cursor);
+ }
+ side_from_cursor = (dot_v2v2(dir_side[0], dir_cursor) -
+ dot_v2v2(dir_side[1], dir_cursor)) < 0.0f;
+ }
+ GSetIterator gs_iter;
+ GSET_ITER (gs_iter, rip->loops) {
+ BMLoop *l_iter = BLI_gsetIterator_getKey(&gs_iter);
+ ULData *ul = UL(l_iter);
+ if (ul->side == side_from_cursor) {
+ uvedit_uv_select_disable(scene, em, l_iter, cd_loop_uv_offset);
+ changed = true;
+ }
+ /* Ensure we don't operate on these again. */
+ *ul = ul_clear;
+ }
+ uv_rip_pairs_free(rip);
+ }
+ }
+ else if (UL(l)->is_select_vert_single) {
+ UVRipSingle *rip = uv_rip_single_from_loop(l, co, aspect_y, cd_loop_uv_offset);
+ /* We only ever use one side. */
+ const int side_from_cursor = 0;
+ GSetIterator gs_iter;
+ GSET_ITER (gs_iter, rip->loops) {
+ BMLoop *l_iter = BLI_gsetIterator_getKey(&gs_iter);
+ ULData *ul = UL(l_iter);
+ if (ul->side == side_from_cursor) {
+ uvedit_uv_select_disable(scene, em, l_iter, cd_loop_uv_offset);
+ changed = true;
+ }
+ /* Ensure we don't operate on these again. */
+ *ul = ul_clear;
+ }
+ uv_rip_single_free(rip);
+ }
+ }
+ }
+ }
+ return changed;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name UV Rip Operator
+ * \{ */
+
+static int uv_rip_exec(bContext *C, wmOperator *op)
+{
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ bool changed_multi = false;
+
+ float co[2];
+ RNA_float_get_array(op->ptr, "location", co);
+
+ float aspx, aspy;
+ {
+ /* Note that we only want to run this on the */
+ Object *obedit = CTX_data_edit_object(C);
+ ED_uvedit_get_aspect(obedit, &aspx, &aspy);
+ }
+ const float aspect_y = aspx / aspy;
+
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ view_layer, ((View3D *)NULL), &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+
+ if (uv_rip_object(scene, obedit, co, aspect_y)) {
+ changed_multi = true;
+ uvedit_live_unwrap_update(sima, scene, obedit);
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ }
+ }
+ MEM_freeN(objects);
+
+ if (!changed_multi) {
+ BKE_report(op->reports, RPT_ERROR, "Rip failed");
+ return OPERATOR_CANCELLED;
+ }
+ return OPERATOR_FINISHED;
+}
+
+static int uv_rip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ float co[2];
+
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
+ RNA_float_set_array(op->ptr, "location", co);
+
+ return uv_rip_exec(C, op);
+}
+
+void UV_OT_rip(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "UV Rip";
+ ot->description = "Rip selected vertices or a selected region";
+ ot->idname = "UV_OT_rip";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = uv_rip_exec;
+ ot->invoke = uv_rip_invoke;
+ ot->poll = ED_operator_uvedit;
+
+ /* translation data */
+ Transform_Properties(ot, P_MIRROR_DUMMY);
+
+ /* properties */
+ RNA_def_float_vector(
+ ot->srna,
+ "location",
+ 2,
+ NULL,
+ -FLT_MAX,
+ FLT_MAX,
+ "Location",
+ "Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds",
+ -100.0f,
+ 100.0f);
+}
+
+/** \} */
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index cc9be9d48c1..151c881a466 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -88,12 +88,128 @@ static void uv_select_tag_update_for_object(Depsgraph *depsgraph,
Object *obedit);
/* -------------------------------------------------------------------- */
+/** \name Active Selection Tracking
+ *
+ * Currently we don't store loops in the selection history,
+ * store face/edge/vert combinations (needed for UV path selection).
+ * \{ */
+
+void ED_uvedit_active_vert_loop_set(BMesh *bm, BMLoop *l)
+{
+ BM_select_history_clear(bm);
+ BM_select_history_remove(bm, (BMElem *)l->f);
+ BM_select_history_remove(bm, (BMElem *)l->v);
+ BM_select_history_store_notest(bm, (BMElem *)l->f);
+ BM_select_history_store_notest(bm, (BMElem *)l->v);
+}
+
+BMLoop *ED_uvedit_active_vert_loop_get(BMesh *bm)
+{
+ BMEditSelection *ese = bm->selected.last;
+ if (ese && ese->prev) {
+ BMEditSelection *ese_prev = ese->prev;
+ if ((ese->htype == BM_VERT) && (ese_prev->htype == BM_FACE)) {
+ /* May be NULL. */
+ return BM_face_vert_share_loop((BMFace *)ese_prev->ele, (BMVert *)ese->ele);
+ }
+ }
+ return NULL;
+}
+
+void ED_uvedit_active_edge_loop_set(BMesh *bm, BMLoop *l)
+{
+ BM_select_history_clear(bm);
+ BM_select_history_remove(bm, (BMElem *)l->f);
+ BM_select_history_remove(bm, (BMElem *)l->e);
+ BM_select_history_store_notest(bm, (BMElem *)l->f);
+ BM_select_history_store_notest(bm, (BMElem *)l->e);
+}
+
+BMLoop *ED_uvedit_active_edge_loop_get(BMesh *bm)
+{
+ BMEditSelection *ese = bm->selected.last;
+ if (ese && ese->prev) {
+ BMEditSelection *ese_prev = ese->prev;
+ if ((ese->htype == BM_EDGE) && (ese_prev->htype == BM_FACE)) {
+ /* May be NULL. */
+ return BM_face_edge_share_loop((BMFace *)ese_prev->ele, (BMEdge *)ese->ele);
+ }
+ }
+ return NULL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Visibility and Selection Utilities
* \{ */
-static void uv_select_island_limit_default(SpaceImage *sima, float r_limit[2])
+/**
+ * Intentionally don't return #UV_SELECT_ISLAND as it's not an element type.
+ * In this case return #UV_SELECT_VERTEX as a fallback.
+ */
+char ED_uvedit_select_mode_get(const Scene *scene)
{
- uvedit_pixel_to_float(sima, 0.05f, r_limit);
+ const ToolSettings *ts = scene->toolsettings;
+ char uv_selectmode = UV_SELECT_VERTEX;
+
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (ts->selectmode & SCE_SELECT_VERTEX) {
+ uv_selectmode = UV_SELECT_VERTEX;
+ }
+ else if (ts->selectmode & SCE_SELECT_EDGE) {
+ uv_selectmode = UV_SELECT_EDGE;
+ }
+ else if (ts->selectmode & SCE_SELECT_FACE) {
+ uv_selectmode = UV_SELECT_FACE;
+ }
+ }
+ else {
+ if (ts->uv_selectmode & UV_SELECT_VERTEX) {
+ uv_selectmode = UV_SELECT_VERTEX;
+ }
+ else if (ts->uv_selectmode & UV_SELECT_EDGE) {
+ uv_selectmode = UV_SELECT_EDGE;
+ }
+ else if (ts->uv_selectmode & UV_SELECT_FACE) {
+ uv_selectmode = UV_SELECT_FACE;
+ }
+ }
+ return uv_selectmode;
+}
+
+void ED_uvedit_select_sync_flush(const ToolSettings *ts, BMEditMesh *em, const bool select)
+{
+ /* bmesh API handles flushing but not on de-select */
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (ts->selectmode != SCE_SELECT_FACE) {
+ if (select == false) {
+ EDBM_deselect_flush(em);
+ }
+ else {
+ EDBM_select_flush(em);
+ }
+ }
+
+ if (select == false) {
+ BM_select_history_validate(em->bm);
+ }
+ }
+}
+
+/**
+ * Apply a penalty to elements that are already selected
+ * so elements that aren't already selected are prioritized.
+ *
+ * \note This is calculated in screen-space otherwise zooming in on a uv-vert and
+ * shift-selecting can consider an adjacent point close enough to add to
+ * the selection rather than de-selecting the closest.
+ */
+static float uv_select_penalty_default(SpaceImage *sima)
+{
+ float penalty[2];
+ uvedit_pixel_to_float(sima, 5.0f / (sima ? sima->zoom : 1.0f), penalty);
+ return len_v2(penalty);
}
static void uvedit_vertex_select_tagged(BMEditMesh *em,
@@ -108,7 +224,7 @@ static void uvedit_vertex_select_tagged(BMEditMesh *em,
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
}
}
}
@@ -119,9 +235,7 @@ bool uvedit_face_visible_test_ex(const ToolSettings *ts, BMFace *efa)
if (ts->uv_flag & UV_SYNC_SELECTION) {
return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0);
}
- else {
- return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0 && BM_elem_flag_test(efa, BM_ELEM_SELECT));
- }
+ return (BM_elem_flag_test(efa, BM_ELEM_HIDDEN) == 0 && BM_elem_flag_test(efa, BM_ELEM_SELECT));
}
bool uvedit_face_visible_test(const Scene *scene, BMFace *efa)
{
@@ -133,27 +247,47 @@ bool uvedit_face_select_test_ex(const ToolSettings *ts, BMFace *efa, const int c
if (ts->uv_flag & UV_SYNC_SELECTION) {
return (BM_elem_flag_test(efa, BM_ELEM_SELECT));
}
- else {
- BMLoop *l;
- MLoopUV *luv;
- BMIter liter;
- 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_VERTSEL)) {
- return false;
- }
- }
+ BMLoop *l;
+ MLoopUV *luv;
+ BMIter liter;
- return true;
+ 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_VERTSEL)) {
+ return false;
+ }
}
+ return true;
}
bool uvedit_face_select_test(const Scene *scene, BMFace *efa, const int cd_loop_uv_offset)
{
return uvedit_face_select_test_ex(scene->toolsettings, efa, cd_loop_uv_offset);
}
-bool uvedit_face_select_set(const struct Scene *scene,
+void uvedit_face_select_set_with_sticky(const SpaceImage *sima,
+ const Scene *scene,
+ BMEditMesh *em,
+ BMFace *efa,
+ const bool select,
+ const bool do_history,
+ const int cd_loop_uv_offset)
+{
+ const ToolSettings *ts = scene->toolsettings;
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ uvedit_face_select_set(scene, em, efa, select, do_history, cd_loop_uv_offset);
+ return;
+ }
+
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ uvedit_uv_select_set_with_sticky(
+ sima, scene, em, l_iter, select, do_history, cd_loop_uv_offset);
+ } while ((l_iter = l_iter->next) != l_first);
+}
+
+void uvedit_face_select_set(const struct Scene *scene,
struct BMEditMesh *em,
struct BMFace *efa,
const bool select,
@@ -161,14 +295,14 @@ bool uvedit_face_select_set(const struct Scene *scene,
const int cd_loop_uv_offset)
{
if (select) {
- return uvedit_face_select_enable(scene, em, efa, do_history, cd_loop_uv_offset);
+ uvedit_face_select_enable(scene, em, efa, do_history, cd_loop_uv_offset);
}
else {
- return uvedit_face_select_disable(scene, em, efa, cd_loop_uv_offset);
+ uvedit_face_select_disable(scene, em, efa, cd_loop_uv_offset);
}
}
-bool uvedit_face_select_enable(const Scene *scene,
+void uvedit_face_select_enable(const Scene *scene,
BMEditMesh *em,
BMFace *efa,
const bool do_history,
@@ -191,14 +325,10 @@ bool uvedit_face_select_enable(const Scene *scene,
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag |= MLOOPUV_VERTSEL;
}
-
- return true;
}
-
- return false;
}
-bool uvedit_face_select_disable(const Scene *scene,
+void uvedit_face_select_disable(const Scene *scene,
BMEditMesh *em,
BMFace *efa,
const int cd_loop_uv_offset)
@@ -217,11 +347,7 @@ bool uvedit_face_select_disable(const Scene *scene,
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
luv->flag &= ~MLOOPUV_VERTSEL;
}
-
- return true;
}
-
- return false;
}
bool uvedit_edge_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_loop_uv_offset)
@@ -230,30 +356,46 @@ bool uvedit_edge_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_
if (ts->selectmode & SCE_SELECT_FACE) {
return BM_elem_flag_test(l->f, BM_ELEM_SELECT);
}
- else if (ts->selectmode == SCE_SELECT_EDGE) {
+ if (ts->selectmode == SCE_SELECT_EDGE) {
return BM_elem_flag_test(l->e, BM_ELEM_SELECT);
}
- else {
- return BM_elem_flag_test(l->v, BM_ELEM_SELECT) &&
- BM_elem_flag_test(l->next->v, BM_ELEM_SELECT);
- }
+ return BM_elem_flag_test(l->v, BM_ELEM_SELECT) &&
+ BM_elem_flag_test(l->next->v, BM_ELEM_SELECT);
}
- else {
- MLoopUV *luv1, *luv2;
- 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);
+ MLoopUV *luv1, *luv2;
- return (luv1->flag & MLOOPUV_VERTSEL) && (luv2->flag & MLOOPUV_VERTSEL);
- }
+ 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);
+
+ return (luv1->flag & MLOOPUV_VERTSEL) && (luv2->flag & MLOOPUV_VERTSEL);
}
bool uvedit_edge_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_offset)
{
return uvedit_edge_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset);
}
-void uvedit_edge_select_set(BMEditMesh *em,
- const Scene *scene,
+void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima,
+ const Scene *scene,
+ BMEditMesh *em,
+ BMLoop *l,
+ const bool select,
+ const bool do_history,
+ const uint cd_loop_uv_offset)
+{
+ const ToolSettings *ts = scene->toolsettings;
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ uvedit_edge_select_set(scene, em, l, select, do_history, cd_loop_uv_offset);
+ return;
+ }
+
+ uvedit_uv_select_set_with_sticky(sima, scene, em, l, select, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(
+ sima, scene, em, l->next, select, do_history, cd_loop_uv_offset);
+}
+
+void uvedit_edge_select_set(const Scene *scene,
+ BMEditMesh *em,
BMLoop *l,
const bool select,
const bool do_history,
@@ -261,15 +403,15 @@ void uvedit_edge_select_set(BMEditMesh *em,
{
if (select) {
- uvedit_edge_select_enable(em, scene, l, do_history, cd_loop_uv_offset);
+ uvedit_edge_select_enable(scene, em, l, do_history, cd_loop_uv_offset);
}
else {
- uvedit_edge_select_disable(em, scene, l, cd_loop_uv_offset);
+ uvedit_edge_select_disable(scene, em, l, cd_loop_uv_offset);
}
}
-void uvedit_edge_select_enable(BMEditMesh *em,
- const Scene *scene,
+void uvedit_edge_select_enable(const Scene *scene,
+ BMEditMesh *em,
BMLoop *l,
const bool do_history,
const int cd_loop_uv_offset)
@@ -304,8 +446,8 @@ void uvedit_edge_select_enable(BMEditMesh *em,
}
}
-void uvedit_edge_select_disable(BMEditMesh *em,
- const Scene *scene,
+void uvedit_edge_select_disable(const Scene *scene,
+ BMEditMesh *em,
BMLoop *l,
const int cd_loop_uv_offset)
@@ -341,37 +483,90 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_lo
if (ts->selectmode & SCE_SELECT_FACE) {
return BM_elem_flag_test_bool(l->f, BM_ELEM_SELECT);
}
- else {
- return BM_elem_flag_test_bool(l->v, BM_ELEM_SELECT);
- }
- }
- else {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- return (luv->flag & MLOOPUV_VERTSEL) != 0;
+ return BM_elem_flag_test_bool(l->v, BM_ELEM_SELECT);
}
+
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ return (luv->flag & MLOOPUV_VERTSEL) != 0;
}
bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_offset)
{
return uvedit_uv_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset);
}
-void uvedit_uv_select_set(BMEditMesh *em,
- const Scene *scene,
+void uvedit_uv_select_set_with_sticky(const struct SpaceImage *sima,
+ const Scene *scene,
+ BMEditMesh *em,
+ BMLoop *l,
+ const bool select,
+ const bool do_history,
+ const uint cd_loop_uv_offset)
+{
+ const ToolSettings *ts = scene->toolsettings;
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ uvedit_uv_select_set(scene, em, l, select, do_history, cd_loop_uv_offset);
+ return;
+ }
+
+ const int sticky = sima->sticky;
+ switch (sticky) {
+ case SI_STICKY_DISABLE: {
+ uvedit_uv_select_set(scene, em, l, select, do_history, cd_loop_uv_offset);
+ break;
+ }
+ default: {
+ /* #SI_STICKY_VERTEX or #SI_STICKY_LOC. */
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ BMEdge *e_first, *e_iter;
+ e_first = e_iter = l->e;
+ do {
+ if (e_iter->l) {
+ BMLoop *l_radial_iter = e_iter->l;
+ do {
+ if (l_radial_iter->v == l->v) {
+ if (uvedit_face_visible_test(scene, l_radial_iter->f)) {
+ bool do_select = false;
+ if (sticky == SI_STICKY_VERTEX) {
+ do_select = true;
+ }
+ else {
+ const MLoopUV *luv_other = BM_ELEM_CD_GET_VOID_P(l_radial_iter,
+ cd_loop_uv_offset);
+ if (equals_v2v2(luv_other->uv, luv->uv)) {
+ do_select = true;
+ }
+ }
+
+ if (do_select) {
+ uvedit_uv_select_set(
+ scene, em, l_radial_iter, select, do_history, cd_loop_uv_offset);
+ }
+ }
+ }
+ } while ((l_radial_iter = l_radial_iter->radial_next) != e_iter->l);
+ }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, l->v)) != e_first);
+ }
+ }
+}
+
+void uvedit_uv_select_set(const Scene *scene,
+ BMEditMesh *em,
BMLoop *l,
const bool select,
const bool do_history,
const int cd_loop_uv_offset)
{
if (select) {
- uvedit_uv_select_enable(em, scene, l, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_enable(scene, em, l, do_history, cd_loop_uv_offset);
}
else {
- uvedit_uv_select_disable(em, scene, l, cd_loop_uv_offset);
+ uvedit_uv_select_disable(scene, em, l, cd_loop_uv_offset);
}
}
-void uvedit_uv_select_enable(BMEditMesh *em,
- const Scene *scene,
+void uvedit_uv_select_enable(const Scene *scene,
+ BMEditMesh *em,
BMLoop *l,
const bool do_history,
const int cd_loop_uv_offset)
@@ -387,7 +582,7 @@ void uvedit_uv_select_enable(BMEditMesh *em,
}
if (do_history) {
- BM_select_history_remove(em->bm, (BMElem *)l->v);
+ BM_select_history_store(em->bm, (BMElem *)l->v);
}
}
else {
@@ -396,8 +591,8 @@ void uvedit_uv_select_enable(BMEditMesh *em,
}
}
-void uvedit_uv_select_disable(BMEditMesh *em,
- const Scene *scene,
+void uvedit_uv_select_disable(const Scene *scene,
+ BMEditMesh *em,
BMLoop *l,
const int cd_loop_uv_offset)
{
@@ -417,6 +612,31 @@ void uvedit_uv_select_disable(BMEditMesh *em,
}
}
+static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(Scene *scene,
+ BMLoop *l_src,
+ const int cd_loop_uv_offset)
+{
+ BMLoop *l_other = NULL;
+ BMLoop *l_iter = l_src->radial_next;
+ if (l_iter != l_src) {
+ do {
+ if (uvedit_face_visible_test(scene, l_iter->f) &&
+ BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset)) {
+ /* Check UV's are contiguous. */
+ if (l_other == NULL) {
+ l_other = l_iter;
+ }
+ else {
+ /* Only use when there is a single alternative. */
+ l_other = NULL;
+ break;
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l_src);
+ }
+ return l_other;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -667,9 +887,7 @@ bool ED_uvedit_nearest_uv(
*dist_sq = dist_best;
return true;
}
- else {
- return false;
- }
+ return false;
}
bool ED_uvedit_nearest_uv_multi(const Scene *scene,
@@ -692,7 +910,73 @@ bool ED_uvedit_nearest_uv_multi(const Scene *scene,
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Loop Select
+/** \name Find Nearest to Element
+ *
+ * These functions are quite specialized, useful when sync select is enabled
+ * and we want to pick an active UV vertex/edge from the active element which may
+ * have multiple UV's split out.
+ * \{ */
+
+BMLoop *uv_find_nearest_loop_from_vert(struct Scene *scene,
+ struct Object *obedit,
+ struct BMVert *v,
+ const float co[2])
+{
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const uint cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ BMIter liter;
+ BMLoop *l;
+ BMLoop *l_found = NULL;
+ float dist_best_sq = FLT_MAX;
+
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ if (!uvedit_face_visible_test(scene, l->f)) {
+ continue;
+ }
+
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ const float dist_test_sq = len_squared_v2v2(co, luv->uv);
+ if (dist_test_sq < dist_best_sq) {
+ dist_best_sq = dist_test_sq;
+ l_found = l;
+ }
+ }
+ return l_found;
+}
+
+BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene,
+ struct Object *obedit,
+ struct BMEdge *e,
+ const float co[2])
+{
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const uint cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ BMIter eiter;
+ BMLoop *l;
+ BMLoop *l_found = NULL;
+ float dist_best_sq = FLT_MAX;
+
+ BM_ITER_ELEM (l, &eiter, e, BM_LOOPS_OF_EDGE) {
+ if (!uvedit_face_visible_test(scene, l->f)) {
+ continue;
+ }
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv);
+ if (dist_test_sq < dist_best_sq) {
+ dist_best_sq = dist_test_sq;
+ l_found = l;
+ }
+ }
+ return l_found;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edge Loop Select
* \{ */
static void uv_select_edgeloop_vertex_loop_flag(UvMapVert *first)
@@ -792,8 +1076,7 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em,
return true;
}
-static int uv_select_edgeloop(
- Scene *scene, Object *obedit, UvNearestHit *hit, const float limit[2], const bool extend)
+static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
@@ -809,7 +1092,7 @@ static int uv_select_edgeloop(
/* setup */
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
- vmap = BM_uv_vert_map_create(em->bm, limit, false, false);
+ vmap = BM_uv_vert_map_create(em->bm, false, false);
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
@@ -882,7 +1165,7 @@ static int uv_select_edgeloop(
iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l);
if (iterv_curr->flag) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
}
}
}
@@ -896,19 +1179,97 @@ static int uv_select_edgeloop(
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Edge Ring Select
+ * \{ */
+
+static int uv_select_edgering(
+ const SpaceImage *sima, Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend)
+{
+ const ToolSettings *ts = scene->toolsettings;
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const bool use_face_select = (ts->uv_flag & UV_SYNC_SELECTION) ?
+ (ts->selectmode & SCE_SELECT_FACE) :
+ (ts->uv_selectmode & UV_SELECT_FACE);
+ bool select;
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ if (!extend) {
+ uv_select_all_perform(scene, obedit, SEL_DESELECT);
+ }
+
+ BM_mesh_elem_hflag_disable_all(em->bm, BM_EDGE, BM_ELEM_TAG, false);
+
+ if (extend) {
+ select = !(uvedit_uv_select_test(scene, hit->l, cd_loop_uv_offset));
+ }
+ else {
+ select = true;
+ }
+
+ BMLoop *l_pair[2] = {
+ hit->l,
+ uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, cd_loop_uv_offset),
+ };
+
+ for (int side = 0; side < 2; side++) {
+ BMLoop *l_step = l_pair[side];
+ /* Disable since we start from the same edge. */
+ BM_elem_flag_disable(hit->l->e, BM_ELEM_TAG);
+ while (l_step) {
+ if (!uvedit_face_visible_test(scene, l_step->f)) {
+ break;
+ }
+
+ if (use_face_select) {
+ uvedit_face_select_set_with_sticky(
+ sima, scene, em, l_step->f, select, false, cd_loop_uv_offset);
+ }
+ else {
+ uvedit_edge_select_set_with_sticky(
+ sima, scene, em, l_step, select, false, cd_loop_uv_offset);
+ }
+
+ BM_elem_flag_enable(l_step->e, BM_ELEM_TAG);
+ if (l_step->f->len == 4) {
+ BMLoop *l_step_opposite = l_step->next->next;
+ l_step = uvedit_loop_find_other_radial_loop_with_visible_face(
+ scene, l_step_opposite, cd_loop_uv_offset);
+ if (l_step == NULL) {
+ /* Ensure we touch the opposite edge if we cant walk over it. */
+ l_step = l_step_opposite;
+ }
+ }
+ else {
+ l_step = NULL;
+ }
+
+ if (l_step && BM_elem_flag_test(l_step->e, BM_ELEM_TAG)) {
+ break;
+ }
+ }
+ }
+
+ return (select) ? 1 : -1;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Select Linked
* \{ */
static void uv_select_linked_multi(Scene *scene,
Object **objects,
const uint objects_len,
- const float limit[2],
UvNearestHit *hit_final,
- bool extend,
+ const bool extend,
bool deselect,
- bool toggle,
- bool select_faces)
+ const bool toggle,
+ const bool select_faces)
{
+ const bool uv_sync_select = (scene->toolsettings->uv_flag & UV_SYNC_SELECTION);
+
/* loop over objects, or just use hit_final->ob */
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
if (hit_final && ob_index != 0) {
@@ -919,7 +1280,6 @@ static void uv_select_linked_multi(Scene *scene,
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
UvVertMap *vmap;
UvMapVert *vlist, *iterv, *startv;
int i, stacksize = 0, *stack;
@@ -937,7 +1297,7 @@ static void uv_select_linked_multi(Scene *scene,
*
* Better solve this by having a delimit option for select-linked operator,
* keeping island-select working as is. */
- vmap = BM_uv_vert_map_create(em->bm, limit, !select_faces, false);
+ vmap = BM_uv_vert_map_create(em->bm, !uv_sync_select, false);
if (vmap == NULL) {
continue;
@@ -959,14 +1319,42 @@ static void uv_select_linked_multi(Scene *scene,
}
else {
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_VERTSEL) {
- stack[stacksize] = a;
- stacksize++;
- flag[a] = 1;
-
- break;
+ if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ bool add_to_stack = true;
+ if (uv_sync_select && !select_faces) {
+ /* Special case, vertex/edge & sync select being enabled.
+ *
+ * Without this, a second linked select will 'grow' each time as each new
+ * selection reaches the boundaries of islands that share vertices but not UV's.
+ *
+ * Rules applied here:
+ * - This loops face isn't selected.
+ * - The only other fully selected face is connected or,
+ * - There are no connected fully selected faces UV-connected to this loop.
+ */
+ if (uvedit_face_select_test(scene, l->f, cd_loop_uv_offset)) {
+ /* pass */
+ }
+ else {
+ BMIter liter_other;
+ BMLoop *l_other;
+ BM_ITER_ELEM (l_other, &liter_other, l->v, BM_LOOPS_OF_VERT) {
+ if ((l != l_other) &&
+ !BM_loop_uv_share_vert_check(l, l_other, cd_loop_uv_offset) &&
+ uvedit_face_select_test(scene, l_other->f, cd_loop_uv_offset)) {
+ add_to_stack = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (add_to_stack) {
+ stack[stacksize] = a;
+ stacksize++;
+ flag[a] = 1;
+ break;
+ }
}
}
}
@@ -1011,7 +1399,7 @@ static void uv_select_linked_multi(Scene *scene,
if ((startv != iterv) && (iterv->separate)) {
break;
}
- else if (!flag[iterv->poly_index]) {
+ if (!flag[iterv->poly_index]) {
flag[iterv->poly_index] = 1;
stack[stacksize] = iterv->poly_index;
stacksize++;
@@ -1035,10 +1423,9 @@ static void uv_select_linked_multi(Scene *scene,
}
else {
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_VERTSEL) {
+ if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
found_selected = true;
+ break;
}
}
@@ -1055,10 +1442,7 @@ static void uv_select_linked_multi(Scene *scene,
BM_face_select_set(em->bm, efa, value); \
} \
else { \
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { \
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); \
- luv->flag = (value) ? (luv->flag | MLOOPUV_VERTSEL) : (luv->flag & ~MLOOPUV_VERTSEL); \
- } \
+ uvedit_face_select_set(scene, em, efa, value, false, cd_loop_uv_offset); \
} \
(void)0
@@ -1083,6 +1467,17 @@ static void uv_select_linked_multi(Scene *scene,
MEM_freeN(stack);
MEM_freeN(flag);
BM_uv_vert_map_free(vmap);
+
+ if (uv_sync_select) {
+ if (deselect) {
+ EDBM_deselect_flush(em);
+ }
+ else {
+ if (!select_faces) {
+ EDBM_selectmode_flush(em);
+ }
+ }
+ }
}
}
@@ -1289,17 +1684,16 @@ bool uvedit_select_is_any_selected(Scene *scene, Object *obedit)
if (ts->uv_flag & UV_SYNC_SELECTION) {
return (em->bm->totvertsel || em->bm->totedgesel || em->bm->totfacesel);
}
- else {
- 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) {
- if (!uvedit_face_visible_test(scene, efa)) {
- continue;
- }
- 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_VERTSEL) {
- return true;
- }
+
+ 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) {
+ if (!uvedit_face_visible_test(scene, efa)) {
+ continue;
+ }
+ 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_VERTSEL) {
+ return true;
}
}
}
@@ -1438,76 +1832,27 @@ void UV_OT_select_all(wmOperatorType *ot)
/** \name Mouse Select Operator
* \{ */
-static bool uv_sticky_select(
- float *limit, int hitv[], int v, float *hituv[], float *uv, int sticky, int hitlen)
-{
- int i;
-
- /* this function test if some vertex needs to selected
- * in addition to the existing ones due to sticky select */
- if (sticky == SI_STICKY_DISABLE) {
- return false;
- }
-
- for (i = 0; i < hitlen; i++) {
- if (hitv[i] == v) {
- if (sticky == SI_STICKY_LOC) {
- if (fabsf(hituv[i][0] - uv[0]) < limit[0] && fabsf(hituv[i][1] - uv[1]) < limit[1]) {
- return true;
- }
- }
- else if (sticky == SI_STICKY_VERTEX) {
- return true;
- }
- }
- }
-
- return false;
-}
-
static int uv_mouse_select_multi(bContext *C,
Object **objects,
uint objects_len,
const float co[2],
const bool extend,
- const bool deselect_all,
- const bool loop)
+ const bool deselect_all)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
- BMFace *efa;
- BMLoop *l;
- BMIter iter, liter;
- MLoopUV *luv;
UvNearestHit hit = UV_NEAREST_HIT_INIT;
- int i, selectmode, sticky, sync, *hitv = NULL;
- bool select = true;
+ int selectmode, sticky;
bool found_item = false;
/* 0 == don't flush, 1 == sel, -1 == desel; only use when selection sync is enabled */
int flush = 0;
- int hitlen = 0;
- float limit[2], **hituv = NULL;
-
- /* notice 'limit' is the same no matter the zoom level, since this is like
- * remove doubles and could annoying if it joined points when zoomed out.
- * 'penalty' is in screen pixel space otherwise zooming in on a uv-vert and
- * shift-selecting can consider an adjacent point close enough to add to
- * the selection rather than de-selecting the closest. */
- float penalty_dist;
- {
- float penalty[2];
- uvedit_pixel_to_float(sima, 0.05f, limit);
- uvedit_pixel_to_float(sima, 5.0f / (sima ? sima->zoom : 1.0f), penalty);
- penalty_dist = len_v2(penalty);
- }
+ const float penalty_dist = uv_select_penalty_default(sima);
/* retrieve operation mode */
if (ts->uv_flag & UV_SYNC_SELECTION) {
- sync = 1;
-
if (ts->selectmode & SCE_SELECT_FACE) {
selectmode = UV_SELECT_FACE;
}
@@ -1521,31 +1866,21 @@ static int uv_mouse_select_multi(bContext *C,
sticky = SI_STICKY_DISABLE;
}
else {
- sync = 0;
selectmode = ts->uv_selectmode;
- sticky = (sima) ? sima->sticky : 1;
+ sticky = (sima) ? sima->sticky : SI_STICKY_DISABLE;
}
/* find nearest element */
- if (loop) {
- /* find edge */
- found_item = uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit);
- }
- else if (selectmode == UV_SELECT_VERTEX) {
+ if (selectmode == UV_SELECT_VERTEX) {
/* find vertex */
found_item = uv_find_nearest_vert_multi(scene, objects, objects_len, co, penalty_dist, &hit);
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
if (found_item) {
- /* mark 1 vertex as being hit */
- hitv = BLI_array_alloca(hitv, hit.efa->len);
- hituv = BLI_array_alloca(hituv, hit.efa->len);
- copy_vn_i(hitv, hit.efa->len, 0xFFFFFFFF);
-
- hitv[hit.lindex] = BM_elem_index_get(hit.l->v);
- hituv[hit.lindex] = hit.luv->uv;
-
- hitlen = hit.efa->len;
+ if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) {
+ BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm;
+ ED_uvedit_active_vert_loop_set(bm, hit.l);
+ }
}
}
else if (selectmode == UV_SELECT_EDGE) {
@@ -1554,17 +1889,10 @@ static int uv_mouse_select_multi(bContext *C,
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
if (found_item) {
- /* mark 2 edge vertices as being hit */
- hitv = BLI_array_alloca(hitv, hit.efa->len);
- hituv = BLI_array_alloca(hituv, hit.efa->len);
- copy_vn_i(hitv, hit.efa->len, 0xFFFFFFFF);
-
- hitv[hit.lindex] = BM_elem_index_get(hit.l->v);
- hitv[(hit.lindex + 1) % hit.efa->len] = BM_elem_index_get(hit.l->next->v);
- hituv[hit.lindex] = hit.luv->uv;
- hituv[(hit.lindex + 1) % hit.efa->len] = hit.luv_next->uv;
-
- hitlen = hit.efa->len;
+ if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) {
+ BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm;
+ ED_uvedit_active_edge_loop_set(bm, hit.l);
+ }
}
}
else if (selectmode == UV_SELECT_FACE) {
@@ -1573,23 +1901,8 @@ static int uv_mouse_select_multi(bContext *C,
found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist);
if (found_item) {
- BMEditMesh *em = BKE_editmesh_from_object(hit.ob);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
-
- /* make active */
- BM_mesh_active_face_set(em->bm, hit.efa);
-
- /* mark all face vertices as being hit */
-
- hitv = BLI_array_alloca(hitv, hit.efa->len);
- hituv = BLI_array_alloca(hituv, hit.efa->len);
- BM_ITER_ELEM_INDEX (l, &liter, hit.efa, BM_LOOPS_OF_FACE, i) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- hituv[i] = luv->uv;
- hitv[i] = BM_elem_index_get(l->v);
- }
-
- hitlen = hit.efa->len;
+ BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm;
+ BM_mesh_active_face_set(bm, hit.efa);
}
}
else if (selectmode == UV_SELECT_ISLAND) {
@@ -1616,44 +1929,39 @@ static int uv_mouse_select_multi(bContext *C,
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
/* do selection */
- if (loop) {
- if (!extend) {
- /* TODO(MULTI_EDIT): We only need to de-select non-active */
- uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
- }
- flush = uv_select_edgeloop(scene, obedit, &hit, limit, extend);
- }
- else if (selectmode == UV_SELECT_ISLAND) {
+ if (selectmode == UV_SELECT_ISLAND) {
if (!extend) {
/* TODO(MULTI_EDIT): We only need to de-select non-active */
uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
}
/* Current behavior of 'extend'
* is actually toggling, so pass extend flag as 'toggle' here */
- uv_select_linked_multi(scene, objects, objects_len, limit, &hit, false, false, extend, false);
+ uv_select_linked_multi(scene, objects, objects_len, &hit, false, false, extend, false);
}
else if (extend) {
+ bool select = true;
if (selectmode == UV_SELECT_VERTEX) {
/* (de)select uv vertex */
select = !uvedit_uv_select_test(scene, hit.l, cd_loop_uv_offset);
- uvedit_uv_select_set(em, scene, hit.l, select, true, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset);
flush = 1;
}
else if (selectmode == UV_SELECT_EDGE) {
/* (de)select edge */
select = !(uvedit_edge_select_test(scene, hit.l, cd_loop_uv_offset));
- uvedit_edge_select_set(em, scene, hit.l, select, true, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset);
flush = 1;
}
else if (selectmode == UV_SELECT_FACE) {
/* (de)select face */
select = !(uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset));
- uvedit_face_select_set(scene, em, hit.efa, select, true, cd_loop_uv_offset);
+ uvedit_face_select_set_with_sticky(
+ sima, scene, em, hit.efa, select, true, cd_loop_uv_offset);
flush = -1;
}
/* de-selecting an edge may deselect a face too - validate */
- if (sync) {
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
if (select == false) {
BM_select_history_validate(em->bm);
}
@@ -1661,98 +1969,36 @@ static int uv_mouse_select_multi(bContext *C,
/* (de)select sticky uv nodes */
if (sticky != SI_STICKY_DISABLE) {
-
- BM_mesh_elem_index_ensure(em->bm, BM_VERT);
-
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, efa)) {
- continue;
- }
-
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (uv_sticky_select(
- limit, hitv, BM_elem_index_get(l->v), hituv, luv->uv, sticky, hitlen)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
- }
- }
- }
-
flush = select ? 1 : -1;
}
}
else {
+ const bool select = true;
/* deselect all */
uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
if (selectmode == UV_SELECT_VERTEX) {
/* select vertex */
- uvedit_uv_select_enable(em, scene, hit.l, true, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset);
flush = 1;
}
else if (selectmode == UV_SELECT_EDGE) {
/* select edge */
- uvedit_edge_select_enable(em, scene, hit.l, true, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset);
flush = 1;
}
else if (selectmode == UV_SELECT_FACE) {
/* select face */
- uvedit_face_select_enable(scene, em, hit.efa, true, cd_loop_uv_offset);
- }
-
- /* select sticky uvs */
- if (sticky != SI_STICKY_DISABLE) {
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, 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);
-
- if (uv_sticky_select(
- limit, hitv, BM_elem_index_get(l->v), hituv, luv->uv, sticky, hitlen)) {
- uvedit_uv_select_enable(em, scene, l, false, cd_loop_uv_offset);
- }
-
- flush = 1;
- }
- }
+ uvedit_face_select_set_with_sticky(
+ sima, scene, em, hit.efa, select, true, cd_loop_uv_offset);
+ flush = 1;
}
}
- if (sync) {
- /* flush for mesh selection */
-
- /* before bmesh */
-#if 0
- if (ts->selectmode != SCE_SELECT_FACE) {
- if (flush == 1) {
- EDBM_select_flush(em);
- }
- else if (flush == -1) {
- EDBM_deselect_flush(em);
- }
- }
-#else
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
if (flush != 0) {
- if (loop) {
- /* push vertex -> edge selection */
- if (select) {
- EDBM_select_flush(em);
- }
- else {
- EDBM_deselect_flush(em);
- }
- }
- else {
- EDBM_selectmode_flush(em);
- }
+ EDBM_selectmode_flush(em);
}
-#endif
}
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
@@ -1762,14 +2008,16 @@ static int uv_mouse_select_multi(bContext *C,
return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
}
-static int uv_mouse_select(
- bContext *C, const float co[2], const bool extend, const bool deselect_all, const bool loop)
+static int uv_mouse_select(bContext *C,
+ const float co[2],
+ const bool extend,
+ const bool deselect_all)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, ((View3D *)NULL), &objects_len);
- int ret = uv_mouse_select_multi(C, objects, objects_len, co, extend, deselect_all, loop);
+ int ret = uv_mouse_select_multi(C, objects, objects_len, co, extend, deselect_all);
MEM_freeN(objects);
return ret;
}
@@ -1781,9 +2029,8 @@ static int uv_select_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "location", co);
const bool extend = RNA_boolean_get(op->ptr, "extend");
const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
- const bool loop = false;
- return uv_mouse_select(C, co, extend, deselect_all, loop);
+ return uv_mouse_select(C, co, extend, deselect_all);
}
static int uv_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -1840,7 +2087,89 @@ void UV_OT_select(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Loop Select Operator
+/** \name Shared Edge Loop/Ring Select Operator Functions
+ * \{ */
+
+enum eUVLoopGenericType {
+ UV_LOOP_SELECT = 1,
+ UV_RING_SELECT = 2,
+};
+
+static int uv_mouse_select_loop_generic_multi(bContext *C,
+ Object **objects,
+ uint objects_len,
+ const float co[2],
+ const bool extend,
+ enum eUVLoopGenericType loop_type)
+{
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ const ToolSettings *ts = scene->toolsettings;
+ UvNearestHit hit = UV_NEAREST_HIT_INIT;
+ bool found_item = false;
+ /* 0 == don't flush, 1 == sel, -1 == desel; only use when selection sync is enabled */
+ int flush = 0;
+
+ /* Find edge. */
+ found_item = uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit);
+ if (!found_item) {
+ return OPERATOR_CANCELLED;
+ }
+
+ Object *obedit = hit.ob;
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ /* Do selection. */
+ if (!extend) {
+ /* TODO(MULTI_EDIT): We only need to de-select non-active */
+ uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
+ }
+
+ if (loop_type == UV_LOOP_SELECT) {
+ flush = uv_select_edgeloop(scene, obedit, &hit, extend);
+ }
+ else if (loop_type == UV_RING_SELECT) {
+ flush = uv_select_edgering(sima, scene, obedit, &hit, extend);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (flush == 1) {
+ EDBM_select_flush(em);
+ }
+ else if (flush == -1) {
+ EDBM_deselect_flush(em);
+ }
+ }
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obiter = objects[ob_index];
+ uv_select_tag_update_for_object(depsgraph, ts, obiter);
+ }
+
+ return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
+}
+static int uv_mouse_select_loop_generic(bContext *C,
+ const float co[2],
+ const bool extend,
+ enum eUVLoopGenericType loop_type)
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ view_layer, ((View3D *)NULL), &objects_len);
+ int ret = uv_mouse_select_loop_generic_multi(C, objects, objects_len, co, extend, loop_type);
+ MEM_freeN(objects);
+ return ret;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edge Loop Select Operator
* \{ */
static int uv_select_loop_exec(bContext *C, wmOperator *op)
@@ -1849,10 +2178,8 @@ static int uv_select_loop_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "location", co);
const bool extend = RNA_boolean_get(op->ptr, "extend");
- const bool deselect_all = false;
- const bool loop = true;
- return uv_mouse_select(C, co, extend, deselect_all, loop);
+ return uv_mouse_select_loop_generic(C, co, extend, UV_LOOP_SELECT);
}
static int uv_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -1901,34 +2228,81 @@ void UV_OT_select_loop(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Edge Ring Select Operator
+ * \{ */
+
+static int uv_select_edge_ring_exec(bContext *C, wmOperator *op)
+{
+ float co[2];
+ RNA_float_get_array(op->ptr, "location", co);
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
+ return uv_mouse_select_loop_generic(C, co, extend, UV_RING_SELECT);
+}
+
+static int uv_select_edge_ring_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ const ARegion *region = CTX_wm_region(C);
+ float co[2];
+
+ UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
+ RNA_float_set_array(op->ptr, "location", co);
+
+ return uv_select_edge_ring_exec(C, op);
+}
+
+void UV_OT_select_edge_ring(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Edge Ring Select";
+ ot->description = "Select an edge ring of connected UV vertices";
+ ot->idname = "UV_OT_select_edge_ring";
+ ot->flag = OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = uv_select_edge_ring_exec;
+ ot->invoke = uv_select_edge_ring_invoke;
+ ot->poll = ED_operator_uvedit; /* requires space image */
+
+ /* properties */
+ RNA_def_boolean(ot->srna,
+ "extend",
+ 0,
+ "Extend",
+ "Extend selection rather than clearing the existing selection");
+ RNA_def_float_vector(
+ ot->srna,
+ "location",
+ 2,
+ NULL,
+ -FLT_MAX,
+ FLT_MAX,
+ "Location",
+ "Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds",
+ -100.0f,
+ 100.0f);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Select Linked Operator
* \{ */
static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent *event, bool pick)
{
- SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
const ToolSettings *ts = scene->toolsettings;
ViewLayer *view_layer = CTX_data_view_layer(C);
- float limit[2];
bool extend = true;
bool deselect = false;
bool select_faces = (ts->uv_flag & UV_SYNC_SELECTION) && (ts->selectmode & SCE_SELECT_FACE);
UvNearestHit hit = UV_NEAREST_HIT_INIT;
- if ((ts->uv_flag & UV_SYNC_SELECTION) && !(ts->selectmode & SCE_SELECT_FACE)) {
- BKE_report(op->reports,
- RPT_ERROR,
- "Select linked only works in face select mode when sync selection is enabled");
- return OPERATOR_CANCELLED;
- }
-
if (pick) {
extend = RNA_boolean_get(op->ptr, "extend");
deselect = RNA_boolean_get(op->ptr, "deselect");
}
- uv_select_island_limit_default(sima, limit);
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
@@ -1955,19 +2329,12 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent
}
}
- if (!extend) {
+ if (!extend && !deselect) {
uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT);
}
- uv_select_linked_multi(scene,
- objects,
- objects_len,
- limit,
- pick ? &hit : NULL,
- extend,
- deselect,
- false,
- select_faces);
+ uv_select_linked_multi(
+ scene, objects, objects_len, pick ? &hit : NULL, extend, deselect, false, select_faces);
/* weak!, but works */
Object **objects_free = objects;
@@ -2076,6 +2443,7 @@ void UV_OT_select_linked_pick(wmOperatorType *ot)
*/
static int uv_select_split_exec(bContext *C, wmOperator *op)
{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const ToolSettings *ts = scene->toolsettings;
@@ -2142,6 +2510,7 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
if (changed) {
changed_multi = true;
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL);
+ uv_select_tag_update_for_object(depsgraph, ts, obedit);
}
}
MEM_freeN(objects);
@@ -2162,25 +2531,6 @@ void UV_OT_select_split(wmOperatorType *ot)
ot->poll = ED_operator_uvedit; /* requires space image */
}
-static void uv_select_sync_flush(const ToolSettings *ts, BMEditMesh *em, const short select)
-{
- /* bmesh API handles flushing but not on de-select */
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- if (ts->selectmode != SCE_SELECT_FACE) {
- if (select == false) {
- EDBM_deselect_flush(em);
- }
- else {
- EDBM_select_flush(em);
- }
- }
-
- if (select == false) {
- BM_select_history_validate(em->bm);
- }
- }
-}
-
static void uv_select_tag_update_for_object(Depsgraph *depsgraph,
const ToolSettings *ts,
Object *obedit)
@@ -2219,7 +2569,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(Scene *scene,
UvMapVert *start_vlist = NULL, *vlist_iter;
BMFace *efa_vlist;
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
vlist_iter = BM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v));
@@ -2250,7 +2600,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(Scene *scene,
l_other = BM_iter_at_index(
em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->loop_of_poly_index);
- uvedit_uv_select_set(em, scene, l_other, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l_other, select, false, cd_loop_uv_offset);
}
vlist_iter = vlist_iter->next;
}
@@ -2303,20 +2653,17 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
}
}
}
}
else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_LOC) {
struct UvVertMap *vmap;
- float limit[2];
uint efa_index;
- uv_select_island_limit_default(sima, limit);
-
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
- vmap = BM_uv_vert_map_create(em->bm, limit, false, false);
+ vmap = BM_uv_vert_map_create(em->bm, false, false);
if (vmap == NULL) {
return;
}
@@ -2390,20 +2737,17 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
}
}
}
}
else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_LOC) {
struct UvVertMap *vmap;
- float limit[2];
uint efa_index;
- uv_select_island_limit_default(sima, limit);
-
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
- vmap = BM_uv_vert_map_create(em->bm, limit, false, false);
+ vmap = BM_uv_vert_map_create(em->bm, false, false);
if (vmap == NULL) {
return;
}
@@ -2424,7 +2768,7 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima,
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l, BM_ELEM_TAG)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
}
}
}
@@ -2451,7 +2795,6 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
rctf rectf;
bool pinned;
- float limit[2];
const bool use_face_center = ((ts->uv_flag & UV_SYNC_SELECTION) ?
(ts->selectmode == SCE_SELECT_FACE) :
(ts->uv_selectmode == UV_SELECT_FACE));
@@ -2469,8 +2812,6 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
pinned = RNA_boolean_get(op->ptr, "pinned");
- uv_select_island_limit_default(sima, limit);
-
bool changed_multi = false;
uint objects_len = 0;
@@ -2532,8 +2873,8 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
if ((select != luv_select) || (select != luv_select_prev)) {
if (BLI_rctf_isect_pt_v(&rectf, luv->uv) &&
BLI_rctf_isect_pt_v(&rectf, luv_prev->uv)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
- uvedit_uv_select_set(em, scene, l_prev, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l_prev, select, false, cd_loop_uv_offset);
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
BM_elem_flag_enable(l_prev->v, BM_ELEM_TAG);
}
@@ -2564,14 +2905,14 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
if (!pinned || (ts->uv_flag & UV_SYNC_SELECTION)) {
/* UV_SYNC_SELECTION - can't do pinned selection */
if (BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
has_selected = true;
}
}
else if (pinned) {
if ((luv->flag & MLOOPUV_PINNED) && BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
}
}
@@ -2582,8 +2923,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
.ob = obedit,
.efa = efa,
};
- uv_select_linked_multi(
- scene, objects, objects_len, limit, &hit, true, !select, false, false);
+ uv_select_linked_multi(scene, objects, objects_len, &hit, true, !select, false, false);
}
}
@@ -2595,7 +2935,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
if (changed || use_pre_deselect) {
changed_multi = true;
- uv_select_sync_flush(ts, em, select);
+ ED_uvedit_select_sync_flush(ts, em, select);
uv_select_tag_update_for_object(depsgraph, ts, obedit);
}
}
@@ -2678,7 +3018,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
int x, y, radius, width, height;
float zoomx, zoomy;
- float limit[2], offset[2], ellipse[2];
+ float offset[2], ellipse[2];
const bool use_face_center = ((ts->uv_flag & UV_SYNC_SELECTION) ?
(ts->selectmode == SCE_SELECT_FACE) :
@@ -2702,8 +3042,6 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
UI_view2d_region_to_view(&region->v2d, x, y, &offset[0], &offset[1]);
- uv_select_island_limit_default(sima, limit);
-
bool changed_multi = false;
uint objects_len = 0;
@@ -2765,8 +3103,8 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
if ((select != luv_select) || (select != luv_select_prev)) {
if (uv_circle_select_is_edge_inside(luv->uv, luv_prev->uv, offset, ellipse)) {
changed = true;
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
- uvedit_uv_select_set(em, scene, l_prev, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l_prev, select, false, cd_loop_uv_offset);
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
BM_elem_flag_enable(l_prev->v, BM_ELEM_TAG);
}
@@ -2794,7 +3132,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (uv_circle_select_is_point_inside(luv->uv, offset, ellipse)) {
changed = true;
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
has_selected = true;
}
@@ -2805,8 +3143,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
.ob = obedit,
.efa = efa,
};
- uv_select_linked_multi(
- scene, objects, objects_len, limit, &hit, true, !select, false, false);
+ uv_select_linked_multi(scene, objects, objects_len, &hit, true, !select, false, false);
}
}
@@ -2818,7 +3155,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
if (changed || use_pre_deselect) {
changed_multi = true;
- uv_select_sync_flush(ts, em, select);
+ ED_uvedit_select_sync_flush(ts, em, select);
uv_select_tag_update_for_object(depsgraph, ts, obedit);
}
}
@@ -2897,12 +3234,9 @@ static bool do_lasso_select_mesh_uv(bContext *C,
BMFace *efa;
BMLoop *l;
- float limit[2];
bool changed_multi = false;
rcti rect;
- uv_select_island_limit_default(sima, limit);
-
BLI_lasso_boundbox(&rect, mcoords, mcoords_len);
uint objects_len = 0;
@@ -2962,8 +3296,8 @@ static bool do_lasso_select_mesh_uv(bContext *C,
region, &rect, mcoords, mcoords_len, luv->uv) &&
do_lasso_select_mesh_uv_is_point_inside(
region, &rect, mcoords, mcoords_len, luv_prev->uv)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
- uvedit_uv_select_set(em, scene, l_prev, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l_prev, select, false, cd_loop_uv_offset);
changed = true;
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
BM_elem_flag_enable(l_prev->v, BM_ELEM_TAG);
@@ -2992,7 +3326,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (do_lasso_select_mesh_uv_is_point_inside(
region, &rect, mcoords, mcoords_len, luv->uv)) {
- uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
changed = true;
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
has_selected = true;
@@ -3004,8 +3338,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
.ob = obedit,
.efa = efa,
};
- uv_select_linked_multi(
- scene, objects, objects_len, limit, &hit, true, !select, false, false);
+ uv_select_linked_multi(scene, objects, objects_len, &hit, true, !select, false, false);
}
}
@@ -3017,7 +3350,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
if (changed || use_pre_deselect) {
changed_multi = true;
- uv_select_sync_flush(ts, em, select);
+ ED_uvedit_select_sync_flush(ts, em, select);
uv_select_tag_update_for_object(depsgraph, ts, obedit);
}
}
@@ -3099,7 +3432,7 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *UNUSED(op))
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);
+ uvedit_uv_select_enable(scene, em, l, false, cd_loop_uv_offset);
changed = true;
}
}
@@ -3369,3 +3702,154 @@ void UV_OT_select_overlap(wmOperatorType *ot)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Selected Elements as Arrays (Vertex, Edge & Faces)
+ *
+ * These functions return single elements per connected vertex/edge.
+ * So an edge that has two connected edge loops only assigns one loop in the array.
+ * \{ */
+
+BMFace **ED_uvedit_selected_faces(Scene *scene, BMesh *bm, int len_max, int *r_faces_len)
+{
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ CLAMP_MAX(len_max, bm->totface);
+ int faces_len = 0;
+ BMFace **faces = MEM_mallocN(sizeof(*faces) * len_max, __func__);
+
+ BMIter iter;
+ BMFace *f;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (uvedit_face_visible_test(scene, f)) {
+ if (uvedit_face_select_test(scene, f, cd_loop_uv_offset)) {
+ faces[faces_len++] = f;
+ if (faces_len == len_max) {
+ goto finally;
+ }
+ }
+ }
+ }
+
+finally:
+ *r_faces_len = faces_len;
+ if (faces_len != len_max) {
+ faces = MEM_reallocN(faces, sizeof(*faces) * faces_len);
+ }
+ return faces;
+}
+
+BMLoop **ED_uvedit_selected_edges(Scene *scene, BMesh *bm, int len_max, int *r_edges_len)
+{
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ CLAMP_MAX(len_max, bm->totloop);
+ int edges_len = 0;
+ BMLoop **edges = MEM_mallocN(sizeof(*edges) * len_max, __func__);
+
+ BMIter iter;
+ BMFace *f;
+
+ /* Clear tag. */
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ BMIter liter;
+ BMLoop *l_iter;
+ BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) {
+ BM_elem_flag_disable(l_iter, BM_ELEM_TAG);
+ }
+ }
+
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (uvedit_face_visible_test(scene, f)) {
+ BMIter liter;
+ BMLoop *l_iter;
+ BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) {
+ if (!BM_elem_flag_test(l_iter, BM_ELEM_TAG)) {
+ const MLoopUV *luv_curr = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
+ const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l_iter->next, cd_loop_uv_offset);
+ if ((luv_curr->flag & MLOOPUV_VERTSEL) && (luv_next->flag & MLOOPUV_VERTSEL)) {
+ BM_elem_flag_enable(l_iter, BM_ELEM_TAG);
+
+ edges[edges_len++] = l_iter;
+ if (edges_len == len_max) {
+ goto finally;
+ }
+
+ /* Tag other connected loops so we don't consider them separate edges. */
+ if (l_iter != l_iter->radial_next) {
+ BMLoop *l_radial_iter = l_iter->radial_next;
+ do {
+ if (BM_loop_uv_share_edge_check(l_iter, l_radial_iter, cd_loop_uv_offset)) {
+ BM_elem_flag_enable(l_radial_iter, BM_ELEM_TAG);
+ }
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
+ }
+ }
+ }
+ }
+ }
+ }
+
+finally:
+ *r_edges_len = edges_len;
+ if (edges_len != len_max) {
+ edges = MEM_reallocN(edges, sizeof(*edges) * edges_len);
+ }
+ return edges;
+}
+
+BMLoop **ED_uvedit_selected_verts(Scene *scene, BMesh *bm, int len_max, int *r_verts_len)
+{
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ CLAMP_MAX(len_max, bm->totloop);
+ int verts_len = 0;
+ BMLoop **verts = MEM_mallocN(sizeof(*verts) * len_max, __func__);
+
+ BMIter iter;
+ BMFace *f;
+
+ /* Clear tag. */
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ BMIter liter;
+ BMLoop *l_iter;
+ BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) {
+ BM_elem_flag_disable(l_iter, BM_ELEM_TAG);
+ }
+ }
+
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (uvedit_face_visible_test(scene, f)) {
+ BMIter liter;
+ BMLoop *l_iter;
+ BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) {
+ if (!BM_elem_flag_test(l_iter, BM_ELEM_TAG)) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
+ if ((luv->flag & MLOOPUV_VERTSEL)) {
+ BM_elem_flag_enable(l_iter->v, BM_ELEM_TAG);
+
+ verts[verts_len++] = l_iter;
+ if (verts_len == len_max) {
+ goto finally;
+ }
+
+ /* Tag other connected loops so we don't consider them separate vertices. */
+ BMIter liter_disk;
+ BMLoop *l_disk_iter;
+ BM_ITER_ELEM (l_disk_iter, &liter_disk, l_iter->v, BM_LOOPS_OF_VERT) {
+ if (BM_loop_uv_share_vert_check(l_iter, l_disk_iter, cd_loop_uv_offset)) {
+ BM_elem_flag_enable(l_disk_iter, BM_ELEM_TAG);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+finally:
+ *r_verts_len = verts_len;
+ if (verts_len != len_max) {
+ verts = MEM_reallocN(verts, sizeof(*verts) * verts_len);
+ }
+ return verts;
+}
+
+/** \} */
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 594847b7249..f649ee528d4 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -320,9 +320,7 @@ static int getNumOfIslandUvs(UvElementMap *elementMap, int island)
if (island == elementMap->totalIslands - 1) {
return elementMap->totalUVs - elementMap->islandIndices[island];
}
- else {
- return elementMap->islandIndices[island + 1] - elementMap->islandIndices[island];
- }
+ return elementMap->islandIndices[island + 1] - elementMap->islandIndices[island];
}
static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2], float aspect)
@@ -367,13 +365,9 @@ static bool stitch_check_uvs_stitchable(UvElement *element,
fabsf(luv->uv[1] - luv_iter->uv[1]) < limit) {
return 1;
}
- else {
- return 0;
- }
- }
- else {
- return 1;
+ return 0;
}
+ return 1;
}
static bool stitch_check_edges_stitchable(UvEdge *edge,
@@ -411,13 +405,9 @@ static bool stitch_check_edges_stitchable(UvEdge *edge,
fabsf(luv_orig2->uv[1] - luv_iter2->uv[1]) < limit) {
return 1;
}
- else {
- return 0;
- }
- }
- else {
- return 1;
+ return 0;
}
+ return 1;
}
static bool stitch_check_uvs_state_stitchable(UvElement *element,
@@ -544,7 +534,7 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge,
StitchStateContainer *ssc,
StitchState *state,
UVVertAverage *uv_average,
- uint *uvfinal_map,
+ const uint *uvfinal_map,
IslandStitchData *island_stitch_data)
{
BMesh *bm = state->em->bm;
@@ -991,7 +981,7 @@ static void stitch_propagate_uv_final_position(Scene *scene,
if (final) {
copy_v2_v2(luv->uv, final_position[index].uv);
- uvedit_uv_select_enable(state->em, scene, l, false, cd_loop_uv_offset);
+ uvedit_uv_select_enable(scene, state->em, l, false, cd_loop_uv_offset);
}
else {
int face_preview_pos =
@@ -1945,7 +1935,7 @@ static StitchState *stitch_init(bContext *C,
return NULL;
}
- ED_uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy);
+ ED_uvedit_get_aspect(obedit, &aspx, &aspy);
state->aspect = aspx / aspy;
/* Count 'unique' uvs */
@@ -2535,10 +2525,8 @@ static int stitch_exec(bContext *C, wmOperator *op)
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
- else {
- stitch_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
+ stitch_cancel(C, op);
+ return OPERATOR_CANCELLED;
}
static StitchState *stitch_select(bContext *C,
@@ -2619,14 +2607,12 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
- else {
- stitch_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
- }
- else {
- return OPERATOR_PASS_THROUGH;
+
+ stitch_cancel(C, op);
+ return OPERATOR_CANCELLED;
}
+ return OPERATOR_PASS_THROUGH;
+
/* Increase limit */
case EVT_PADPLUSKEY:
case WHEELUPMOUSE:
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 3227a9557e6..9f77bf31481 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -35,7 +35,10 @@
#include "DNA_scene_types.h"
#include "BLI_alloca.h"
+#include "BLI_array.h"
+#include "BLI_linklist.h"
#include "BLI_math.h"
+#include "BLI_memarena.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLI_uvproject.h"
@@ -147,7 +150,13 @@ typedef struct UnwrapOptions {
/** Connectivity based on UV coordinates instead of seams. */
bool topology_from_uvs;
/** Only affect selected faces. */
- bool only_selected;
+ bool only_selected_faces;
+ /**
+ * Only affect selected UV's.
+ * \note Disable this for operations that don't run in the image-window.
+ * Unwrapping from the 3D view for example, where only 'only_selected_faces' should be used.
+ */
+ bool only_selected_uvs;
/** Fill holes to better preserve shape. */
bool fill_holes;
/** Correct for mapped image texture aspect ratio. */
@@ -210,15 +219,16 @@ static bool uvedit_have_selection_multi(const Scene *scene,
return have_select;
}
-void ED_uvedit_get_aspect(
- const Scene *UNUSED(scene), Object *ob, BMesh *bm, float *r_aspx, float *r_aspy)
+void ED_uvedit_get_aspect(Object *ob, float *r_aspx, float *r_aspy)
{
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BLI_assert(em != NULL);
bool sloppy = true;
bool selected = false;
BMFace *efa;
Image *ima;
- efa = BM_mesh_active_face_get(bm, sloppy, selected);
+ efa = BM_mesh_active_face_get(em->bm, sloppy, selected);
if (efa) {
ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL);
@@ -285,7 +295,7 @@ static ParamHandle *construct_param_handle(const Scene *scene,
if (options->correct_aspect) {
float aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, bm, &aspx, &aspy);
+ ED_uvedit_get_aspect(ob, &aspx, &aspy);
if (aspx != aspy) {
param_aspect_ratio(handle, aspx, aspy);
@@ -298,7 +308,7 @@ static ParamHandle *construct_param_handle(const Scene *scene,
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) ||
- (options->only_selected && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
+ (options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
continue;
}
@@ -306,10 +316,12 @@ static ParamHandle *construct_param_handle(const Scene *scene,
bool is_loopsel = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- is_loopsel = true;
- break;
+ if (options->only_selected_uvs &&
+ (uvedit_uv_select_test(scene, l, cd_loop_uv_offset) == false)) {
+ continue;
}
+ is_loopsel = true;
+ break;
}
if (is_loopsel == false) {
continue;
@@ -354,11 +366,9 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene,
if (options->correct_aspect) {
Object *ob = objects[0];
- BMEditMesh *em = BKE_editmesh_from_object(ob);
- BMesh *bm = em->bm;
float aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, bm, &aspx, &aspy);
+ ED_uvedit_get_aspect(ob, &aspx, &aspy);
if (aspx != aspy) {
param_aspect_ratio(handle, aspx, aspy);
}
@@ -383,7 +393,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene,
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) ||
- (options->only_selected && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
+ (options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
continue;
}
@@ -391,10 +401,12 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene,
bool is_loopsel = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- is_loopsel = true;
- break;
+ if (options->only_selected_uvs &&
+ (uvedit_uv_select_test(scene, l, cd_loop_uv_offset) == false)) {
+ continue;
}
+ is_loopsel = true;
+ break;
}
if (is_loopsel == false) {
continue;
@@ -500,7 +512,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
if (options->correct_aspect) {
float aspx, aspy;
- ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy);
+ ED_uvedit_get_aspect(ob, &aspx, &aspy);
if (aspx != aspy) {
param_aspect_ratio(handle, aspx, aspy);
@@ -572,7 +584,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
}
else {
if (BM_elem_flag_test(origFace, BM_ELEM_HIDDEN) ||
- (options->only_selected && !BM_elem_flag_test(origFace, BM_ELEM_SELECT))) {
+ (options->only_selected_faces && !BM_elem_flag_test(origFace, BM_ELEM_SELECT))) {
continue;
}
}
@@ -672,7 +684,8 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op)
const UnwrapOptions options = {
.topology_from_uvs = true,
.fill_holes = RNA_boolean_get(op->ptr, "fill_holes"),
- .only_selected = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = true,
.correct_aspect = true,
};
@@ -934,7 +947,8 @@ static void uvedit_pack_islands(const Scene *scene, Object *ob, BMesh *bm)
{
const UnwrapOptions options = {
.topology_from_uvs = true,
- .only_selected = false,
+ .only_selected_faces = false,
+ .only_selected_uvs = true,
.fill_holes = false,
.correct_aspect = false,
};
@@ -976,7 +990,8 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
const UnwrapOptions options = {
.topology_from_uvs = true,
- .only_selected = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = true,
.fill_holes = false,
.correct_aspect = true,
};
@@ -1041,7 +1056,8 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op))
const UnwrapOptions options = {
.topology_from_uvs = true,
- .only_selected = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = true,
.fill_holes = false,
.correct_aspect = true,
};
@@ -1115,7 +1131,8 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
const UnwrapOptions options = {
.topology_from_uvs = false,
- .only_selected = false,
+ .only_selected_faces = false,
+ .only_selected_uvs = true,
.fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0,
.correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0,
};
@@ -1413,7 +1430,7 @@ static void uv_transform_properties(wmOperatorType *ot, int radius)
}
}
-static void correct_uv_aspect(const Scene *scene, Object *ob, BMEditMesh *em)
+static void correct_uv_aspect(Object *ob, BMEditMesh *em)
{
BMLoop *l;
BMIter iter, liter;
@@ -1423,7 +1440,7 @@ static void correct_uv_aspect(const Scene *scene, Object *ob, BMEditMesh *em)
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy);
+ ED_uvedit_get_aspect(ob, &aspx, &aspy);
if (aspx == aspy) {
return;
@@ -1472,18 +1489,21 @@ static void correct_uv_aspect(const Scene *scene, Object *ob, BMEditMesh *em)
/** \name UV Map Clip & Correct
* \{ */
-static void uv_map_clip_correct_properties(wmOperatorType *ot)
+static void uv_map_clip_correct_properties_ex(wmOperatorType *ot, bool clip_to_bounds)
{
RNA_def_boolean(ot->srna,
"correct_aspect",
1,
"Correct Aspect",
"Map UVs taking image aspect ratio into account");
- RNA_def_boolean(ot->srna,
- "clip_to_bounds",
- 0,
- "Clip to Bounds",
- "Clip UV coordinates to bounds after unwrapping");
+ /* Optional, since not all unwrapping types need to be clipped. */
+ if (clip_to_bounds) {
+ RNA_def_boolean(ot->srna,
+ "clip_to_bounds",
+ 0,
+ "Clip to Bounds",
+ "Clip UV coordinates to bounds after unwrapping");
+ }
RNA_def_boolean(ot->srna,
"scale_to_bounds",
0,
@@ -1491,10 +1511,12 @@ static void uv_map_clip_correct_properties(wmOperatorType *ot)
"Scale UV coordinates to bounds after unwrapping");
}
-static void uv_map_clip_correct_multi(const Scene *scene,
- Object **objects,
- uint objects_len,
- wmOperator *op)
+static void uv_map_clip_correct_properties(wmOperatorType *ot)
+{
+ uv_map_clip_correct_properties_ex(ot, true);
+}
+
+static void uv_map_clip_correct_multi(Object **objects, uint objects_len, wmOperator *op)
{
BMFace *efa;
BMLoop *l;
@@ -1502,7 +1524,8 @@ static void uv_map_clip_correct_multi(const Scene *scene,
MLoopUV *luv;
float dx, dy, min[2], max[2];
const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
- const bool clip_to_bounds = RNA_boolean_get(op->ptr, "clip_to_bounds");
+ const bool clip_to_bounds = (RNA_struct_find_property(op->ptr, "clip_to_bounds") &&
+ RNA_boolean_get(op->ptr, "clip_to_bounds"));
const bool scale_to_bounds = RNA_boolean_get(op->ptr, "scale_to_bounds");
INIT_MINMAX2(min, max);
@@ -1515,7 +1538,7 @@ static void uv_map_clip_correct_multi(const Scene *scene,
/* correct for image aspect ratio */
if (correct_aspect) {
- correct_uv_aspect(scene, ob, em);
+ correct_uv_aspect(ob, em);
}
if (scale_to_bounds) {
@@ -1580,9 +1603,9 @@ static void uv_map_clip_correct_multi(const Scene *scene,
}
}
-static void uv_map_clip_correct(const Scene *scene, Object *ob, wmOperator *op)
+static void uv_map_clip_correct(Object *ob, wmOperator *op)
{
- uv_map_clip_correct_multi(scene, &ob, 1, op);
+ uv_map_clip_correct_multi(&ob, 1, op);
}
/** \} */
@@ -1639,7 +1662,8 @@ void ED_uvedit_live_unwrap(const Scene *scene, Object **objects, int objects_len
if (scene->toolsettings->edge_mode_live_unwrap) {
const UnwrapOptions options = {
.topology_from_uvs = false,
- .only_selected = false,
+ .only_selected_faces = false,
+ .only_selected_uvs = true,
.fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0,
.correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0,
};
@@ -1674,7 +1698,8 @@ static int unwrap_exec(bContext *C, wmOperator *op)
const UnwrapOptions options = {
.topology_from_uvs = false,
- .only_selected = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = true,
.fill_holes = RNA_boolean_get(op->ptr, "fill_holes"),
.correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"),
};
@@ -1833,6 +1858,363 @@ void UV_OT_unwrap(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Smart UV Project Operator
+ * \{ */
+
+/* Ignore all areas below this, as the UV's get zeroed. */
+static const float smart_uv_project_area_ignore = 1e-12f;
+
+typedef struct ThickFace {
+ float area;
+ BMFace *efa;
+} ThickFace;
+
+static int smart_uv_project_thickface_area_cmp_fn(const void *tf_a_p, const void *tf_b_p)
+{
+
+ const ThickFace *tf_a = (ThickFace *)tf_a_p;
+ const ThickFace *tf_b = (ThickFace *)tf_b_p;
+
+ /* Ignore the area of small faces.
+ * Also, order checks so `!isfinite(...)` values are counted as zero area. */
+ if (!((tf_a->area > smart_uv_project_area_ignore) ||
+ (tf_b->area > smart_uv_project_area_ignore))) {
+ return 0;
+ }
+
+ if (tf_a->area < tf_b->area) {
+ return 1;
+ }
+ if (tf_a->area > tf_b->area) {
+ return -1;
+ }
+ return 0;
+}
+
+static uint smart_uv_project_calculate_project_normals(const ThickFace *thick_faces,
+ const uint thick_faces_len,
+ BMesh *bm,
+ const float project_angle_limit_half_cos,
+ const float project_angle_limit_cos,
+ const float area_weight,
+ float (**r_project_normal_array)[3])
+{
+ if (UNLIKELY(thick_faces_len == 0)) {
+ *r_project_normal_array = NULL;
+ return 0;
+ }
+
+ const float *project_normal = thick_faces[0].efa->no;
+
+ const ThickFace **project_thick_faces = NULL;
+ BLI_array_declare(project_thick_faces);
+
+ float(*project_normal_array)[3] = NULL;
+ BLI_array_declare(project_normal_array);
+
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+
+ while (true) {
+ for (int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
+ if (BM_elem_flag_test(thick_faces[f_index].efa, BM_ELEM_TAG)) {
+ continue;
+ }
+
+ if (dot_v3v3(thick_faces[f_index].efa->no, project_normal) > project_angle_limit_half_cos) {
+ BLI_array_append(project_thick_faces, &thick_faces[f_index]);
+ BM_elem_flag_set(thick_faces[f_index].efa, BM_ELEM_TAG, true);
+ }
+ }
+
+ float average_normal[3] = {0.0f, 0.0f, 0.0f};
+
+ if (area_weight <= 0.0f) {
+ for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces);
+ f_proj_index++) {
+ const ThickFace *tf = project_thick_faces[f_proj_index];
+ add_v3_v3(average_normal, tf->efa->no);
+ }
+ }
+ else if (area_weight >= 1.0f) {
+ for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces);
+ f_proj_index++) {
+ const ThickFace *tf = project_thick_faces[f_proj_index];
+ madd_v3_v3fl(average_normal, tf->efa->no, tf->area);
+ }
+ }
+ else {
+ for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces);
+ f_proj_index++) {
+ const ThickFace *tf = project_thick_faces[f_proj_index];
+ const float area_blend = (tf->area * area_weight) + (1.0f - area_weight);
+ madd_v3_v3fl(average_normal, tf->efa->no, area_blend);
+ }
+ }
+
+ /* Avoid NAN. */
+ if (normalize_v3(average_normal) != 0.0f) {
+ float(*normal)[3] = BLI_array_append_ret(project_normal_array);
+ copy_v3_v3(*normal, average_normal);
+ }
+
+ /* Find the most unique angle that points away from other normals. */
+ float anble_best = 1.0f;
+ uint angle_best_index = 0;
+
+ for (int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
+ if (BM_elem_flag_test(thick_faces[f_index].efa, BM_ELEM_TAG)) {
+ continue;
+ }
+
+ float angle_test = -1.0f;
+ for (int p_index = 0; p_index < BLI_array_len(project_normal_array); p_index++) {
+ angle_test = max_ff(angle_test,
+ dot_v3v3(project_normal_array[p_index], thick_faces[f_index].efa->no));
+ }
+
+ if (angle_test < anble_best) {
+ anble_best = angle_test;
+ angle_best_index = f_index;
+ }
+ }
+
+ if (anble_best < project_angle_limit_cos) {
+ project_normal = thick_faces[angle_best_index].efa->no;
+ BLI_array_clear(project_thick_faces);
+ BLI_array_append(project_thick_faces, &thick_faces[angle_best_index]);
+ BM_elem_flag_enable(thick_faces[angle_best_index].efa, BM_ELEM_TAG);
+ }
+ else {
+ if (BLI_array_len(project_normal_array) >= 1) {
+ break;
+ }
+ }
+ }
+
+ BLI_array_free(project_thick_faces);
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+
+ *r_project_normal_array = project_normal_array;
+ return BLI_array_len(project_normal_array);
+}
+
+static int smart_project_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ /* May be NULL. */
+ View3D *v3d = CTX_wm_view3d(C);
+
+ const float project_angle_limit = RNA_float_get(op->ptr, "angle_limit");
+ const float island_margin = RNA_float_get(op->ptr, "island_margin");
+ const float area_weight = RNA_float_get(op->ptr, "area_weight");
+
+ const float project_angle_limit_cos = cosf(project_angle_limit);
+ const float project_angle_limit_half_cos = cosf(project_angle_limit / 2);
+
+ /* Memory arena for list links (cleared for each object). */
+ MemArena *arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ view_layer, v3d, &objects_len);
+
+ Object **objects_changed = MEM_mallocN(sizeof(*objects_changed) * objects_len, __func__);
+ uint object_changed_len = 0;
+
+ BMFace *efa;
+ BMIter iter;
+ uint ob_index;
+
+ for (ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ bool changed = false;
+
+ const uint cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ ThickFace *thick_faces = MEM_mallocN(sizeof(*thick_faces) * em->bm->totface, __func__);
+
+ uint thick_faces_len = 0;
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
+ continue;
+ }
+ thick_faces[thick_faces_len].area = BM_face_calc_area(efa);
+ thick_faces[thick_faces_len].efa = efa;
+ thick_faces_len++;
+ }
+
+ qsort(thick_faces, thick_faces_len, sizeof(ThickFace), smart_uv_project_thickface_area_cmp_fn);
+
+ /* Remove all zero area faces. */
+ while ((thick_faces_len > 0) &&
+ !(thick_faces[thick_faces_len - 1].area > smart_uv_project_area_ignore)) {
+
+ /* Zero UV's so they don't overlap with other faces being unwrapped. */
+ BMIter liter;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, thick_faces[thick_faces_len - 1].efa, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ zero_v2(luv->uv);
+ changed = true;
+ }
+
+ thick_faces_len -= 1;
+ }
+
+ float(*project_normal_array)[3] = NULL;
+ int project_normals_len = smart_uv_project_calculate_project_normals(
+ thick_faces,
+ thick_faces_len,
+ em->bm,
+ project_angle_limit_half_cos,
+ project_angle_limit_cos,
+ area_weight,
+ &project_normal_array);
+
+ if (project_normals_len == 0) {
+ MEM_freeN(thick_faces);
+ BLI_assert(project_normal_array == NULL);
+ continue;
+ }
+
+ /* After finding projection vectors, we find the uv positions. */
+ LinkNode **thickface_project_groups = MEM_callocN(
+ sizeof(*thickface_project_groups) * project_normals_len, __func__);
+
+ BLI_memarena_clear(arena);
+
+ for (int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
+ const float *f_normal = thick_faces[f_index].efa->no;
+
+ float angle_best = dot_v3v3(f_normal, project_normal_array[0]);
+ uint angle_best_index = 0;
+
+ for (int p_index = 1; p_index < project_normals_len; p_index++) {
+ const float angle_test = dot_v3v3(f_normal, project_normal_array[p_index]);
+ if (angle_test > angle_best) {
+ angle_best = angle_test;
+ angle_best_index = p_index;
+ }
+ }
+
+ BLI_linklist_prepend_arena(
+ &thickface_project_groups[angle_best_index], &thick_faces[f_index], arena);
+ }
+
+ for (int p_index = 0; p_index < project_normals_len; p_index++) {
+ if (thickface_project_groups[p_index] == NULL) {
+ continue;
+ }
+
+ float axis_mat[3][3];
+ axis_dominant_v3_to_m3_negate(axis_mat, project_normal_array[p_index]);
+
+ for (LinkNode *list = thickface_project_groups[p_index]; list; list = list->next) {
+ ThickFace *tf = list->link;
+ BMIter liter;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, tf->efa, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ mul_v2_m3v3(luv->uv, axis_mat, l->v->co);
+ }
+ changed = true;
+ }
+ }
+
+ MEM_freeN(thick_faces);
+ MEM_freeN(project_normal_array);
+
+ /* No need to free the lists in 'thickface_project_groups' values as the 'arena' is used. */
+ MEM_freeN(thickface_project_groups);
+
+ if (changed) {
+ objects_changed[object_changed_len] = objects[ob_index];
+ object_changed_len += 1;
+ }
+ }
+
+ BLI_memarena_free(arena);
+
+ MEM_freeN(objects);
+
+ /* Pack islands & Stretch to UV bounds */
+ if (object_changed_len > 0) {
+
+ scene->toolsettings->uvcalc_margin = island_margin;
+ const UnwrapOptions options = {
+ .topology_from_uvs = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = false,
+ .fill_holes = true,
+ .correct_aspect = false,
+ };
+
+ /* Depsgraph refresh functions are called here. */
+ uvedit_pack_islands_multi(scene, objects_changed, object_changed_len, &options, true, false);
+ uv_map_clip_correct_multi(objects_changed, object_changed_len, op);
+ }
+
+ MEM_freeN(objects_changed);
+
+ return OPERATOR_FINISHED;
+}
+
+void UV_OT_smart_project(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Smart UV Project";
+ ot->idname = "UV_OT_smart_project";
+ ot->description = "Projection unwraps the selected faces of mesh objects";
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = smart_project_exec;
+ ot->poll = ED_operator_uvmap;
+ ot->invoke = WM_operator_props_popup_confirm;
+
+ /* properties */
+ prop = RNA_def_float_rotation(ot->srna,
+ "angle_limit",
+ 0,
+ NULL,
+ DEG2RADF(0.0f),
+ DEG2RADF(90.0f),
+ "Angle Limit",
+ "Lower for more projection groups, higher for less distortion",
+ DEG2RADF(0.0f),
+ DEG2RADF(89.0f));
+ RNA_def_property_float_default(prop, DEG2RADF(66.0f));
+
+ RNA_def_float(ot->srna,
+ "island_margin",
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ "Island Margin",
+ "Margin to reduce bleed from adjacent islands",
+ 0.0f,
+ 1.0f);
+ RNA_def_float(ot->srna,
+ "area_weight",
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ "Area Weight",
+ "Weight projections vector by faces with larger areas",
+ 0.0f,
+ 1.0f);
+
+ uv_map_clip_correct_properties_ex(ot, false);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Project UV From View Operator
* \{ */
@@ -1973,7 +2355,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
}
if (changed_multi) {
- uv_map_clip_correct_multi(scene, objects, objects_len, op);
+ uv_map_clip_correct_multi(objects, objects_len, op);
}
MEM_freeN(objects);
@@ -1981,9 +2363,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
if (changed_multi) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static bool uv_from_view_poll(bContext *C)
@@ -2176,7 +2556,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
uv_map_mirror(em, efa);
}
- uv_map_clip_correct(scene, obedit, op);
+ uv_map_clip_correct(obedit, op);
DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
@@ -2274,7 +2654,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
uv_map_mirror(em, efa);
}
- uv_map_clip_correct(scene, obedit, op);
+ uv_map_clip_correct(obedit, op);
DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
@@ -2397,7 +2777,7 @@ static int cube_project_exec(bContext *C, wmOperator *op)
uvedit_unwrap_cube_project(em->bm, cube_size, true, center);
- uv_map_clip_correct(scene, obedit, op);
+ uv_map_clip_correct(obedit, op);
DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
diff --git a/source/blender/freestyle/FRS_freestyle.h b/source/blender/freestyle/FRS_freestyle.h
index 876f40b211f..bc5e9d49bee 100644
--- a/source/blender/freestyle/FRS_freestyle.h
+++ b/source/blender/freestyle/FRS_freestyle.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FRS_FREESTYLE_H__
-#define __FRS_FREESTYLE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -43,7 +42,7 @@ struct FreestyleGlobals {
extern struct FreestyleGlobals g_freestyle;
/* Rendering */
-void FRS_initialize(void);
+void FRS_init(void);
void FRS_set_context(struct bContext *C);
int FRS_is_freestyle_enabled(struct ViewLayer *view_layer);
void FRS_init_stroke_renderer(struct Render *re);
@@ -69,5 +68,3 @@ struct Material *FRS_create_stroke_material(struct Main *bmain,
#ifdef __cplusplus
}
#endif
-
-#endif // __FRS_FREESTYLE_H__
diff --git a/source/blender/freestyle/intern/application/AppCanvas.h b/source/blender/freestyle/intern/application/AppCanvas.h
index 9d1e2458564..1ff7e781ce6 100644
--- a/source/blender/freestyle/intern/application/AppCanvas.h
+++ b/source/blender/freestyle/intern/application/AppCanvas.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __APPCANVAS_H__
-#define __APPCANVAS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -93,5 +92,3 @@ class AppCanvas : public Canvas {
};
} /* namespace Freestyle */
-
-#endif // __APPCANVAS_H__
diff --git a/source/blender/freestyle/intern/application/AppConfig.cpp b/source/blender/freestyle/intern/application/AppConfig.cpp
index a2f0a3395af..3aae4254b4b 100644
--- a/source/blender/freestyle/intern/application/AppConfig.cpp
+++ b/source/blender/freestyle/intern/application/AppConfig.cpp
@@ -26,9 +26,7 @@
using namespace std;
-extern "C" {
#include "BKE_appdir.h"
-}
namespace Freestyle {
@@ -46,17 +44,15 @@ Path::Path()
void Path::setRootDir(const string &iRootDir)
{
- _ProjectDir = iRootDir + string(DIR_SEP.c_str()) + "freestyle";
+ _ProjectDir = iRootDir + string(DIR_SEP) + "freestyle";
_ModelsPath = "";
- _PatternsPath = _ProjectDir + string(DIR_SEP.c_str()) + "data" + string(DIR_SEP.c_str()) +
- "textures" + string(DIR_SEP.c_str()) + "variation_patterns" +
- string(DIR_SEP.c_str());
- _BrushesPath = _ProjectDir + string(DIR_SEP.c_str()) + "data" + string(DIR_SEP.c_str()) +
- "textures" + string(DIR_SEP.c_str()) + "brushes" + string(DIR_SEP.c_str());
- _EnvMapDir = _ProjectDir + string(DIR_SEP.c_str()) + "data" + string(DIR_SEP.c_str()) +
- "env_map" + string(DIR_SEP.c_str());
- _MapsDir = _ProjectDir + string(DIR_SEP.c_str()) + "data" + string(DIR_SEP.c_str()) + "maps" +
- string(DIR_SEP.c_str());
+ _PatternsPath = _ProjectDir + string(DIR_SEP) + "data" + string(DIR_SEP) + "textures" +
+ string(DIR_SEP) + "variation_patterns" + string(DIR_SEP);
+ _BrushesPath = _ProjectDir + string(DIR_SEP) + "data" + string(DIR_SEP) + "textures" +
+ string(DIR_SEP) + "brushes" + string(DIR_SEP);
+ _EnvMapDir = _ProjectDir + string(DIR_SEP) + "data" + string(DIR_SEP) + "env_map" +
+ string(DIR_SEP);
+ _MapsDir = _ProjectDir + string(DIR_SEP) + "data" + string(DIR_SEP) + "maps" + string(DIR_SEP);
}
void Path::setHomeDir(const string &iHomeDir)
diff --git a/source/blender/freestyle/intern/application/AppConfig.h b/source/blender/freestyle/intern/application/AppConfig.h
index 34f5d220cfe..61beff33876 100644
--- a/source/blender/freestyle/intern/application/AppConfig.h
+++ b/source/blender/freestyle/intern/application/AppConfig.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __APP_CONFIG_H__
-#define __APP_CONFIG_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -123,5 +122,3 @@ static const real DEFAULT_DKR_EPSILON = 0.0;
} // namespace Config
} /* namespace Freestyle */
-
-#endif // __APP_CONFIG_H__
diff --git a/source/blender/freestyle/intern/application/AppView.cpp b/source/blender/freestyle/intern/application/AppView.cpp
index 0956d33a20e..5cd30a61712 100644
--- a/source/blender/freestyle/intern/application/AppView.cpp
+++ b/source/blender/freestyle/intern/application/AppView.cpp
@@ -33,7 +33,6 @@
#include "../view_map/Silhouette.h"
#include "../view_map/ViewMap.h"
-extern "C" {
#include "BLI_blenlib.h"
#include "IMB_imbuf.h"
@@ -45,7 +44,6 @@ extern "C" {
#endif
#include "FRS_freestyle.h"
-}
namespace Freestyle {
diff --git a/source/blender/freestyle/intern/application/AppView.h b/source/blender/freestyle/intern/application/AppView.h
index 6009f2b0e50..3f07d2794c4 100644
--- a/source/blender/freestyle/intern/application/AppView.h
+++ b/source/blender/freestyle/intern/application/AppView.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __APPVIEW_H__
-#define __APPVIEW_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -272,5 +271,3 @@ class AppView {
};
} /* namespace Freestyle */
-
-#endif // __APPVIEW_H__
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index dfe78eaf10c..f9edadb2d4a 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -74,7 +74,7 @@ namespace Freestyle {
Controller::Controller()
{
- const string sep(Config::DIR_SEP.c_str());
+ const string sep(Config::DIR_SEP);
#if 0
const string filename = Config::Path::getInstance()->getHomeDir() + sep + Config::OPTIONS_DIR +
sep + Config::OPTIONS_CURRENT_DIRS_FILE;
diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h
index 613ea2cb45c..6c41733db36 100644
--- a/source/blender/freestyle/intern/application/Controller.h
+++ b/source/blender/freestyle/intern/application/Controller.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __CONTROLLER_H__
-#define __CONTROLLER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -278,5 +277,3 @@ class Controller {
extern Controller *g_pController;
} /* namespace Freestyle */
-
-#endif // __CONTROLLER_H__
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index 0af57e5d728..e1763514e08 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -222,7 +222,7 @@ void BlenderFileLoader::clipTriangle(int numTris,
bool em1,
bool em2,
bool em3,
- int clip[3])
+ const int clip[3])
{
float *v[3], *n[3];
bool em[3];
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
index ad6379d5f52..50834db3c5c 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLENDER_FILE_LOADER_H__
-#define __BLENDER_FILE_LOADER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -37,7 +36,6 @@
#include "MEM_guardedalloc.h"
-extern "C" {
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -56,7 +54,6 @@ extern "C" {
#include "BLI_iterator.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
-}
#include "DEG_depsgraph_query.h"
@@ -128,7 +125,7 @@ class BlenderFileLoader {
bool em1,
bool em2,
bool em3,
- int clip[3]);
+ const int clip[3]);
void addTriangle(struct LoaderState *ls,
float v1[3],
float v2[3],
@@ -170,5 +167,3 @@ class BlenderFileLoader {
};
} /* namespace Freestyle */
-
-#endif // __BLENDER_FILE_LOADER_H__
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
index 21505f47ae2..1b2e57529d6 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLENDER_STROKE_RENDERER_H__
-#define __BLENDER_STROKE_RENDERER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -102,5 +101,3 @@ class BlenderStrokeRenderer : public StrokeRenderer {
};
} /* namespace Freestyle */
-
-#endif // __BLENDER_STROKE_RENDERER_H__
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
index 95612a42722..e7636e2453a 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLENDERSTYLEMODULE_H__
-#define __BLENDERSTYLEMODULE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -87,5 +86,3 @@ class BlenderStyleModule : public StyleModule {
};
} /* namespace Freestyle */
-
-#endif // __BLENDERSTYLEMODULE_H__
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 26070a88e5d..2b43e913b3d 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -34,8 +34,6 @@ using namespace Freestyle;
#include "MEM_guardedalloc.h"
-extern "C" {
-
#include "DNA_camera_types.h"
#include "DNA_collection_types.h"
#include "DNA_freestyle_types.h"
@@ -65,6 +63,8 @@ extern "C" {
#include "FRS_freestyle.h"
+extern "C" {
+
#define DEFAULT_SPHERE_RADIUS 1.0f
#define DEFAULT_DKR_EPSILON 0.0f
@@ -100,7 +100,7 @@ static bCallbackFuncStore load_post_callback_funcstore = {
// Initialization
//=======================================================
-void FRS_initialize()
+void FRS_init()
{
if (freestyle_is_initialized) {
return;
diff --git a/source/blender/freestyle/intern/geometry/BBox.h b/source/blender/freestyle/intern/geometry/BBox.h
index a8965e63451..d9a070faa55 100644
--- a/source/blender/freestyle/intern/geometry/BBox.h
+++ b/source/blender/freestyle/intern/geometry/BBox.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BBOX_H__
-#define __BBOX_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -156,5 +155,3 @@ template<class Point> BBox<Point> &operator+(const BBox<Point> &b1, const BBox<P
}
} /* namespace Freestyle */
-
-#endif // __BBOX_H__
diff --git a/source/blender/freestyle/intern/geometry/Bezier.cpp b/source/blender/freestyle/intern/geometry/Bezier.cpp
index 9a832c04699..4ae30ff893c 100644
--- a/source/blender/freestyle/intern/geometry/Bezier.cpp
+++ b/source/blender/freestyle/intern/geometry/Bezier.cpp
@@ -109,9 +109,7 @@ BezierCurve::~BezierCurve()
delete *v;
}
}
- if (_currentSegment) {
- delete _currentSegment;
- }
+ delete _currentSegment;
}
void BezierCurve::AddControlPoint(const Vec2d &iPoint)
diff --git a/source/blender/freestyle/intern/geometry/Bezier.h b/source/blender/freestyle/intern/geometry/Bezier.h
index adcd6e3a652..4c6b38935f9 100644
--- a/source/blender/freestyle/intern/geometry/Bezier.h
+++ b/source/blender/freestyle/intern/geometry/Bezier.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BEZIER_H__
-#define __BEZIER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -92,5 +91,3 @@ class BezierCurve {
};
} /* namespace Freestyle */
-
-#endif // __BEZIER_H__
diff --git a/source/blender/freestyle/intern/geometry/FastGrid.h b/source/blender/freestyle/intern/geometry/FastGrid.h
index 367c233d799..ec47f36d644 100644
--- a/source/blender/freestyle/intern/geometry/FastGrid.h
+++ b/source/blender/freestyle/intern/geometry/FastGrid.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FASTGRID_H__
-#define __FASTGRID_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -76,5 +75,3 @@ class FastGrid : public Grid {
};
} /* namespace Freestyle */
-
-#endif // __FASTGRID_H__
diff --git a/source/blender/freestyle/intern/geometry/FitCurve.h b/source/blender/freestyle/intern/geometry/FitCurve.h
index 92afd685d8f..c08dc52249e 100644
--- a/source/blender/freestyle/intern/geometry/FitCurve.h
+++ b/source/blender/freestyle/intern/geometry/FitCurve.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FITCURVE_H__
-#define __FITCURVE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -109,5 +108,3 @@ class FitCurveWrapper {
};
} /* namespace Freestyle */
-
-#endif // __FITCURVE_H__
diff --git a/source/blender/freestyle/intern/geometry/Geom.h b/source/blender/freestyle/intern/geometry/Geom.h
index 63785d56cab..53703c3497a 100644
--- a/source/blender/freestyle/intern/geometry/Geom.h
+++ b/source/blender/freestyle/intern/geometry/Geom.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GEOM_H__
-#define __GEOM_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -69,5 +68,3 @@ typedef VecMat::SquareMatrix<real, 4> Matrix44r;
} // end of namespace Geometry
} /* namespace Freestyle */
-
-#endif // __GEOM_H__
diff --git a/source/blender/freestyle/intern/geometry/GeomCleaner.h b/source/blender/freestyle/intern/geometry/GeomCleaner.h
index aee8ed6963d..7abbf881548 100644
--- a/source/blender/freestyle/intern/geometry/GeomCleaner.h
+++ b/source/blender/freestyle/intern/geometry/GeomCleaner.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GEOMCLEANER_H__
-#define __GEOMCLEANER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -257,5 +256,3 @@ bool operator<(const IndexedVertex &iv1, const IndexedVertex &iv2)
#endif
} /* namespace Freestyle */
-
-#endif // __GEOMCLEANER_H__
diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.h b/source/blender/freestyle/intern/geometry/GeomUtils.h
index 635808aab4b..46cd307d9af 100644
--- a/source/blender/freestyle/intern/geometry/GeomUtils.h
+++ b/source/blender/freestyle/intern/geometry/GeomUtils.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GEOMUTILS_H__
-#define __GEOMUTILS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -266,5 +265,3 @@ void fromCameraToWorld(const Vec3r &p, Vec3r &q, const real model_view_matrix[4]
} // end of namespace GeomUtils
} /* namespace Freestyle */
-
-#endif // __GEOMUTILS_H__
diff --git a/source/blender/freestyle/intern/geometry/Grid.h b/source/blender/freestyle/intern/geometry/Grid.h
index c1a8dcdb370..b66f04398af 100644
--- a/source/blender/freestyle/intern/geometry/Grid.h
+++ b/source/blender/freestyle/intern/geometry/Grid.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GRID_H__
-#define __GRID_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -433,5 +432,3 @@ class VirtualOccludersSet {
};
} /* namespace Freestyle */
-
-#endif // __GRID_H__
diff --git a/source/blender/freestyle/intern/geometry/GridHelpers.h b/source/blender/freestyle/intern/geometry/GridHelpers.h
index 3f3c669cb57..077688164b4 100644
--- a/source/blender/freestyle/intern/geometry/GridHelpers.h
+++ b/source/blender/freestyle/intern/geometry/GridHelpers.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GRIDHELPERS_H__
-#define __GRIDHELPERS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -212,5 +211,3 @@ inline void expandProscenium(real proscenium[4], const Vec3r &point)
}; // namespace GridHelpers
} /* namespace Freestyle */
-
-#endif // __GRIDHELPERS_H__
diff --git a/source/blender/freestyle/intern/geometry/HashGrid.h b/source/blender/freestyle/intern/geometry/HashGrid.h
index 4bb92859775..6fb7f2b9cbe 100644
--- a/source/blender/freestyle/intern/geometry/HashGrid.h
+++ b/source/blender/freestyle/intern/geometry/HashGrid.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __HASHGRID_H__
-#define __HASHGRID_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -104,5 +103,3 @@ class HashGrid : public Grid {
};
} /* namespace Freestyle */
-
-#endif // __HASHGRID_H__
diff --git a/source/blender/freestyle/intern/geometry/Noise.h b/source/blender/freestyle/intern/geometry/Noise.h
index 18992092b19..27a91ded9e2 100644
--- a/source/blender/freestyle/intern/geometry/Noise.h
+++ b/source/blender/freestyle/intern/geometry/Noise.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __NOISE_H__
-#define __NOISE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -81,5 +80,3 @@ class Noise {
};
} /* namespace Freestyle */
-
-#endif // __NOISE_H__
diff --git a/source/blender/freestyle/intern/geometry/Polygon.h b/source/blender/freestyle/intern/geometry/Polygon.h
index b3f47c8ca77..f6f827fd0f2 100644
--- a/source/blender/freestyle/intern/geometry/Polygon.h
+++ b/source/blender/freestyle/intern/geometry/Polygon.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __POLYGON_H__
-#define __POLYGON_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -230,5 +229,3 @@ class Polygon3r : public Polygon<Vec3r> {
} // end of namespace Geometry
} /* namespace Freestyle */
-
-#endif // __POLYGON_H__
diff --git a/source/blender/freestyle/intern/geometry/SweepLine.h b/source/blender/freestyle/intern/geometry/SweepLine.h
index b3555a4a160..d7d379d82f2 100644
--- a/source/blender/freestyle/intern/geometry/SweepLine.h
+++ b/source/blender/freestyle/intern/geometry/SweepLine.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __SWEEPLINE_H__
-#define __SWEEPLINE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -347,5 +346,3 @@ template<class T, class Point> class SweepLine {
};
} /* namespace Freestyle */
-
-#endif // __SWEEPLINE_H__
diff --git a/source/blender/freestyle/intern/geometry/VecMat.h b/source/blender/freestyle/intern/geometry/VecMat.h
index ee1cc42876c..64c3213560c 100644
--- a/source/blender/freestyle/intern/geometry/VecMat.h
+++ b/source/blender/freestyle/intern/geometry/VecMat.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __VECMAT_H__
-#define __VECMAT_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -1005,5 +1004,3 @@ inline std::ostream &operator<<(std::ostream &s, const Matrix<T, M, N> &m)
} // end of namespace VecMat
} /* namespace Freestyle */
-
-#endif // __VECMAT_H__
diff --git a/source/blender/freestyle/intern/geometry/matrix_util.cpp b/source/blender/freestyle/intern/geometry/matrix_util.cpp
index 811b10813d1..9d25a240a63 100644
--- a/source/blender/freestyle/intern/geometry/matrix_util.cpp
+++ b/source/blender/freestyle/intern/geometry/matrix_util.cpp
@@ -248,7 +248,6 @@ void semi_definite_symmetric_eigen(const double *mat, int n, double *eigen_vec,
delete[] v;
delete[] index;
- return;
}
//_________________________________________________________
diff --git a/source/blender/freestyle/intern/geometry/matrix_util.h b/source/blender/freestyle/intern/geometry/matrix_util.h
index f42e043ca97..996ebc928a1 100644
--- a/source/blender/freestyle/intern/geometry/matrix_util.h
+++ b/source/blender/freestyle/intern/geometry/matrix_util.h
@@ -25,8 +25,7 @@
* FRANCE
*/
-#ifndef __MATRIX_UTIL__
-#define __MATRIX_UTIL__
+#pragma once
/** \file
* \ingroup freestyle
@@ -61,5 +60,3 @@ void semi_definite_symmetric_eigen(const double *mat, int n, double *eigen_vec,
} // namespace OGF
} /* namespace Freestyle */
-
-#endif // __MATRIX_UTIL__
diff --git a/source/blender/freestyle/intern/geometry/normal_cycle.h b/source/blender/freestyle/intern/geometry/normal_cycle.h
index a57bfdb953e..6ac9779e7c2 100644
--- a/source/blender/freestyle/intern/geometry/normal_cycle.h
+++ b/source/blender/freestyle/intern/geometry/normal_cycle.h
@@ -25,8 +25,7 @@
* FRANCE
*/
-#ifndef __MESH_TOOLS_MATH_NORMAL_CYCLE__
-#define __MESH_TOOLS_MATH_NORMAL_CYCLE__
+#pragma once
/** \file
* \ingroup freestyle
@@ -145,5 +144,3 @@ inline void NormalCycle::accumulate_dihedral_angle(const Vec3r &edge,
} // namespace OGF
} /* namespace Freestyle */
-
-#endif // __MESH_TOOLS_MATH_NORMAL_CYCLE__
diff --git a/source/blender/freestyle/intern/image/GaussianFilter.cpp b/source/blender/freestyle/intern/image/GaussianFilter.cpp
index 87e2caee8a9..ca476bee0d3 100644
--- a/source/blender/freestyle/intern/image/GaussianFilter.cpp
+++ b/source/blender/freestyle/intern/image/GaussianFilter.cpp
@@ -55,9 +55,7 @@ GaussianFilter &GaussianFilter::operator=(const GaussianFilter &iBrother)
GaussianFilter::~GaussianFilter()
{
- if (0 != _mask) {
- delete[] _mask;
- }
+ delete[] _mask;
}
int GaussianFilter::computeMaskSize(float sigma)
@@ -78,9 +76,7 @@ void GaussianFilter::setSigma(float sigma)
void GaussianFilter::computeMask()
{
- if (0 != _mask) {
- delete[] _mask;
- }
+ delete[] _mask;
_maskSize = computeMaskSize(_sigma);
_storedMaskSize = (_maskSize + 1) >> 1;
diff --git a/source/blender/freestyle/intern/image/GaussianFilter.h b/source/blender/freestyle/intern/image/GaussianFilter.h
index 625e357eddf..ff765e619a8 100644
--- a/source/blender/freestyle/intern/image/GaussianFilter.h
+++ b/source/blender/freestyle/intern/image/GaussianFilter.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __GAUSSIANFILTER_H__
-#define __GAUSSIANFILTER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -151,5 +150,3 @@ template<class Map> float GaussianFilter::getSmoothedPixel(Map *map, int x, int
}
} /* namespace Freestyle */
-
-#endif // __GAUSSIANFILTER_H__
diff --git a/source/blender/freestyle/intern/image/Image.h b/source/blender/freestyle/intern/image/Image.h
index c42e47a670b..385e243a1a2 100644
--- a/source/blender/freestyle/intern/image/Image.h
+++ b/source/blender/freestyle/intern/image/Image.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __IMAGE_H__
-#define __IMAGE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -394,7 +393,7 @@ class GrayImage : public FrsImage {
/*! Sets the array.
* copy
- * If true, the array is copie, otherwise the pounsigneder is copied
+ * If true, the array is copied, otherwise the pounsigneder is copied
*/
void setArray(float *lvl,
unsigned width,
@@ -430,5 +429,3 @@ class GrayImage : public FrsImage {
};
} /* namespace Freestyle */
-
-#endif // __IMAGE_H__
diff --git a/source/blender/freestyle/intern/image/ImagePyramid.h b/source/blender/freestyle/intern/image/ImagePyramid.h
index 8c6a8bcdff4..ee8bf69aa10 100644
--- a/source/blender/freestyle/intern/image/ImagePyramid.h
+++ b/source/blender/freestyle/intern/image/ImagePyramid.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __IMAGEPYRAMID_H__
-#define __IMAGEPYRAMID_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -113,5 +112,3 @@ class GaussianPyramid : public ImagePyramid {
};
} /* namespace Freestyle */
-
-#endif // __IMAGEPYRAMID_H__
diff --git a/source/blender/freestyle/intern/python/BPy_BBox.h b/source/blender/freestyle/intern/python/BPy_BBox.h
index 84542dc6d1c..a284deed10c 100644
--- a/source/blender/freestyle/intern/python/BPy_BBox.h
+++ b/source/blender/freestyle/intern/python/BPy_BBox.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_BBOX_H__
-#define __FREESTYLE_PYTHON_BBOX_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -55,5 +54,3 @@ int BBox_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_BBOX_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp
index a631b45f6d4..42b13bf4920 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp
@@ -84,9 +84,8 @@ static int BinaryPredicate0D___init__(BPy_BinaryPredicate0D *self, PyObject *arg
static void BinaryPredicate0D___dealloc__(BPy_BinaryPredicate0D *self)
{
- if (self->bp0D) {
- delete self->bp0D;
- }
+ delete self->bp0D;
+
Py_TYPE(self)->tp_free((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h
index 3d0575a676c..cdf81f3e4fc 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_BINARYPREDICATE0D_H__
-#define __FREESTYLE_PYTHON_BINARYPREDICATE0D_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -54,5 +53,3 @@ int BinaryPredicate0D_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_BINARYPREDICATE0D_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp
index 9add706bea7..ed991695739 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp
@@ -120,9 +120,7 @@ static int BinaryPredicate1D___init__(BPy_BinaryPredicate1D *self, PyObject *arg
static void BinaryPredicate1D___dealloc__(BPy_BinaryPredicate1D *self)
{
- if (self->bp1D) {
- delete self->bp1D;
- }
+ delete self->bp1D;
Py_TYPE(self)->tp_free((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h
index b258f293694..b761f6f6ace 100644
--- a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h
+++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_BINARYPREDICATE1D_H__
-#define __FREESTYLE_PYTHON_BINARYPREDICATE1D_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -54,5 +53,3 @@ int BinaryPredicate1D_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_BINARYPREDICATE1D_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_ContextFunctions.h b/source/blender/freestyle/intern/python/BPy_ContextFunctions.h
index 674023fa008..4cc04379f18 100644
--- a/source/blender/freestyle/intern/python/BPy_ContextFunctions.h
+++ b/source/blender/freestyle/intern/python/BPy_ContextFunctions.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CONTEXTFUNCTIONS_H__
-#define __FREESTYLE_PYTHON_CONTEXTFUNCTIONS_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -36,5 +35,3 @@ int ContextFunctions_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CONTEXTFUNCTIONS_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_Convert.h b/source/blender/freestyle/intern/python/BPy_Convert.h
index 19e0879beff..5a1c11ec086 100644
--- a/source/blender/freestyle/intern/python/BPy_Convert.h
+++ b/source/blender/freestyle/intern/python/BPy_Convert.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CONVERT_H__
-#define __FREESTYLE_PYTHON_CONVERT_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -177,5 +176,3 @@ int convert_v2(PyObject *obj, void *v);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CONVERT_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
index 33078e6ba6a..9796dcda964 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
@@ -264,7 +264,7 @@ static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject *
return NULL;
}
cumap = (CurveMapping *)py_srna->ptr.data;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
/* disable extrapolation if enabled */
if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE)) {
cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.h b/source/blender/freestyle/intern/python/BPy_Freestyle.h
index a3a482be9ee..f63eb0d8466 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.h
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FREESTYLE_H__
-#define __FREESTYLE_PYTHON_FREESTYLE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -38,5 +37,3 @@ PyObject *Freestyle_Init(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FREESTYLE_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
index 2c226e330d7..3c2f022adb6 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
+++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
@@ -108,7 +108,7 @@ static int FrsMaterial_init(BPy_FrsMaterial *self, PyObject *args, PyObject *kwd
self->m = new FrsMaterial(*m);
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O&O&O&O&O&fi",
diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.h b/source/blender/freestyle/intern/python/BPy_FrsMaterial.h
index 84a3ac2463f..13a116d7ef2 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.h
+++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FRSMATERIAL_H__
-#define __FREESTYLE_PYTHON_FRSMATERIAL_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -55,5 +54,3 @@ void FrsMaterial_mathutils_register_callback();
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FRSMATERIAL_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_FrsNoise.h b/source/blender/freestyle/intern/python/BPy_FrsNoise.h
index 9dcf59779cf..09bcc82ae94 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsNoise.h
+++ b/source/blender/freestyle/intern/python/BPy_FrsNoise.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FRSNOISE_H__
-#define __FREESTYLE_PYTHON_FRSNOISE_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -55,5 +54,3 @@ int FrsNoise_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FRSNOISE_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_Id.cpp b/source/blender/freestyle/intern/python/BPy_Id.cpp
index 4f61ba847f6..eb0eb661e3d 100644
--- a/source/blender/freestyle/intern/python/BPy_Id.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Id.cpp
@@ -75,7 +75,7 @@ static int Id_init(BPy_Id *self, PyObject *args, PyObject *kwds)
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_1, &Id_Type, &brother)) {
self->id = new Id(*(((BPy_Id *)brother)->id));
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "|ii", (char **)kwlist_2, &first, &second)) {
self->id = new Id(first, second);
}
diff --git a/source/blender/freestyle/intern/python/BPy_Id.h b/source/blender/freestyle/intern/python/BPy_Id.h
index 3544f751453..f5952297c66 100644
--- a/source/blender/freestyle/intern/python/BPy_Id.h
+++ b/source/blender/freestyle/intern/python/BPy_Id.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_ID_H__
-#define __FREESTYLE_PYTHON_ID_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -57,5 +56,3 @@ int Id_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_ID_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.h b/source/blender/freestyle/intern/python/BPy_IntegrationType.h
index 525feb002e4..be815c6c95a 100644
--- a/source/blender/freestyle/intern/python/BPy_IntegrationType.h
+++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_INTEGRATIONTYPE_H__
-#define __FREESTYLE_PYTHON_INTEGRATIONTYPE_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -49,5 +48,3 @@ int IntegrationType_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_INTEGRATIONTYPE_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_Interface0D.h b/source/blender/freestyle/intern/python/BPy_Interface0D.h
index 81fdd40ff04..7e41a8888e1 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface0D.h
+++ b/source/blender/freestyle/intern/python/BPy_Interface0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_INTERFACE0D_H__
-#define __FREESTYLE_PYTHON_INTERFACE0D_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -55,5 +54,3 @@ int Interface0D_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_INTERFACE0D_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_Interface1D.h b/source/blender/freestyle/intern/python/BPy_Interface1D.h
index db9bfa7f79c..20a4af0b4d0 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface1D.h
+++ b/source/blender/freestyle/intern/python/BPy_Interface1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_INTERFACE1D_H__
-#define __FREESTYLE_PYTHON_INTERFACE1D_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -55,5 +54,3 @@ int Interface1D_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_INTERFACE1D_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_Iterator.cpp b/source/blender/freestyle/intern/python/BPy_Iterator.cpp
index 6e00a05b969..b8dedb6497a 100644
--- a/source/blender/freestyle/intern/python/BPy_Iterator.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Iterator.cpp
@@ -137,9 +137,7 @@ static int Iterator_init(BPy_Iterator *self, PyObject *args, PyObject *kwds)
static void Iterator_dealloc(BPy_Iterator *self)
{
- if (self->it) {
- delete self->it;
- }
+ delete self->it;
Py_TYPE(self)->tp_free((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/BPy_Iterator.h b/source/blender/freestyle/intern/python/BPy_Iterator.h
index f9f80c5f1db..5d1e8422976 100644
--- a/source/blender/freestyle/intern/python/BPy_Iterator.h
+++ b/source/blender/freestyle/intern/python/BPy_Iterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_ITERATOR_H__
-#define __FREESTYLE_PYTHON_ITERATOR_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -53,5 +52,3 @@ int Iterator_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_ITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_MediumType.h b/source/blender/freestyle/intern/python/BPy_MediumType.h
index 5c91890c249..854f826291e 100644
--- a/source/blender/freestyle/intern/python/BPy_MediumType.h
+++ b/source/blender/freestyle/intern/python/BPy_MediumType.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_MEDIUMTYPE_H__
-#define __FREESTYLE_PYTHON_MEDIUMTYPE_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -62,5 +61,3 @@ extern PyLongObject _BPy_MediumType_OPAQUE_MEDIUM;
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_MEDIUMTYPE_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_Nature.h b/source/blender/freestyle/intern/python/BPy_Nature.h
index 8eb33f02488..48d15c8e796 100644
--- a/source/blender/freestyle/intern/python/BPy_Nature.h
+++ b/source/blender/freestyle/intern/python/BPy_Nature.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_NATURE_H__
-#define __FREESTYLE_PYTHON_NATURE_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -53,5 +52,3 @@ int Nature_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_NATURE_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_Operators.cpp b/source/blender/freestyle/intern/python/BPy_Operators.cpp
index 510e823ba55..56f95b8ecbb 100644
--- a/source/blender/freestyle/intern/python/BPy_Operators.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Operators.cpp
@@ -365,8 +365,8 @@ static PyObject *Operators_sequential_split(BPy_Operators * /*self*/,
return NULL;
}
}
- else if (PyErr_Clear(),
- (f = 0.0f),
+ else if ((void)PyErr_Clear(),
+ (void)(f = 0.0f),
PyArg_ParseTupleAndKeywords(
args, kwds, "O!|f", (char **)kwlist_2, &UnaryPredicate0D_Type, &obj1, &f)) {
if (!((BPy_UnaryPredicate0D *)obj1)->up0D) {
@@ -484,8 +484,8 @@ static PyObject *Operators_recursive_split(BPy_Operators * /*self*/,
return NULL;
}
}
- else if (PyErr_Clear(),
- (f = 0.0f),
+ else if ((void)PyErr_Clear(),
+ (void)(f = 0.0f),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!O!|f",
diff --git a/source/blender/freestyle/intern/python/BPy_Operators.h b/source/blender/freestyle/intern/python/BPy_Operators.h
index 15797ca742e..3b060d63f3c 100644
--- a/source/blender/freestyle/intern/python/BPy_Operators.h
+++ b/source/blender/freestyle/intern/python/BPy_Operators.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_OPERATORS_H__
-#define __FREESTYLE_PYTHON_OPERATORS_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -53,5 +52,3 @@ int Operators_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_OPERATORS_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_SShape.h b/source/blender/freestyle/intern/python/BPy_SShape.h
index 55ef11b9a0b..9741a10f69e 100644
--- a/source/blender/freestyle/intern/python/BPy_SShape.h
+++ b/source/blender/freestyle/intern/python/BPy_SShape.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_SSHAPE_H__
-#define __FREESTYLE_PYTHON_SSHAPE_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -54,5 +53,3 @@ int SShape_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_SSHAPE_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
index 5f5407e82e3..214385f74ad 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
@@ -110,7 +110,7 @@ static int StrokeAttribute_init(BPy_StrokeAttribute *self, PyObject *args, PyObj
self->sa = new StrokeAttribute(*(((BPy_StrokeAttribute *)obj1)->sa));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!f",
@@ -123,7 +123,7 @@ static int StrokeAttribute_init(BPy_StrokeAttribute *self, PyObject *args, PyObj
self->sa = new StrokeAttribute(
*(((BPy_StrokeAttribute *)obj1)->sa), *(((BPy_StrokeAttribute *)obj2)->sa), t);
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"ffffff",
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h
index 9e14c292c0a..9068eb4c7a3 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h
+++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_STROKEATTRIBUTE_H__
-#define __FREESTYLE_PYTHON_STROKEATTRIBUTE_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -56,5 +55,3 @@ void StrokeAttribute_mathutils_register_callback();
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_STROKEATTRIBUTE_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
index 993afc2e32e..5e5685153af 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp
@@ -210,9 +210,7 @@ static int StrokeShader___init__(BPy_StrokeShader *self, PyObject *args, PyObjec
static void StrokeShader___dealloc__(BPy_StrokeShader *self)
{
- if (self->ss) {
- delete self->ss;
- }
+ delete self->ss;
Py_TYPE(self)->tp_free((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.h b/source/blender/freestyle/intern/python/BPy_StrokeShader.h
index 23b1196fdb9..04fff8e8052 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeShader.h
+++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_STROKESHADER_H__
-#define __FREESTYLE_PYTHON_STROKESHADER_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -58,5 +57,3 @@ int StrokeShader_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_STROKESHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h
index c0834859dc8..1319cabe94a 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0D_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0D_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -54,5 +53,3 @@ int UnaryFunction0D_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0D_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h
index dfd0e56beb6..331c3b4aaa1 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1D_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION1D_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -54,5 +53,3 @@ int UnaryFunction1D_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION1D_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp
index 3d4191c2c44..ddbb55fdb4d 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp
@@ -97,9 +97,7 @@ static int UnaryPredicate0D___init__(BPy_UnaryPredicate0D *self, PyObject *args,
static void UnaryPredicate0D___dealloc__(BPy_UnaryPredicate0D *self)
{
- if (self->up0D) {
- delete self->up0D;
- }
+ delete self->up0D;
Py_TYPE(self)->tp_free((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h
index d422b10f18e..2460b1f028b 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYPREDICATE0D_H__
-#define __FREESTYLE_PYTHON_UNARYPREDICATE0D_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -54,5 +53,3 @@ int UnaryPredicate0D_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYPREDICATE0D_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp
index ba68d21f941..11e77fa365a 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp
@@ -155,9 +155,7 @@ static int UnaryPredicate1D___init__(BPy_UnaryPredicate1D *self, PyObject *args,
static void UnaryPredicate1D___dealloc__(BPy_UnaryPredicate1D *self)
{
- if (self->up1D) {
- delete self->up1D;
- }
+ delete self->up1D;
Py_TYPE(self)->tp_free((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h
index 22358fab525..8fad7f94caf 100644
--- a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h
+++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYPREDICATE1D_H__
-#define __FREESTYLE_PYTHON_UNARYPREDICATE1D_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -54,5 +53,3 @@ int UnaryPredicate1D_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYPREDICATE1D_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_ViewMap.cpp b/source/blender/freestyle/intern/python/BPy_ViewMap.cpp
index b7b425abe23..67a4249ade8 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewMap.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ViewMap.cpp
@@ -69,9 +69,7 @@ static int ViewMap_init(BPy_ViewMap *self, PyObject *args, PyObject *kwds)
static void ViewMap_dealloc(BPy_ViewMap *self)
{
- if (self->vm) {
- delete self->vm;
- }
+ delete self->vm;
Py_TYPE(self)->tp_free((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/BPy_ViewMap.h b/source/blender/freestyle/intern/python/BPy_ViewMap.h
index fe1cd39deb3..59738b6dce9 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewMap.h
+++ b/source/blender/freestyle/intern/python/BPy_ViewMap.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_VIEWMAP_H__
-#define __FREESTYLE_PYTHON_VIEWMAP_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -53,5 +52,3 @@ int ViewMap_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_VIEWMAP_H__ */
diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
index f59ae15ae01..2adcae13e6d 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
@@ -88,7 +88,7 @@ static int ViewShape_init(BPy_ViewShape *self, PyObject *args, PyObject *kwds)
self->py_ss = ((BPy_ViewShape *)obj)->py_ss;
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &SShape_Type, &obj)) {
BPy_SShape *py_ss = (BPy_SShape *)obj;
self->vs = new ViewShape(py_ss->ss);
diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.h b/source/blender/freestyle/intern/python/BPy_ViewShape.h
index 3158353136f..bd51fd0d5cb 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewShape.h
+++ b/source/blender/freestyle/intern/python/BPy_ViewShape.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_VIEWSHAPE_H__
-#define __FREESTYLE_PYTHON_VIEWSHAPE_H__
+#pragma once
extern "C" {
#include <Python.h>
@@ -57,5 +56,3 @@ int ViewShape_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_VIEWSHAPE_H__ */
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h
index abb9eca9b30..6d741400caa 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FALSEBP1D_H__
-#define __FREESTYLE_PYTHON_FALSEBP1D_H__
+#pragma once
#include "../BPy_BinaryPredicate1D.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FALSEBP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h
index 6ad2373c570..755da249855 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_LENGTH2DBP1D_H__
-#define __FREESTYLE_PYTHON_LENGTH2DBP1D_H__
+#pragma once
#include "../BPy_BinaryPredicate1D.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_LENGTH2DBP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h
index 75fc5eaa271..08326706a53 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_SAMESHAPEIDBP1D_H__
-#define __FREESTYLE_PYTHON_SAMESHAPEIDBP1D_H__
+#pragma once
#include "../BPy_BinaryPredicate1D.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_SAMESHAPEIDBP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h
index ed6a783fa47..76f3487d7db 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_TRUEBP1D_H__
-#define __FREESTYLE_PYTHON_TRUEBP1D_H__
+#pragma once
#include "../BPy_BinaryPredicate1D.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_TRUEBP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h
index 1a451a688fb..b9ce88773a8 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_VIEWMAPGRADIENTNORMBP1D_H__
-#define __FREESTYLE_PYTHON_VIEWMAPGRADIENTNORMBP1D_H__
+#pragma once
#include "../BPy_BinaryPredicate1D.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_VIEWMAPGRADIENTNORMBP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/Director.h b/source/blender/freestyle/intern/python/Director.h
index 5c087e411ff..468150524f1 100644
--- a/source/blender/freestyle/intern/python/Director.h
+++ b/source/blender/freestyle/intern/python/Director.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_DIRECTOR_H__
-#define __FREESTYLE_PYTHON_DIRECTOR_H__
+#pragma once
namespace Freestyle {
class UnaryPredicate0D;
@@ -63,5 +62,3 @@ int Director_BPy_StrokeShader_shade(StrokeShader *ss, Stroke &s);
// ChainingIterator: init, traverse
int Director_BPy_ChainingIterator_init(ChainingIterator *c_it);
int Director_BPy_ChainingIterator_traverse(ChainingIterator *c_it, AdjacencyIterator &a_it);
-
-#endif // __FREESTYLE_PYTHON_DIRECTOR_H__
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
index 6af80c4bfd9..81dd79ff270 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
@@ -95,7 +95,7 @@ static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds)
self->cp = new CurvePoint(*(((BPy_CurvePoint *)obj1)->cp));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!f",
@@ -107,7 +107,7 @@ static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds)
&t2d)) {
self->cp = new CurvePoint(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv, t2d);
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!f",
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h
index d0f4087f8a6..6a550085817 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CURVEPOINT_H__
-#define __FREESTYLE_PYTHON_CURVEPOINT_H__
+#pragma once
#include "../BPy_Interface0D.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CURVEPOINT_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
index 71a87c2c01e..c01f1f17000 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
@@ -72,7 +72,7 @@ static int SVertex_init(BPy_SVertex *self, PyObject *args, PyObject *kwds)
self->sv = new SVertex(*(((BPy_SVertex *)obj)->sv));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "O&O!", (char **)kwlist_2, convert_v3, v, &Id_Type, &obj)) {
Vec3r point_3d(v[0], v[1], v[2]);
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h
index 20a14f1422c..8d24576a98f 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_SVERTEX_H__
-#define __FREESTYLE_PYTHON_SVERTEX_H__
+#pragma once
#include "../BPy_Interface0D.h"
@@ -50,5 +49,3 @@ void SVertex_mathutils_register_callback();
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_SVERTEX_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h
index 6769efa4673..cb9815fb3d4 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_VIEWVERTEX_H__
-#define __FREESTYLE_PYTHON_VIEWVERTEX_H__
+#pragma once
#include "../BPy_Interface0D.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_VIEWVERTEX_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
index b4c08714af0..519bd72db3b 100644
--- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
@@ -107,7 +107,7 @@ static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *k
self->sv = new StrokeVertex(*(((BPy_StrokeVertex *)obj1)->sv));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!f",
@@ -129,7 +129,7 @@ static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *k
}
self->sv = new StrokeVertex(sv1, sv2, t3d);
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "O!", (char **)kwlist_3, &CurvePoint_Type, &obj1)) {
CurvePoint *cp = ((BPy_CurvePoint *)obj1)->cp;
@@ -139,8 +139,8 @@ static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *k
}
self->sv = new StrokeVertex(cp);
}
- else if (PyErr_Clear(),
- (obj2 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj2 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!|O!",
diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h
index e2eab6ab887..44da0ed212a 100644
--- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_STROKEVERTEX_H__
-#define __FREESTYLE_PYTHON_STROKEVERTEX_H__
+#pragma once
#include "../BPy_CurvePoint.h"
@@ -51,5 +50,3 @@ void StrokeVertex_mathutils_register_callback();
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_STROKEVERTEX_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h
index fdea985a125..43f2c2b4a5c 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_NONTVERTEX_H__
-#define __FREESTYLE_PYTHON_NONTVERTEX_H__
+#pragma once
#include "../BPy_ViewVertex.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_NONTVERTEX_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h
index 165ad976fdf..253934bb4e7 100644
--- a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h
+++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_TVERTEX_H__
-#define __FREESTYLE_PYTHON_TVERTEX_H__
+#pragma once
#include "../BPy_ViewVertex.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_TVERTEX_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
index 8a09e7722ea..187ab94360a 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
@@ -81,7 +81,7 @@ static int FEdge_init(BPy_FEdge *self, PyObject *args, PyObject *kwds)
self->fe = new FEdge(*(((BPy_FEdge *)obj1)->fe));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!",
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h
index 3ab8c5f8273..25b1bc99860 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FEDGE_H__
-#define __FREESTYLE_PYTHON_FEDGE_H__
+#pragma once
#include "../BPy_Interface1D.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FEDGE_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
index fd434f9c4ef..788dfa78992 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
@@ -72,7 +72,7 @@ static int FrsCurve_init(BPy_FrsCurve *self, PyObject *args, PyObject *kwds)
self->c = new Curve(*(((BPy_FrsCurve *)obj)->c));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &Id_Type, &obj)) {
self->c = new Curve(*(((BPy_Id *)obj)->id));
}
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h
index aa4fb409076..9bdc3919a38 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FRSCURVE_H__
-#define __FREESTYLE_PYTHON_FRSCURVE_H__
+#pragma once
#include "../BPy_Interface1D.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FRSCURVE_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
index 3a25ddb0252..b31efe1f923 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
@@ -157,7 +157,8 @@ static PyObject *Stroke_resample(BPy_Stroke *self, PyObject *args, PyObject *kwd
return NULL;
}
}
- else if (PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &f)) {
+ else if ((void)PyErr_Clear(),
+ PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &f)) {
if (self->s->Resample(f) < 0) {
PyErr_SetString(PyExc_RuntimeError, "Stroke resampling (by vertex interval) failed");
return NULL;
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h
index a08905e6043..33c6aa70f91 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_STROKE_H__
-#define __FREESTYLE_PYTHON_STROKE_H__
+#pragma once
#include "../BPy_Interface1D.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_STROKE_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h
index c02d5d0f21b..519081cedbd 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_VIEWEDGE_H__
-#define __FREESTYLE_PYTHON_VIEWEDGE_H__
+#pragma once
#include "../BPy_Interface1D.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_VIEWEDGE_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
index 285100193d3..9cdc344081e 100644
--- a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
@@ -71,7 +71,7 @@ static int Chain_init(BPy_Chain *self, PyObject *args, PyObject *kwds)
self->c = new Chain(*(((BPy_Chain *)obj)->c));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &Id_Type, &obj)) {
self->c = new Chain(*(((BPy_Id *)obj)->id));
}
diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h
index a9392cd81bf..73da253688c 100644
--- a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h
+++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CHAIN_H__
-#define __FREESTYLE_PYTHON_CHAIN_H__
+#pragma once
#include "../BPy_FrsCurve.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CHAIN_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
index 725daa80b5e..5db75c84608 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
@@ -75,7 +75,7 @@ static int FEdgeSharp_init(BPy_FEdgeSharp *self, PyObject *args, PyObject *kwds)
self->fes = new FEdgeSharp(*(((BPy_FEdgeSharp *)obj1)->fes));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!",
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h
index 450539acb16..2b8b09a5990 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FEDGESHARP_H__
-#define __FREESTYLE_PYTHON_FEDGESHARP_H__
+#pragma once
#include "../BPy_FEdge.h"
@@ -50,5 +49,3 @@ void FEdgeSharp_mathutils_register_callback();
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FEDGESHARP_H__ */
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
index 65d9dcbe01f..3fb739b18db 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
@@ -73,7 +73,7 @@ static int FEdgeSmooth_init(BPy_FEdgeSmooth *self, PyObject *args, PyObject *kwd
self->fes = new FEdgeSmooth(*(((BPy_FEdgeSmooth *)obj1)->fes));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!",
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h
index 901741a76ff..97497281310 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FEDGESMOOTH_H__
-#define __FREESTYLE_PYTHON_FEDGESMOOTH_H__
+#pragma once
#include "../BPy_FEdge.h"
@@ -51,5 +50,3 @@ void FEdgeSmooth_mathutils_register_callback();
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FEDGESMOOTH_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
index 74ae7809284..90e751333b9 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
@@ -82,8 +82,8 @@ static int AdjacencyIterator_init(BPy_AdjacencyIterator *self, PyObject *args, P
self->at_start = ((BPy_AdjacencyIterator *)obj1)->at_start;
}
}
- else if (PyErr_Clear(),
- (obj2 = obj3 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj2 = obj3 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!|O!O!",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h
index 9a360f23f0a..e5332e0d180 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_ADJACENCYITERATOR_H__
-#define __FREESTYLE_PYTHON_ADJACENCYITERATOR_H__
+#pragma once
#include "../BPy_Iterator.h"
@@ -48,5 +47,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_ADJACENCYITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
index 164e1646934..1703fc2bddb 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
@@ -114,8 +114,8 @@ static int ChainPredicateIterator_init(BPy_ChainPredicateIterator *self,
Py_INCREF(self->upred);
Py_INCREF(self->bpred);
}
- else if (PyErr_Clear(),
- (obj3 = obj4 = obj5 = obj6 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj3 = obj4 = obj5 = obj6 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!|O!O!O&O!",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h
index 645e6573257..ece8018d285 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CHAINPREDICATEITERATOR_H__
-#define __FREESTYLE_PYTHON_CHAINPREDICATEITERATOR_H__
+#pragma once
#include "BPy_ChainingIterator.h"
@@ -49,5 +48,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CHAINPREDICATEITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
index 401959be0c0..d8ad82d667c 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
@@ -91,8 +91,8 @@ static int ChainSilhouetteIterator_init(BPy_ChainSilhouetteIterator *self,
args, kwds, "O!", (char **)kwlist_1, &ChainSilhouetteIterator_Type, &obj1)) {
self->cs_it = new ChainSilhouetteIterator(*(((BPy_ChainSilhouetteIterator *)obj1)->cs_it));
}
- else if (PyErr_Clear(),
- (obj1 = obj2 = obj3 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj1 = obj2 = obj3 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"|O!O&O!",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h
index 72823832441..f91d0fb2585 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CHAINSILHOUETTEITERATOR_H__
-#define __FREESTYLE_PYTHON_CHAINSILHOUETTEITERATOR_H__
+#pragma once
#include "BPy_ChainingIterator.h"
@@ -47,5 +46,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CHAINSILHOUETTEITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
index b6d841c5b64..dbd6e8dd09d 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
@@ -91,8 +91,8 @@ static int ChainingIterator___init__(BPy_ChainingIterator *self, PyObject *args,
args, kwds, "O!", (char **)kwlist_1, &ChainingIterator_Type, &obj1)) {
self->c_it = new ChainingIterator(*(((BPy_ChainingIterator *)obj1)->c_it));
}
- else if (PyErr_Clear(),
- (obj1 = obj2 = obj3 = obj4 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj1 = obj2 = obj3 = obj4 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"|O!O!O&O!",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h
index 7e3be0bc6cd..e950824764c 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CHAININGITERATOR_H__
-#define __FREESTYLE_PYTHON_CHAININGITERATOR_H__
+#pragma once
#include "BPy_ViewEdgeIterator.h"
@@ -47,5 +46,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CHAININGITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
index 6ea61a060cb..6c496b0308b 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
@@ -75,7 +75,8 @@ static int CurvePointIterator_init(BPy_CurvePointIterator *self, PyObject *args,
*(((BPy_CurvePointIterator *)brother)->cp_it));
}
}
- else if (PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &step)) {
+ else if ((void)PyErr_Clear(),
+ PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &step)) {
self->cp_it = new CurveInternal::CurvePointIterator(step);
}
else {
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h
index aa84b1020ce..db36bf386ec 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CURVEPOINTITERATOR_H__
-#define __FREESTYLE_PYTHON_CURVEPOINTITERATOR_H__
+#pragma once
#include "../BPy_Iterator.h"
@@ -47,5 +46,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CURVEPOINTITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
index 0dbef9f325c..f0d6acf461b 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
@@ -81,14 +81,14 @@ static int Interface0DIterator_init(BPy_Interface0DIterator *self, PyObject *arg
self->at_start = true;
self->reversed = false;
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "O!", (char **)kwlist_2, &Interface1D_Type, &inter)) {
self->if0D_it = new Interface0DIterator(((BPy_Interface1D *)inter)->if1D->verticesBegin());
self->at_start = true;
self->reversed = false;
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "O!", (char **)kwlist_3, &Interface0DIterator_Type, &brother)) {
self->if0D_it = new Interface0DIterator(*(((BPy_Interface0DIterator *)brother)->if0D_it));
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h
index 3695cda6c76..663193bedee 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_INTERFACE0DITERATOR_H__
-#define __FREESTYLE_PYTHON_INTERFACE0DITERATOR_H__
+#pragma once
#include "../BPy_Iterator.h"
@@ -49,5 +48,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_INTERFACE0DITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
index dd738b97473..4a5927ff6eb 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
@@ -82,7 +82,7 @@ static int SVertexIterator_init(BPy_SVertexIterator *self, PyObject *args, PyObj
self->sv_it = new ViewEdgeInternal::SVertexIterator(*(((BPy_SVertexIterator *)obj1)->sv_it));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!O!O!f",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h
index 2a3bfa6baf9..a34dc7a63c5 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_SVERTEXITERATOR_H__
-#define __FREESTYLE_PYTHON_SVERTEXITERATOR_H__
+#pragma once
#include "../BPy_Iterator.h"
@@ -47,5 +46,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_SVERTEXITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
index 84f57f1fe31..df03ecba96f 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
@@ -74,7 +74,7 @@ static int StrokeVertexIterator_init(BPy_StrokeVertexIterator *self,
self->at_start = ((BPy_StrokeVertexIterator *)brother)->at_start;
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "|O!", (char **)kwlist_2, &Stroke_Type, &stroke)) {
if (!stroke) {
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h
index 04bca16337d..629471a664c 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_STROKEVERTEXITERATOR_H__
-#define __FREESTYLE_PYTHON_STROKEVERTEXITERATOR_H__
+#pragma once
#include "../BPy_Iterator.h"
@@ -50,5 +49,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_STROKEVERTEXITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
index c8a978784a4..3d0ed5d5a4d 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
@@ -78,8 +78,8 @@ static int ViewEdgeIterator_init(BPy_ViewEdgeIterator *self, PyObject *args, PyO
args, kwds, "O!", (char **)kwlist_1, &ViewEdgeIterator_Type, &obj1)) {
self->ve_it = new ViewEdgeInternal::ViewEdgeIterator(*(((BPy_ViewEdgeIterator *)obj1)->ve_it));
}
- else if (PyErr_Clear(),
- (obj1 = obj2 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj1 = obj2 = 0),
PyArg_ParseTupleAndKeywords(
args, kwds, "|O&O!", (char **)kwlist_2, check_begin, &obj1, &PyBool_Type, &obj2)) {
ViewEdge *begin = (!obj1 || obj1 == Py_None) ? NULL : ((BPy_ViewEdge *)obj1)->ve;
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h
index c9061d30e07..7169a13f328 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_VIEWEDGEITERATOR_H__
-#define __FREESTYLE_PYTHON_VIEWEDGEITERATOR_H__
+#pragma once
#include "../BPy_Iterator.h"
@@ -47,5 +46,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_VIEWEDGEITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h
index 179e315b1be..7a13f6d2c72 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_ORIENTEDVIEWEDGEITERATOR_H__
-#define __FREESTYLE_PYTHON_ORIENTEDVIEWEDGEITERATOR_H__
+#pragma once
#include "../BPy_Iterator.h"
@@ -49,5 +48,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_ORIENTEDVIEWEDGEITERATOR_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h
index c37d330e4a7..bd63b2fb337 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_BACKBONESTRETCHERSHADER_H__
-#define __FREESTYLE_PYTHON_BACKBONESTRETCHERSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_BACKBONESTRETCHERSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h
index b38fcec838d..a0b80b401ba 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_BEZIERCURVESHADER_H__
-#define __FREESTYLE_PYTHON_BEZIERCURVESHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_BEZIERCURVESHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h
index 35335ffc023..7147a542467 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_BLENDERTEXTURESHADER_H__
-#define __FREESTYLE_PYTHON_BLENDERTEXTURESHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_BLENDERTEXTURESHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h
index 35a94a1620d..b64e1b9376e 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CALLIGRAPHICSHADER_H__
-#define __FREESTYLE_PYTHON_CALLIGRAPHICSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CALLIGRAPHICSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h
index 054479d916d..ada3165eea9 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_COLORNOISESHADER_H__
-#define __FREESTYLE_PYTHON_COLORNOISESHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_COLORNOISESHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h
index 36b59e6493e..7f58ed53e96 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CONSTANTCOLORSHADER_H__
-#define __FREESTYLE_PYTHON_CONSTANTCOLORSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CONSTANTCOLORSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h
index 3a11ab9c9a0..9323e2b9143 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CONSTANTTHICKNESSSHADER_H__
-#define __FREESTYLE_PYTHON_CONSTANTTHICKNESSSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CONSTANTTHICKNESSSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h
index 04912499c04..e3946c4bedb 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CONSTRAINEDINCREASINGTHICKNESSSHADER_H__
-#define __FREESTYLE_PYTHON_CONSTRAINEDINCREASINGTHICKNESSSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CONSTRAINEDINCREASINGTHICKNESSSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h
index 217acbc4648..51fd37978d5 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GUIDINGLINESSHADER_H__
-#define __FREESTYLE_PYTHON_GUIDINGLINESSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GUIDINGLINESSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h
index d7d1d053efd..def647abcce 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_INCREASINGCOLORSHADER_H__
-#define __FREESTYLE_PYTHON_INCREASINGCOLORSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_INCREASINGCOLORSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h
index 28636263813..7ded1c81beb 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_INCREASINGTHICKNESSSHADER_H__
-#define __FREESTYLE_PYTHON_INCREASINGTHICKNESSSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_INCREASINGTHICKNESSSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h
index e44ca1caa51..c50b388965a 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_POLYGONALIZATIONSHADER_H__
-#define __FREESTYLE_PYTHON_POLYGONALIZATIONSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_POLYGONALIZATIONSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h
index 50dbae6916e..073c5e8df42 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_SAMPLINGSHADER_H__
-#define __FREESTYLE_PYTHON_SAMPLINGSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_SAMPLINGSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
index 51a0c670d75..9e2726061c3 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
@@ -35,9 +35,9 @@ static char SmoothingShader___doc__[] =
"\n"
"[Geometry shader]\n"
"\n"
- ".. method:: __init__(num_iterations=100, factor_point=0.1,\n"
- " factor_curvature=0.0, factor_curvature_difference=0.2,\n"
- " aniso_point=0.0, aniso_normal=0.0, aniso_curvature=0.0,\n"
+ ".. method:: __init__(num_iterations=100, factor_point=0.1, \\\n"
+ " factor_curvature=0.0, factor_curvature_difference=0.2, \\\n"
+ " aniso_point=0.0, aniso_normal=0.0, aniso_curvature=0.0, \\\n"
" carricature_factor=1.0)\n"
"\n"
" Builds a SmoothingShader object.\n"
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h
index 4b553d76770..fcd559b661d 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHONSMOOTHINGSHADER_H__
-#define __FREESTYLE_PYTHONSMOOTHINGSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHONSMOOTHINGSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h
index 7e5e644c46f..59e3e32d6cf 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_SPATIALNOISESHADER_H__
-#define __FREESTYLE_PYTHON_SPATIALNOISESHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_SPATIALNOISESHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
index d53ca139b2b..ef0ebfad883 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_STROKETEXTURESTEPSHADER_H__
-#define __FREESTYLE_PYTHON_STROKETEXTURESTEPSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -46,5 +45,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_STROKETEXTURESTEPSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h
index 1a42985b245..e18f60c033b 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_THICKNESSNOISESHADER_H__
-#define __FREESTYLE_PYTHON_THICKNESSNOISESHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_THICKNESSNOISESHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h
index a82be691c81..bc7c2a2f2f4 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_TIPREMOVERSHADER_H__
-#define __FREESTYLE_PYTHON_TIPREMOVERSHADER_H__
+#pragma once
#include "../BPy_StrokeShader.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_TIPREMOVERSHADER_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
index d1ea13c90a7..9ced91f6867 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp
@@ -145,9 +145,7 @@ static int UnaryFunction0DDouble___init__(BPy_UnaryFunction0DDouble *self,
static void UnaryFunction0DDouble___dealloc__(BPy_UnaryFunction0DDouble *self)
{
- if (self->uf0D_double) {
- delete self->uf0D_double;
- }
+ delete self->uf0D_double;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h
index 8abccd27591..60ebc646d74 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DDOUBLE_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DDOUBLE_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -48,5 +47,3 @@ int UnaryFunction0DDouble_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DDOUBLE_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp
index 00600c405ef..7520f647276 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp
@@ -83,9 +83,7 @@ static int UnaryFunction0DEdgeNature___init__(BPy_UnaryFunction0DEdgeNature *sel
static void UnaryFunction0DEdgeNature___dealloc__(BPy_UnaryFunction0DEdgeNature *self)
{
- if (self->uf0D_edgenature) {
- delete self->uf0D_edgenature;
- }
+ delete self->uf0D_edgenature;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h
index 5a92142c88a..9ce4b3bfd0b 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DEDGENATURE_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DEDGENATURE_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -50,5 +49,3 @@ int UnaryFunction0DEdgeNature_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DEDGENATURE_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp
index 3961bf58bc4..7ee0d9bd71d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp
@@ -121,9 +121,7 @@ static int UnaryFunction0DFloat___init__(BPy_UnaryFunction0DFloat *self,
static void UnaryFunction0DFloat___dealloc__(BPy_UnaryFunction0DFloat *self)
{
- if (self->uf0D_float) {
- delete self->uf0D_float;
- }
+ delete self->uf0D_float;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h
index 53dc88d0e21..fd221201d99 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DFLOAT_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DFLOAT_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -48,5 +47,3 @@ int UnaryFunction0DFloat_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DFLOAT_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp
index 86e902bafe4..9c0f833d8fa 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp
@@ -80,9 +80,7 @@ static int UnaryFunction0DId___init__(BPy_UnaryFunction0DId *self, PyObject *arg
static void UnaryFunction0DId___dealloc__(BPy_UnaryFunction0DId *self)
{
- if (self->uf0D_id) {
- delete self->uf0D_id;
- }
+ delete self->uf0D_id;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h
index a8887b081ce..14e5d48ce43 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DID_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DID_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -50,5 +49,3 @@ int UnaryFunction0DId_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DID_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp
index 551429add8b..95cdc1522ac 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp
@@ -82,9 +82,7 @@ static int UnaryFunction0DMaterial___init__(BPy_UnaryFunction0DMaterial *self,
static void UnaryFunction0DMaterial___dealloc__(BPy_UnaryFunction0DMaterial *self)
{
- if (self->uf0D_material) {
- delete self->uf0D_material;
- }
+ delete self->uf0D_material;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h
index 558719032f8..bbd53c409eb 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DMATERIAL_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DMATERIAL_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -50,5 +49,3 @@ int UnaryFunction0DMaterial_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DMATERIAL_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp
index 8721e820fee..17ddd9773d2 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp
@@ -83,9 +83,7 @@ static int UnaryFunction0DUnsigned___init__(BPy_UnaryFunction0DUnsigned *self,
static void UnaryFunction0DUnsigned___dealloc__(BPy_UnaryFunction0DUnsigned *self)
{
- if (self->uf0D_unsigned) {
- delete self->uf0D_unsigned;
- }
+ delete self->uf0D_unsigned;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h
index ac09b51eceb..1a466ffc673 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DUNSIGNED_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DUNSIGNED_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -48,5 +47,3 @@ int UnaryFunction0DUnsigned_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DUNSIGNED_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp
index 44a39af68dd..3ff73dca832 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp
@@ -89,9 +89,7 @@ static int UnaryFunction0DVec2f___init__(BPy_UnaryFunction0DVec2f *self,
static void UnaryFunction0DVec2f___dealloc__(BPy_UnaryFunction0DVec2f *self)
{
- if (self->uf0D_vec2f) {
- delete self->uf0D_vec2f;
- }
+ delete self->uf0D_vec2f;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h
index 1639e1a5356..6c3d5fc85cc 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DVEC2F_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DVEC2F_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -51,5 +50,3 @@ int UnaryFunction0DVec2f_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DVEC2F_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp
index 6a27fc6e140..afbd25df122 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp
@@ -82,9 +82,7 @@ static int UnaryFunction0DVec3f___init__(BPy_UnaryFunction0DVec3f *self,
static void UnaryFunction0DVec3f___dealloc__(BPy_UnaryFunction0DVec3f *self)
{
- if (self->uf0D_vec3f) {
- delete self->uf0D_vec3f;
- }
+ delete self->uf0D_vec3f;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h
index 0f3bcc51f2e..4be9b170311 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DVEC3F_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DVEC3F_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -51,5 +50,3 @@ int UnaryFunction0DVec3f_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DVEC3F_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
index 88c050e243e..4fd6d949974 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
@@ -84,9 +84,7 @@ static int UnaryFunction0DVectorViewShape___init__(BPy_UnaryFunction0DVectorView
static void UnaryFunction0DVectorViewShape___dealloc__(BPy_UnaryFunction0DVectorViewShape *self)
{
- if (self->uf0D_vectorviewshape) {
- delete self->uf0D_vectorviewshape;
- }
+ delete self->uf0D_vectorviewshape;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h
index 4f559a09ba9..2a36ae21002 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DVECTORVIEWSHAPE_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DVECTORVIEWSHAPE_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -53,5 +52,3 @@ int UnaryFunction0DVectorViewShape_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DVECTORVIEWSHAPE_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp
index 11f4e114342..0f623b0e765 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp
@@ -90,9 +90,7 @@ static int UnaryFunction0DViewShape___init__(BPy_UnaryFunction0DViewShape *self,
static void UnaryFunction0DViewShape___dealloc__(BPy_UnaryFunction0DViewShape *self)
{
- if (self->uf0D_viewshape) {
- delete self->uf0D_viewshape;
- }
+ delete self->uf0D_viewshape;
UnaryFunction0D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h
index af3661669bd..8a8dcdceb1f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION0DVIEWSHAPE_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION0DVIEWSHAPE_H__
+#pragma once
#include "../BPy_UnaryFunction0D.h"
@@ -50,5 +49,3 @@ int UnaryFunction0DViewShape_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION0DVIEWSHAPE_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h
index 1aea0736c9b..ce4b448df03 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_SHAPEIDF0D_H__
-#define __FREESTYLE_PYTHON_SHAPEIDF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DId.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_SHAPEIDF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h
index f1520fa63ee..b569b9e1e81 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_MATERIALF0D_H__
-#define __FREESTYLE_PYTHON_MATERIALF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DMaterial.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_MATERIALF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h
index f24e63d09f9..5e29845c6b9 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CURVENATUREF0D_H__
-#define __FREESTYLE_PYTHON_CURVENATUREF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DEdgeNature.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CURVENATUREF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h
index 45a4ec3124d..c9b10412f34 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_NORMAL2DF0D_H__
-#define __FREESTYLE_PYTHON_NORMAL2DF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DVec2f.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_NORMAL2DF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h
index 8e76c31ff27..036bc82b52a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_VERTEXORIENTATION2DF0D_H__
-#define __FREESTYLE_PYTHON_VERTEXORIENTATION2DF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DVec2f.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_VERTEXORIENTATION2DF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h
index 391f7c9536b..c99c344d470 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_VERTEXORIENTATION3DF0D_H__
-#define __FREESTYLE_PYTHON_VERTEXORIENTATION3DF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DVec3f.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_VERTEXORIENTATION3DF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h
index 45c9524e185..20ca0499a1e 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETOCCLUDEEF0D_H__
-#define __FREESTYLE_PYTHON_GETOCCLUDEEF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DViewShape.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETOCCLUDEEF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h
index c1db8c1219a..4e6dd6b9f60 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETSHAPEF0D_H__
-#define __FREESTYLE_PYTHON_GETSHAPEF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DViewShape.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETSHAPEF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h
index b57119257b9..6fcafef8143 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CURVATURE2DANGLEF0D_H__
-#define __FREESTYLE_PYTHON_CURVATURE2DANGLEF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CURVATURE2DANGLEF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h
index 34bbd8331fb..8df2f67aff3 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_DENSITYF0D_H__
-#define __FREESTYLE_PYTHON_DENSITYF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_DENSITYF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h
index ddd500f617e..cf5adf216fc 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETPROJECTEDXF0D_H__
-#define __FREESTYLE_PYTHON_GETPROJECTEDXF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETPROJECTEDXF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h
index 8fccf14971f..6293f9daa24 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETPROJECTEDYF0D_H__
-#define __FREESTYLE_PYTHON_GETPROJECTEDYF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETPROJECTEDYF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h
index eecf69adb12..edae33e4c85 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETPROJECTEDZF0D_H__
-#define __FREESTYLE_PYTHON_GETPROJECTEDZF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETPROJECTEDZF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h
index 745bd5c628d..e0427fb1ccd 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETXF0D_H__
-#define __FREESTYLE_PYTHON_GETXF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETXF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h
index 437ec573585..3f4f3c85dc7 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETYF0D_H__
-#define __FREESTYLE_PYTHON_GETYF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETYF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h
index 840303fa59d..54a451e81f4 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETZF0D_H__
-#define __FREESTYLE_PYTHON_GETZF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETZF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h
index f8072427d47..85626895d20 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF0D_H__
-#define __FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h
index d0aed95fc1a..fe2f333da37 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_ZDISCONTINUITYF0D_H__
-#define __FREESTYLE_PYTHON_ZDISCONTINUITYF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_ZDISCONTINUITYF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h
index 72238cfc255..8fffe3fd51d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETCURVILINEARABSCISSAF0D_H__
-#define __FREESTYLE_PYTHON_GETCURVILINEARABSCISSAF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DFloat.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETCURVILINEARABSCISSAF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h
index 4fdb6419f21..3346b519e60 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETPARAMETERF0D_H__
-#define __FREESTYLE_PYTHON_GETPARAMETERF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DFloat.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETPARAMETERF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h
index 6ed42ee8019..de4930912f4 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF0D_H__
-#define __FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DFloat.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h
index 48d36543ca0..ceee0151771 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_READCOMPLETEVIEWMAPPIXELF0D_H__
-#define __FREESTYLE_PYTHON_READCOMPLETEVIEWMAPPIXELF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DFloat.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_READCOMPLETEVIEWMAPPIXELF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h
index 014a4aa2b8e..54c9ac984f9 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_READMAPPIXELF0D_H__
-#define __FREESTYLE_PYTHON_READMAPPIXELF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DFloat.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_READMAPPIXELF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h
index 3cff99be633..f1fa1f1b7a2 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_READSTEERABLEVIEWMAPPIXELF0D_H__
-#define __FREESTYLE_PYTHON_READSTEERABLEVIEWMAPPIXELF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DFloat.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_READSTEERABLEVIEWMAPPIXELF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h
index dd64fb40d85..510cc7ef146 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF0D_H__
-#define __FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DUnsigned.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h
index 82889b64aba..9e932ff9eff 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETOCCLUDERSF0D_H__
-#define __FREESTYLE_PYTHON_GETOCCLUDERSF0D_H__
+#pragma once
#include "../BPy_UnaryFunction0DVectorViewShape.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETOCCLUDERSF0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp
index fb887371c3a..88705c41204 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp
@@ -197,9 +197,7 @@ static int UnaryFunction1DDouble___init__(BPy_UnaryFunction1DDouble *self,
static void UnaryFunction1DDouble___dealloc__(BPy_UnaryFunction1DDouble *self)
{
- if (self->uf1D_double) {
- delete self->uf1D_double;
- }
+ delete self->uf1D_double;
UnaryFunction1D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h
index cfd7f954b54..1fb42a18337 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1DDOUBLE_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION1DDOUBLE_H__
+#pragma once
#include "../BPy_UnaryFunction1D.h"
@@ -48,5 +47,3 @@ int UnaryFunction1DDouble_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION1DDOUBLE_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp
index e2a55d49a06..3cfc5464296 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp
@@ -103,9 +103,7 @@ static int UnaryFunction1DEdgeNature___init__(BPy_UnaryFunction1DEdgeNature *sel
static void UnaryFunction1DEdgeNature___dealloc__(BPy_UnaryFunction1DEdgeNature *self)
{
- if (self->uf1D_edgenature) {
- delete self->uf1D_edgenature;
- }
+ delete self->uf1D_edgenature;
UnaryFunction1D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h
index 1a7a5a2d7ee..886eb469d51 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1DEDGENATURE_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION1DEDGENATURE_H__
+#pragma once
#include "../BPy_UnaryFunction1D.h"
@@ -50,5 +49,3 @@ int UnaryFunction1DEdgeNature_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION1DEDGENATURE_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp
index 2eb4f9349da..4fdc68a2e89 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp
@@ -93,9 +93,7 @@ static int UnaryFunction1DFloat___init__(BPy_UnaryFunction1DFloat *self,
static void UnaryFunction1DFloat___dealloc__(BPy_UnaryFunction1DFloat *self)
{
- if (self->uf1D_float) {
- delete self->uf1D_float;
- }
+ delete self->uf1D_float;
UnaryFunction1D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h
index 8a5a329b0bf..8b977c9c96a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1DFLOAT_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION1DFLOAT_H__
+#pragma once
#include "../BPy_UnaryFunction1D.h"
@@ -48,5 +47,3 @@ int UnaryFunction1DFloat_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION1DFLOAT_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp
index ff306652036..218afa3ff10 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp
@@ -103,9 +103,7 @@ static int UnaryFunction1DUnsigned___init__(BPy_UnaryFunction1DUnsigned *self,
static void UnaryFunction1DUnsigned___dealloc__(BPy_UnaryFunction1DUnsigned *self)
{
- if (self->uf1D_unsigned) {
- delete self->uf1D_unsigned;
- }
+ delete self->uf1D_unsigned;
UnaryFunction1D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h
index b18bf34b27e..9149275b610 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1DUNSIGNED_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION1DUNSIGNED_H__
+#pragma once
#include "../BPy_UnaryFunction1D.h"
@@ -48,5 +47,3 @@ int UnaryFunction1DUnsigned_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION1DUNSIGNED_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp
index 1469b0a6e33..939ccfb8905 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp
@@ -108,9 +108,7 @@ static int UnaryFunction1DVec2f___init__(BPy_UnaryFunction1DVec2f *self,
static void UnaryFunction1DVec2f___dealloc__(BPy_UnaryFunction1DVec2f *self)
{
- if (self->uf1D_vec2f) {
- delete self->uf1D_vec2f;
- }
+ delete self->uf1D_vec2f;
UnaryFunction1D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h
index f4cad92334f..b55f9af7c4d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1DVEC2F_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION1DVEC2F_H__
+#pragma once
#include "../BPy_UnaryFunction1D.h"
@@ -51,5 +50,3 @@ int UnaryFunction1DVec2f_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION1DVEC2F_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp
index 63cd0584adb..02b6373cce4 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp
@@ -101,9 +101,7 @@ static int UnaryFunction1DVec3f___init__(BPy_UnaryFunction1DVec3f *self,
static void UnaryFunction1DVec3f___dealloc__(BPy_UnaryFunction1DVec3f *self)
{
- if (self->uf1D_vec3f) {
- delete self->uf1D_vec3f;
- }
+ delete self->uf1D_vec3f;
UnaryFunction1D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h
index 253a8d550e3..9e4342979e4 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1DVEC3F_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION1DVEC3F_H__
+#pragma once
#include "../BPy_UnaryFunction1D.h"
@@ -51,5 +50,3 @@ int UnaryFunction1DVec3f_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION1DVEC3F_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
index cb94d6b75e2..b2020e9f554 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
@@ -118,9 +118,7 @@ static int UnaryFunction1DVectorViewShape___init__(BPy_UnaryFunction1DVectorView
static void UnaryFunction1DVectorViewShape___dealloc__(BPy_UnaryFunction1DVectorViewShape *self)
{
- if (self->uf1D_vectorviewshape) {
- delete self->uf1D_vectorviewshape;
- }
+ delete self->uf1D_vectorviewshape;
UnaryFunction1D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h
index 80511e7c145..bfbcf5e451d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1DVECTORVIEWSHAPE_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION1DVECTORVIEWSHAPE_H__
+#pragma once
#include "../BPy_UnaryFunction1D.h"
@@ -53,5 +52,3 @@ int UnaryFunction1DVectorViewShape_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION1DVECTORVIEWSHAPE_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp
index 216b1305556..7b25daa24f9 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp
@@ -116,9 +116,7 @@ static int UnaryFunction1DVoid___init__(BPy_UnaryFunction1DVoid *self,
static void UnaryFunction1DVoid___dealloc__(BPy_UnaryFunction1DVoid *self)
{
- if (self->uf1D_void) {
- delete self->uf1D_void;
- }
+ delete self->uf1D_void;
UnaryFunction1D_Type.tp_dealloc((PyObject *)self);
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h
index 03d949f879d..3a821bc2083 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_UNARYFUNCTION1DVOID_H__
-#define __FREESTYLE_PYTHON_UNARYFUNCTION1DVOID_H__
+#pragma once
#include "../BPy_UnaryFunction1D.h"
@@ -48,5 +47,3 @@ int UnaryFunction1DVoid_Init(PyObject *module);
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_UNARYFUNCTION1DVOID_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h
index 15c381eb279..961c9729e6c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CURVENATUREF1D_H__
-#define __FREESTYLE_PYTHON_CURVENATUREF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DEdgeNature.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CURVENATUREF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h
index 343c4379b4a..080f26aa753 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_NORMAL2DF1D_H__
-#define __FREESTYLE_PYTHON_NORMAL2DF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DVec2f.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_NORMAL2DF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h
index 5b453cbe714..013423003c6 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_ORIENTATION2DF1D_H__
-#define __FREESTYLE_PYTHON_ORIENTATION2DF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DVec2f.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_ORIENTATION2DF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h
index 26c6cd845db..2e79559bf43 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_ORIENTATION3DF1D_H__
-#define __FREESTYLE_PYTHON_ORIENTATION3DF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DVec3f.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_ORIENTATION3DF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h
index 7a3a3fcff4b..241c864fdad 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CURVATURE2DANGLEF1D_H__
-#define __FREESTYLE_PYTHON_CURVATURE2DANGLEF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CURVATURE2DANGLEF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h
index 71daa14069a..1b1040d66c4 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_DENSITYF1D_H__
-#define __FREESTYLE_PYTHON_DENSITYF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_DENSITYF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h
index dacfb33553e..1bbb4d46fc5 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETCOMPLETEVIEWMAPDENSITYF1D_H__
-#define __FREESTYLE_PYTHON_GETCOMPLETEVIEWMAPDENSITYF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETCOMPLETEVIEWMAPDENSITYF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h
index b039fadcdca..8e55fc7cc50 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETDIRECTIONALVIEWMAPDENSITYF1D_H__
-#define __FREESTYLE_PYTHON_GETDIRECTIONALVIEWMAPDENSITYF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETDIRECTIONALVIEWMAPDENSITYF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h
index febb3265f97..66bd3983e45 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETPROJECTEDXF1D_H__
-#define __FREESTYLE_PYTHON_GETPROJECTEDXF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETPROJECTEDXF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h
index 5a0a5f42cb0..b1a1e90f83f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETPROJECTEDYF1D_H__
-#define __FREESTYLE_PYTHON_GETPROJECTEDYF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETPROJECTEDYF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h
index aeb42521d1f..73b01bbf999 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETPROJECTEDZF1D_H__
-#define __FREESTYLE_PYTHON_GETPROJECTEDZF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETPROJECTEDZF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h
index 47f168af2a8..81167d36352 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETSTEERABLEVIEWMAPDENSITYF1D_H__
-#define __FREESTYLE_PYTHON_GETSTEERABLEVIEWMAPDENSITYF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETSTEERABLEVIEWMAPDENSITYF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h
index 4f19b4ac67f..0e4a67cf4df 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF1D_H__
-#define __FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h
index 7db31882381..30218ccd5e5 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETXF1D_H__
-#define __FREESTYLE_PYTHON_GETXF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETXF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h
index 3f70d64e200..16afac368c1 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETYF1D_H__
-#define __FREESTYLE_PYTHON_GETYF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETYF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h
index b841bde2a5c..a204f3d6665 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETZF1D_H__
-#define __FREESTYLE_PYTHON_GETZF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETZF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h
index 258d028bfbd..d472489fb0c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF1D_H__
-#define __FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h
index c336591842b..c1966472377 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_ZDISCONTINUITYF1D_H__
-#define __FREESTYLE_PYTHON_ZDISCONTINUITYF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DDouble.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_ZDISCONTINUITYF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h
index 0d4d118995b..c76e5f821f2 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF1D_H__
-#define __FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DUnsigned.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h
index 5a14b5dc35d..2e414446e47 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETOCCLUDEEF1D_H__
-#define __FREESTYLE_PYTHON_GETOCCLUDEEF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DVectorViewShape.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETOCCLUDEEF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h
index 29899d443a6..52c78bd7f4c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETOCCLUDERSF1D_H__
-#define __FREESTYLE_PYTHON_GETOCCLUDERSF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DVectorViewShape.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETOCCLUDERSF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h
index b90f3df5831..9c025e3b404 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_GETSHAPEF1D_H__
-#define __FREESTYLE_PYTHON_GETSHAPEF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DVectorViewShape.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_GETSHAPEF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h
index c6423ef434f..0a8650d6794 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CHAININGTIMESTAMPF1D_H__
-#define __FREESTYLE_PYTHON_CHAININGTIMESTAMPF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DVoid.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CHAININGTIMESTAMPF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h
index 0d74b1f7756..e555788f4c9 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_INCREMENTCHAININGTIMESTAMPF1D_H__
-#define __FREESTYLE_PYTHON_INCREMENTCHAININGTIMESTAMPF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DVoid.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_INCREMENTCHAININGTIMESTAMPF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h
index 4787f35cfc5..117d724d179 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_TIMESTAMPF1D_H__
-#define __FREESTYLE_PYTHON_TIMESTAMPF1D_H__
+#pragma once
#include "../BPy_UnaryFunction1DVoid.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CHAININGTIMESTAMPF1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h
index b947ccf5b95..0c36e770b80 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FALSEUP0D_H__
-#define __FREESTYLE_PYTHON_FALSEUP0D_H__
+#pragma once
#include "../BPy_UnaryPredicate0D.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FALSEUP0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h
index 72acf363992..abdfb4e294d 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_TRUEUP0D_H__
-#define __FREESTYLE_PYTHON_TRUEUP0D_H__
+#pragma once
#include "../BPy_UnaryPredicate0D.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_TRUEUP0D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h
index de6c40fa8ac..be06a0fee33 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_CONTOURUP1D_H__
-#define __FREESTYLE_PYTHON_CONTOURUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_CONTOURUP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h
index fb02b63fa3d..068c7727ec0 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_DENSITYLOWERTHANUP1D_H__
-#define __FREESTYLE_PYTHON_DENSITYLOWERTHANUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_DENSITYLOWERTHANUP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h
index e2ba8b7709b..d103c1356ab 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_EQUALTOCHAININGTIMESTAMPUP1D_H__
-#define __FREESTYLE_PYTHON_EQUALTOCHAININGTIMESTAMPUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_EQUALTOCHAININGTIMESTAMPUP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h
index 13736242382..9e3d90ab760 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_EQUALTOTIMESTAMPUP1D_H__
-#define __FREESTYLE_PYTHON_EQUALTOTIMESTAMPUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_EQUALTOTIMESTAMPUP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h
index 4d2a22731fa..0576b727f4a 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_EXTERNALCONTOURUP1D_H__
-#define __FREESTYLE_PYTHON_EXTERNALCONTOURUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_EXTERNALCONTOURUP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h
index 57255c2333f..a74d2aba0a6 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_FALSEUP1D_H__
-#define __FREESTYLE_PYTHON_FALSEUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_FALSEUP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h
index bbb1dce5ed1..970ddd48273 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYUP1D_H__
-#define __FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -45,5 +44,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYUP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h
index a48ed0aa0da..c60aa7aa9cf 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_SHAPEUP1D_H__
-#define __FREESTYLE_PYTHON_SHAPEUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_SHAPEUP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h
index 49c3dcdacca..e036cfe95ed 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_TRUEUP1D_H__
-#define __FREESTYLE_PYTHON_TRUEUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -43,5 +42,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_TRUEUP1D_H__ */
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h
index 2481beee78e..1d08f7fb530 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h
@@ -18,8 +18,7 @@
* \ingroup freestyle
*/
-#ifndef __FREESTYLE_PYTHON_WITHINIMAGEBOUNDARYUP1D_H__
-#define __FREESTYLE_PYTHON_WITHINIMAGEBOUNDARYUP1D_H__
+#pragma once
#include "../BPy_UnaryPredicate1D.h"
@@ -44,5 +43,3 @@ typedef struct {
#ifdef __cplusplus
}
#endif
-
-#endif /* __FREESTYLE_PYTHON_WITHINIMAGEBOUNDARYUP1D_H__ */
diff --git a/source/blender/freestyle/intern/scene_graph/DrawingStyle.h b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h
index 631f4b99adc..ca1e2351868 100644
--- a/source/blender/freestyle/intern/scene_graph/DrawingStyle.h
+++ b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_DRAWING_STYLE_H__
-#define __FREESTYLE_DRAWING_STYLE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -124,5 +123,3 @@ DrawingStyle &DrawingStyle::operator=(const DrawingStyle &ds)
}
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_DRAWING_STYLE_H__
diff --git a/source/blender/freestyle/intern/scene_graph/FrsMaterial.h b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h
index 80cd783f164..18d3c8839dd 100644
--- a/source/blender/freestyle/intern/scene_graph/FrsMaterial.h
+++ b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_MATERIAL_H__
-#define __FREESTYLE_MATERIAL_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -479,5 +478,3 @@ bool FrsMaterial::operator==(const FrsMaterial &m) const
}
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_MATERIAL_H__
diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
index f8dd25913c1..9d1fc009e37 100644
--- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
+++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_INDEXED_FACE_SET_H__
-#define __FREESTYLE_INDEXED_FACE_SET_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -311,5 +310,3 @@ class IndexedFaceSet : public Rep {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_INDEXED_FACE_SET_H__
diff --git a/source/blender/freestyle/intern/scene_graph/LineRep.h b/source/blender/freestyle/intern/scene_graph/LineRep.h
index e45a33d9fc4..43fd736570f 100644
--- a/source/blender/freestyle/intern/scene_graph/LineRep.h
+++ b/source/blender/freestyle/intern/scene_graph/LineRep.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_LINE_REP_H__
-#define __FREESTYLE_LINE_REP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -149,5 +148,3 @@ class LineRep : public Rep {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_LINE_REP_H__
diff --git a/source/blender/freestyle/intern/scene_graph/Node.h b/source/blender/freestyle/intern/scene_graph/Node.h
index 96072993590..07bf186ea39 100644
--- a/source/blender/freestyle/intern/scene_graph/Node.h
+++ b/source/blender/freestyle/intern/scene_graph/Node.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_NODE_H__
-#define __FREESTYLE_NODE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -113,5 +112,3 @@ class Node : public BaseObject {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_NODE_H__
diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.h b/source/blender/freestyle/intern/scene_graph/NodeCamera.h
index 2878e7a834e..cc7b1f7f67c 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeCamera.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_NODE_CAMERA_H__
-#define __FREESTYLE_NODE_CAMERA_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -217,5 +216,3 @@ class NodePerspectiveCamera : public NodeCamera {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_NODE_CAMERA_H__
diff --git a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h
index f1dfad06250..8bbdaf30bad 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_NODE_DRAWING_STYLE_H__
-#define __FREESTYLE_NODE_DRAWING_STYLE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -106,5 +105,3 @@ class NodeDrawingStyle : public NodeGroup {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_NODE_DRAWING_STYLE_H__
diff --git a/source/blender/freestyle/intern/scene_graph/NodeGroup.h b/source/blender/freestyle/intern/scene_graph/NodeGroup.h
index 5ef16255e46..0558e22bed1 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeGroup.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeGroup.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_NODE_GROUP_H__
-#define __FREESTYLE_NODE_GROUP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -80,5 +79,3 @@ class NodeGroup : public Node {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_NODE_GROUP_H__
diff --git a/source/blender/freestyle/intern/scene_graph/NodeLight.h b/source/blender/freestyle/intern/scene_graph/NodeLight.h
index 046b61beaf4..bf8389441b6 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeLight.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeLight.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_NODE_LIGHT_H__
-#define __FREESTYLE_NODE_LIGHT_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -101,5 +100,3 @@ class NodeLight : public Node {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_NODE_LIGHT_H__
diff --git a/source/blender/freestyle/intern/scene_graph/NodeShape.h b/source/blender/freestyle/intern/scene_graph/NodeShape.h
index 13ee265ec10..5f7a24b85d5 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeShape.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeShape.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_NODE_SHAPE_H__
-#define __FREESTYLE_NODE_SHAPE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -93,5 +92,3 @@ class NodeShape : public Node {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_NODE_SHAPE_H__
diff --git a/source/blender/freestyle/intern/scene_graph/NodeTransform.h b/source/blender/freestyle/intern/scene_graph/NodeTransform.h
index 1118417657f..9d55046a515 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeTransform.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeTransform.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_NODE_TRANSFORM_H__
-#define __FREESTYLE_NODE_TRANSFORM_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -98,5 +97,3 @@ class NodeTransform : public NodeGroup {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_NODE_TRANSFORM_H__
diff --git a/source/blender/freestyle/intern/scene_graph/NodeViewLayer.h b/source/blender/freestyle/intern/scene_graph/NodeViewLayer.h
index 2339abe9aed..d52155eb216 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeViewLayer.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeViewLayer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_NODE_VIEW_LAYER_H__
-#define __FREESTYLE_NODE_VIEW_LAYER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -59,5 +58,3 @@ class NodeViewLayer : public Node {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_NODE_VIEW_LAYER_H__
diff --git a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h
index 2e39259077e..c33fd529c69 100644
--- a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h
+++ b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_ORIENTED_LINE_REP_H__
-#define __FREESTYLE_ORIENTED_LINE_REP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -62,5 +61,3 @@ class OrientedLineRep : public LineRep {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_ORIENTED_LINE_REP_H__
diff --git a/source/blender/freestyle/intern/scene_graph/Rep.h b/source/blender/freestyle/intern/scene_graph/Rep.h
index 58553d257d9..dae5272beed 100644
--- a/source/blender/freestyle/intern/scene_graph/Rep.h
+++ b/source/blender/freestyle/intern/scene_graph/Rep.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_REP_H__
-#define __FREESTYLE_REP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -181,5 +180,3 @@ class Rep : public BaseObject {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_REP_H__
diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
index b5d954664e4..e5f029d28b7 100644
--- a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
+++ b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
@@ -65,7 +65,7 @@ void SceneHash::visitIndexedFaceSet(IndexedFaceSet &ifs)
static const int MOD_ADLER = 65521;
-void SceneHash::adler32(unsigned char *data, int size)
+void SceneHash::adler32(const unsigned char *data, int size)
{
uint32_t sum1 = _sum & 0xffff;
uint32_t sum2 = (_sum >> 16) & 0xffff;
diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.h b/source/blender/freestyle/intern/scene_graph/SceneHash.h
index 53d1381da60..605e2ddaa84 100644
--- a/source/blender/freestyle/intern/scene_graph/SceneHash.h
+++ b/source/blender/freestyle/intern/scene_graph/SceneHash.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_SCENE_HASH_H__
-#define __FREESTYLE_SCENE_HASH_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -67,7 +66,7 @@ class SceneHash : public SceneVisitor {
}
private:
- void adler32(unsigned char *data, int size);
+ void adler32(const unsigned char *data, int size);
uint32_t _sum;
uint32_t _prevSum;
@@ -78,5 +77,3 @@ class SceneHash : public SceneVisitor {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_SCENE_HASH_H__
diff --git a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp
index 0c533232179..33aa368d755 100644
--- a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp
+++ b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp
@@ -39,42 +39,42 @@ VISIT(NodeLight)
VISIT(NodeDrawingStyle)
VISIT(NodeTransform)
-void ScenePrettyPrinter::visitNodeShapeBefore(NodeShape &)
+void ScenePrettyPrinter::visitNodeShapeBefore(NodeShape &UNUSED(shape))
{
increaseSpace();
}
-void ScenePrettyPrinter::visitNodeShapeAfter(NodeShape &)
+void ScenePrettyPrinter::visitNodeShapeAfter(NodeShape &UNUSED(shape))
{
decreaseSpace();
}
-void ScenePrettyPrinter::visitNodeGroupBefore(NodeGroup &)
+void ScenePrettyPrinter::visitNodeGroupBefore(NodeGroup &UNUSED(group))
{
increaseSpace();
}
-void ScenePrettyPrinter::visitNodeGroupAfter(NodeGroup &)
+void ScenePrettyPrinter::visitNodeGroupAfter(NodeGroup &UNUSED(group))
{
decreaseSpace();
}
-void ScenePrettyPrinter::visitNodeDrawingStyleBefore(NodeDrawingStyle &)
+void ScenePrettyPrinter::visitNodeDrawingStyleBefore(NodeDrawingStyle &UNUSED(style))
{
increaseSpace();
}
-void ScenePrettyPrinter::visitNodeDrawingStyleAfter(NodeDrawingStyle &)
+void ScenePrettyPrinter::visitNodeDrawingStyleAfter(NodeDrawingStyle &UNUSED(style))
{
decreaseSpace();
}
-void ScenePrettyPrinter::visitNodeTransformBefore(NodeTransform &)
+void ScenePrettyPrinter::visitNodeTransformBefore(NodeTransform &UNUSED(transform))
{
increaseSpace();
}
-void ScenePrettyPrinter::visitNodeTransformAfter(NodeTransform &)
+void ScenePrettyPrinter::visitNodeTransformAfter(NodeTransform &UNUSED(transform))
{
decreaseSpace();
}
diff --git a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h
index f19233bba3b..9436bdccf57 100644
--- a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h
+++ b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_SCENE_PRETTY_PRINTER_H__
-#define __FREESTYLE_SCENE_PRETTY_PRINTER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -96,5 +95,3 @@ class ScenePrettyPrinter : public SceneVisitor {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_SCENE_PRETTY_PRINTER_H__
diff --git a/source/blender/freestyle/intern/scene_graph/SceneVisitor.h b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h
index 81a478e8cf3..72e0f4cbb28 100644
--- a/source/blender/freestyle/intern/scene_graph/SceneVisitor.h
+++ b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_SCENE_VISITOR_H__
-#define __FREESTYLE_SCENE_VISITOR_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -111,5 +110,3 @@ class SceneVisitor {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_SCENE_VISITOR_H__
diff --git a/source/blender/freestyle/intern/scene_graph/TriangleRep.h b/source/blender/freestyle/intern/scene_graph/TriangleRep.h
index e4190faae6f..4461b38d68b 100644
--- a/source/blender/freestyle/intern/scene_graph/TriangleRep.h
+++ b/source/blender/freestyle/intern/scene_graph/TriangleRep.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_TRIANGLE_REP_H__
-#define __FREESTYLE_TRIANGLE_REP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -142,5 +141,3 @@ class TriangleRep : public Rep {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_TRIANGLE_REP_H__
diff --git a/source/blender/freestyle/intern/scene_graph/VertexRep.h b/source/blender/freestyle/intern/scene_graph/VertexRep.h
index 3831be3105a..278cfa694f7 100644
--- a/source/blender/freestyle/intern/scene_graph/VertexRep.h
+++ b/source/blender/freestyle/intern/scene_graph/VertexRep.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_VERTEX_REP_H__
-#define __FREESTYLE_VERTEX_REP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -129,5 +128,3 @@ class VertexRep : public Rep {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_VERTEX_REP_H__
diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h
index dcab48fd12f..17e419bed54 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h
+++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_ADVANCED_FUNCTIONS_0D_H__
-#define __FREESTYLE_ADVANCED_FUNCTIONS_0D_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -209,5 +208,3 @@ class GetViewMapGradientNormF0D : public UnaryFunction0D<float> {
} // end of namespace Functions0D
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_ADVANCED_FUNCTIONS_0D_H__
diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h
index d14a9836b95..349db393e17 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h
+++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_ADVANCED_FUNCTIONS_1D_H__
-#define __FREESTYLE_ADVANCED_FUNCTIONS_1D_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -289,5 +288,3 @@ class GetViewMapGradientNormF1D : public UnaryFunction1D<double> {
} // end of namespace Functions1D
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_ADVANCED_FUNCTIONS_1D_H__
diff --git a/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h b/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h
index 05fcf7f356f..25a5efcce34 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h
+++ b/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_ADVANCED_PREDICATES_1D_H__
-#define __FREESTYLE_ADVANCED_PREDICATES_1D_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -82,5 +81,3 @@ class DensityLowerThanUP1D : public UnaryPredicate1D {
} // end of namespace Predicates1D
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_ADVANCED_PREDICATES_1D_H__
diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h
index 544fdee519f..63c7d451599 100644
--- a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h
+++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_ADVANCED_STROKE_SHADERS_H__
-#define __FREESTYLE_ADVANCED_STROKE_SHADERS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -232,5 +231,3 @@ class OmissionShader : public StrokeShader {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_ADVANCED_STROKE_SHADERS_H__
diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
index d969e0e50a3..36234ad619c 100644
--- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
+++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
@@ -37,10 +37,8 @@
#include "BKE_global.h"
-extern "C" {
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-}
namespace Freestyle {
diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h
index 5a2d0cbe458..8663cfd42bf 100644
--- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h
+++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_BASIC_STROKE_SHADERS_H__
-#define __FREESTYLE_BASIC_STROKE_SHADERS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -660,5 +659,3 @@ class StrokeTextureStepShader : public StrokeShader {
} // end of namespace StrokeShaders
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_BASIC_STROKE_SHADERS_H__
diff --git a/source/blender/freestyle/intern/stroke/Canvas.cpp b/source/blender/freestyle/intern/stroke/Canvas.cpp
index 4386e64345f..14c74c0f127 100644
--- a/source/blender/freestyle/intern/stroke/Canvas.cpp
+++ b/source/blender/freestyle/intern/stroke/Canvas.cpp
@@ -90,9 +90,7 @@ Canvas::~Canvas()
}
_maps.clear();
}
- if (_steerableViewMap) {
- delete _steerableViewMap;
- }
+ delete _steerableViewMap;
}
void Canvas::preDraw()
diff --git a/source/blender/freestyle/intern/stroke/Canvas.h b/source/blender/freestyle/intern/stroke/Canvas.h
index 2a0ebbe17c5..2bbd9c2682f 100644
--- a/source/blender/freestyle/intern/stroke/Canvas.h
+++ b/source/blender/freestyle/intern/stroke/Canvas.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CANVAS_H__
-#define __FREESTYLE_CANVAS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -252,5 +251,3 @@ class Canvas {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CANVAS_H__
diff --git a/source/blender/freestyle/intern/stroke/Chain.h b/source/blender/freestyle/intern/stroke/Chain.h
index 7cd0c64cc16..d5dae5c35ba 100644
--- a/source/blender/freestyle/intern/stroke/Chain.h
+++ b/source/blender/freestyle/intern/stroke/Chain.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CHAIN_H__
-#define __FREESTYLE_CHAIN_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -109,5 +108,3 @@ class Chain : public Curve {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CHAIN_H__
diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.h b/source/blender/freestyle/intern/stroke/ChainingIterators.h
index 36611a4a009..e3d49c167b5 100644
--- a/source/blender/freestyle/intern/stroke/ChainingIterators.h
+++ b/source/blender/freestyle/intern/stroke/ChainingIterators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CHAINING_ITERATORS_H__
-#define __FREESTYLE_CHAINING_ITERATORS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -415,5 +414,3 @@ class ChainPredicateIterator : public ChainingIterator {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CHAINING_ITERATORS_H__
diff --git a/source/blender/freestyle/intern/stroke/ContextFunctions.h b/source/blender/freestyle/intern/stroke/ContextFunctions.h
index 6897e2b193d..334bdd657c1 100644
--- a/source/blender/freestyle/intern/stroke/ContextFunctions.h
+++ b/source/blender/freestyle/intern/stroke/ContextFunctions.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CONTEXT_FUNCTIONS_H__
-#define __FREESTYLE_CONTEXT_FUNCTIONS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -106,5 +105,3 @@ FEdge *GetSelectedFEdgeCF();
} // end of namespace ContextFunctions
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CONTEXT_FUNCTIONS_H__
diff --git a/source/blender/freestyle/intern/stroke/Curve.h b/source/blender/freestyle/intern/stroke/Curve.h
index 8a233eef4ab..5f0d2a6aed7 100644
--- a/source/blender/freestyle/intern/stroke/Curve.h
+++ b/source/blender/freestyle/intern/stroke/Curve.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CURVE_H__
-#define __FREESTYLE_CURVE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -604,5 +603,3 @@ class Curve : public Interface1D {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CURVE_H__
diff --git a/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h b/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h
index 4ac4c04774e..1896a674477 100644
--- a/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h
+++ b/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CURVE_ADVANCED_ITERATORS_H__
-#define __FREESTYLE_CURVE_ADVANCED_ITERATORS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -388,5 +387,3 @@ class __point_iterator : public IteratorBase<Traits, BidirectionalIteratorTag_Tr
} // end of namespace CurveInternal
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CURVE_ADVANCED_ITERATORS_H__
diff --git a/source/blender/freestyle/intern/stroke/CurveIterators.h b/source/blender/freestyle/intern/stroke/CurveIterators.h
index 3ac7ede0954..9d1cf33ed80 100644
--- a/source/blender/freestyle/intern/stroke/CurveIterators.h
+++ b/source/blender/freestyle/intern/stroke/CurveIterators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CURVE_ITERATORS_H__
-#define __FREESTYLE_CURVE_ITERATORS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -303,5 +302,3 @@ class CurvePointIterator : public Interface0DIteratorNested {
} // end of namespace CurveInternal
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CURVE_ITERATORS_H__
diff --git a/source/blender/freestyle/intern/stroke/Modifiers.h b/source/blender/freestyle/intern/stroke/Modifiers.h
index ecdfd25c499..0aac6f58658 100644
--- a/source/blender/freestyle/intern/stroke/Modifiers.h
+++ b/source/blender/freestyle/intern/stroke/Modifiers.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_MODIFIERS_H__
-#define __FREESTYLE_MODIFIERS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -71,5 +70,3 @@ template<class Edge> struct TimestampModifier : public EdgeModifier<Edge> {
};
} /* namespace Freestyle */
-
-#endif // MODIFIERS_H
diff --git a/source/blender/freestyle/intern/stroke/Module.h b/source/blender/freestyle/intern/stroke/Module.h
index 3e32361eb45..58c44751d91 100644
--- a/source/blender/freestyle/intern/stroke/Module.h
+++ b/source/blender/freestyle/intern/stroke/Module.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_MODULE_H__
-#define __FREESTYLE_MODULE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -76,5 +75,3 @@ class Module {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_MODULE_H__
diff --git a/source/blender/freestyle/intern/stroke/Operators.h b/source/blender/freestyle/intern/stroke/Operators.h
index 2da9d30f172..e721e9fb837 100644
--- a/source/blender/freestyle/intern/stroke/Operators.h
+++ b/source/blender/freestyle/intern/stroke/Operators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_OPERATORS_H__
-#define __FREESTYLE_OPERATORS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -290,5 +289,3 @@ class Operators {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_OPERATORS_H__
diff --git a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h
index 7ddd3d3e4c0..78aa17d26b6 100644
--- a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h
+++ b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_PS_STROKE_RENDERER_H__
-#define __FREESTYLE_PS_STROKE_RENDERER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -55,5 +54,3 @@ class PSStrokeRenderer : public StrokeRenderer {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_PS_STROKE_RENDERER_H__
diff --git a/source/blender/freestyle/intern/stroke/Predicates0D.h b/source/blender/freestyle/intern/stroke/Predicates0D.h
index 90b6d99f2db..89dbaeb339d 100644
--- a/source/blender/freestyle/intern/stroke/Predicates0D.h
+++ b/source/blender/freestyle/intern/stroke/Predicates0D.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_PREDICATES_0D_H__
-#define __FREESTYLE_PREDICATES_0D_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -178,5 +177,3 @@ class FalseUP0D : public UnaryPredicate0D {
} // end of namespace Predicates0D
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_PREDICATES_0D_H__
diff --git a/source/blender/freestyle/intern/stroke/Predicates1D.h b/source/blender/freestyle/intern/stroke/Predicates1D.h
index 0ad4c69f869..a3953950d86 100644
--- a/source/blender/freestyle/intern/stroke/Predicates1D.h
+++ b/source/blender/freestyle/intern/stroke/Predicates1D.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_PREDICATES_1D_H__
-#define __FREESTYLE_PREDICATES_1D_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -580,5 +579,3 @@ class ViewMapGradientNormBP1D : public BinaryPredicate1D {
} // end of namespace Predicates1D
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_PREDICATES_1D_H__
diff --git a/source/blender/freestyle/intern/stroke/QInformationMap.h b/source/blender/freestyle/intern/stroke/QInformationMap.h
index d3a4218f9d7..0f651a656bf 100644
--- a/source/blender/freestyle/intern/stroke/QInformationMap.h
+++ b/source/blender/freestyle/intern/stroke/QInformationMap.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_Q_INFORMATION_MAP_H__
-#define __FREESTYLE_Q_INFORMATION_MAP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -59,5 +58,3 @@ class QInformationMap : public InformationMap {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_Q_INFORMATION_MAP_H__
diff --git a/source/blender/freestyle/intern/stroke/Stroke.cpp b/source/blender/freestyle/intern/stroke/Stroke.cpp
index 2f29eac83b1..93a870c26ad 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.cpp
+++ b/source/blender/freestyle/intern/stroke/Stroke.cpp
@@ -484,9 +484,7 @@ Stroke &Stroke::operator=(const Stroke &iBrother)
_id = iBrother._id;
_ViewEdges = iBrother._ViewEdges;
_sampling = iBrother._sampling;
- if (_rep) {
- delete _rep;
- }
+ delete _rep;
if (iBrother._rep) {
_rep = new StrokeRep(*(iBrother._rep));
}
diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h
index 7983e8cdde2..71753b25328 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.h
+++ b/source/blender/freestyle/intern/stroke/Stroke.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STROKE_H__
-#define __FREESTYLE_STROKE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -894,5 +893,3 @@ Stroke::Stroke(InputVertexIterator iBegin, InputVertexIterator iEnd)
}
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STROKE_H__
diff --git a/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h b/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h
index b8c96533a1c..4256cdebe86 100644
--- a/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h
+++ b/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STROKE_ADVANCED_ITERATORS_H__
-#define __FREESTYLE_STROKE_ADVANCED_ITERATORS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -179,5 +178,3 @@ class vertex_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTa
} // end of namespace StrokeInternal
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STROKE_ADVANCED_ITERATORS_H__
diff --git a/source/blender/freestyle/intern/stroke/StrokeIO.h b/source/blender/freestyle/intern/stroke/StrokeIO.h
index ae38847f8cc..a0e59655eed 100644
--- a/source/blender/freestyle/intern/stroke/StrokeIO.h
+++ b/source/blender/freestyle/intern/stroke/StrokeIO.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STROKE_IO_H__
-#define __FREESTYLE_STROKE_IO_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -37,5 +36,3 @@ ostream &operator<<(ostream &out, const StrokeVertex &iStrokeVertex);
ostream &operator<<(ostream &out, const Stroke &iStroke);
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STROKE_IO_H__
diff --git a/source/blender/freestyle/intern/stroke/StrokeIterators.h b/source/blender/freestyle/intern/stroke/StrokeIterators.h
index 71932d8487a..d4cbffd535e 100644
--- a/source/blender/freestyle/intern/stroke/StrokeIterators.h
+++ b/source/blender/freestyle/intern/stroke/StrokeIterators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STROKE_ITERATORS_H__
-#define __FREESTYLE_STROKE_ITERATORS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -232,5 +231,3 @@ class StrokeVertexIterator : public Interface0DIteratorNested {
} // end of namespace StrokeInternal
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STROKE_ITERATORS_H__
diff --git a/source/blender/freestyle/intern/stroke/StrokeLayer.h b/source/blender/freestyle/intern/stroke/StrokeLayer.h
index ecb98025875..2101e7732ce 100644
--- a/source/blender/freestyle/intern/stroke/StrokeLayer.h
+++ b/source/blender/freestyle/intern/stroke/StrokeLayer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STROKE_LAYER_H__
-#define __FREESTYLE_STROKE_LAYER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -102,5 +101,3 @@ class StrokeLayer {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STROKE_LAYER_H__
diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.h b/source/blender/freestyle/intern/stroke/StrokeRenderer.h
index 67deb5eebf3..2fb08b880d9 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRenderer.h
+++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STROKE_RENDERER_H__
-#define __FREESTYLE_STROKE_RENDERER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -142,5 +141,3 @@ class StrokeRenderer {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STROKE_RENDERER_H__
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.h b/source/blender/freestyle/intern/stroke/StrokeRep.h
index d6ee1d01279..09048b8e147 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.h
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STROKE_REP_H__
-#define __FREESTYLE_STROKE_REP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -278,5 +277,3 @@ class StrokeRep {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STROKE_REP_H__
diff --git a/source/blender/freestyle/intern/stroke/StrokeShader.h b/source/blender/freestyle/intern/stroke/StrokeShader.h
index 7b1f12a8c9d..f4984136747 100644
--- a/source/blender/freestyle/intern/stroke/StrokeShader.h
+++ b/source/blender/freestyle/intern/stroke/StrokeShader.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STROKE_SHADERS_H__
-#define __FREESTYLE_STROKE_SHADERS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -96,5 +95,3 @@ class StrokeShader {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STROKE_SHADERS_H__
diff --git a/source/blender/freestyle/intern/stroke/StrokeTesselator.h b/source/blender/freestyle/intern/stroke/StrokeTesselator.h
index 8cece705ed4..0c1efb873bc 100644
--- a/source/blender/freestyle/intern/stroke/StrokeTesselator.h
+++ b/source/blender/freestyle/intern/stroke/StrokeTesselator.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STROKE_TESSELATOR_H__
-#define __FREESTYLE_STROKE_TESSELATOR_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -73,5 +72,3 @@ class StrokeTesselator {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STROKE_TESSELATOR_H__
diff --git a/source/blender/freestyle/intern/stroke/StyleModule.h b/source/blender/freestyle/intern/stroke/StyleModule.h
index 6f03d903045..398e4c7ee77 100644
--- a/source/blender/freestyle/intern/stroke/StyleModule.h
+++ b/source/blender/freestyle/intern/stroke/StyleModule.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STYLE_MODULE_H__
-#define __FREESTYLE_STYLE_MODULE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -182,5 +181,3 @@ class StyleModule {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STYLE_MODULE_H__
diff --git a/source/blender/freestyle/intern/system/BaseIterator.h b/source/blender/freestyle/intern/system/BaseIterator.h
index 651f2bf4387..7792fded4cb 100644
--- a/source/blender/freestyle/intern/system/BaseIterator.h
+++ b/source/blender/freestyle/intern/system/BaseIterator.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_BASE_ITERATOR_H__
-#define __FREESTYLE_BASE_ITERATOR_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -103,5 +102,3 @@ template<class Traits, class IteratorTagTraits> class IteratorBase {
};
} /* namespace Freestyle */
-
-#endif // BASEITERATOR_H
diff --git a/source/blender/freestyle/intern/system/BaseObject.h b/source/blender/freestyle/intern/system/BaseObject.h
index 335221223dc..76d30aa74e2 100644
--- a/source/blender/freestyle/intern/system/BaseObject.h
+++ b/source/blender/freestyle/intern/system/BaseObject.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_BASE_OBJECT_H__
-#define __FREESTYLE_BASE_OBJECT_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -72,5 +71,3 @@ class BaseObject {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_BASE_OBJECT_H__
diff --git a/source/blender/freestyle/intern/system/Cast.h b/source/blender/freestyle/intern/system/Cast.h
index 44fd86a9b43..db0defbae22 100644
--- a/source/blender/freestyle/intern/system/Cast.h
+++ b/source/blender/freestyle/intern/system/Cast.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CAST_H__
-#define __FREESTYLE_CAST_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -35,5 +34,3 @@ template<class T, class U> U *cast(T *in)
} // end of namespace Cast
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CAST_H__
diff --git a/source/blender/freestyle/intern/system/Exception.h b/source/blender/freestyle/intern/system/Exception.h
index 0efd136af8f..618c2171fb9 100644
--- a/source/blender/freestyle/intern/system/Exception.h
+++ b/source/blender/freestyle/intern/system/Exception.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_EXCEPTION_H__
-#define __FREESTYLE_EXCEPTION_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -62,5 +61,3 @@ class Exception {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_EXCEPTION_H__
diff --git a/source/blender/freestyle/intern/system/FreestyleConfig.h b/source/blender/freestyle/intern/system/FreestyleConfig.h
index 34db7121eaf..032da864e6c 100644
--- a/source/blender/freestyle/intern/system/FreestyleConfig.h
+++ b/source/blender/freestyle/intern/system/FreestyleConfig.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CONFIG_H__
-#define __FREESTYLE_CONFIG_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -43,5 +42,3 @@ static const string PATH_SEP(":");
} // end of namespace Config
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CONFIG_H__
diff --git a/source/blender/freestyle/intern/system/Id.h b/source/blender/freestyle/intern/system/Id.h
index 549def6cabb..f94e044de29 100644
--- a/source/blender/freestyle/intern/system/Id.h
+++ b/source/blender/freestyle/intern/system/Id.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_ID_H__
-#define __FREESTYLE_ID_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -138,5 +137,3 @@ inline std::ostream &operator<<(std::ostream &s, const Id &id)
}
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_ID_H__
diff --git a/source/blender/freestyle/intern/system/Interpreter.h b/source/blender/freestyle/intern/system/Interpreter.h
index 911d03318e5..0a5c0302fe6 100644
--- a/source/blender/freestyle/intern/system/Interpreter.h
+++ b/source/blender/freestyle/intern/system/Interpreter.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_INTERPRETER_H__
-#define __FREESTYLE_INTERPRETER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -61,5 +60,3 @@ class Interpreter {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_INTERPRETER_H__
diff --git a/source/blender/freestyle/intern/system/Iterator.h b/source/blender/freestyle/intern/system/Iterator.h
index 75d49521f96..d2086f637d9 100644
--- a/source/blender/freestyle/intern/system/Iterator.h
+++ b/source/blender/freestyle/intern/system/Iterator.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_ITERATOR_H__
-#define __FREESTYLE_ITERATOR_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -73,5 +72,3 @@ class Iterator {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_ITERATOR_H__
diff --git a/source/blender/freestyle/intern/system/PointerSequence.h b/source/blender/freestyle/intern/system/PointerSequence.h
index d136632f060..c2301ee740d 100644
--- a/source/blender/freestyle/intern/system/PointerSequence.h
+++ b/source/blender/freestyle/intern/system/PointerSequence.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_POINTER_SEQUENCE_H__
-#define __FREESTYLE_POINTER_SEQUENCE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -91,5 +90,3 @@ template<typename C, typename T> class PointerSequence : public C {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_POINTER_SEQUENCE_H__
diff --git a/source/blender/freestyle/intern/system/Precision.h b/source/blender/freestyle/intern/system/Precision.h
index c6695f207cc..6a6435299ca 100644
--- a/source/blender/freestyle/intern/system/Precision.h
+++ b/source/blender/freestyle/intern/system/Precision.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_PRECISION_H__
-#define __FREESTYLE_PRECISION_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -31,5 +30,3 @@ static const real M_EPSILON = 0.00000001;
#endif // SWIG
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_PRECISION_H__
diff --git a/source/blender/freestyle/intern/system/ProgressBar.h b/source/blender/freestyle/intern/system/ProgressBar.h
index b3a1f98f15e..d7b02c48359 100644
--- a/source/blender/freestyle/intern/system/ProgressBar.h
+++ b/source/blender/freestyle/intern/system/ProgressBar.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_PROGRESS_BAR_H__
-#define __FREESTYLE_PROGRESS_BAR_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -92,5 +91,3 @@ class ProgressBar {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_PROGRESS_BAR_H__
diff --git a/source/blender/freestyle/intern/system/PseudoNoise.h b/source/blender/freestyle/intern/system/PseudoNoise.h
index 53fe54754c8..38270016675 100644
--- a/source/blender/freestyle/intern/system/PseudoNoise.h
+++ b/source/blender/freestyle/intern/system/PseudoNoise.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_PSEUDO_NOISE_H__
-#define __FREESTYLE_PSEUDO_NOISE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -56,5 +55,3 @@ class PseudoNoise {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_PSEUDO_NOISE_H__
diff --git a/source/blender/freestyle/intern/system/PythonInterpreter.h b/source/blender/freestyle/intern/system/PythonInterpreter.h
index 4bc6ba9db38..bae69aa0a42 100644
--- a/source/blender/freestyle/intern/system/PythonInterpreter.h
+++ b/source/blender/freestyle/intern/system/PythonInterpreter.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_PYTHON_INTERPRETER_H__
-#define __FREESTYLE_PYTHON_INTERPRETER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -34,7 +33,6 @@ extern "C" {
#include "MEM_guardedalloc.h"
// soc
-extern "C" {
#include "DNA_text_types.h"
#include "BKE_context.h"
@@ -47,7 +45,6 @@ extern "C" {
#include "BPY_extern.h"
#include "bpy_capi_utils.h"
-}
namespace Freestyle {
@@ -149,5 +146,3 @@ class PythonInterpreter : public Interpreter {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_PYTHON_INTERPRETER_H__
diff --git a/source/blender/freestyle/intern/system/RandGen.h b/source/blender/freestyle/intern/system/RandGen.h
index 43f36b0a2fd..e514f4cfc9f 100644
--- a/source/blender/freestyle/intern/system/RandGen.h
+++ b/source/blender/freestyle/intern/system/RandGen.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_RAND_GEN_H__
-#define __FREESTYLE_RAND_GEN_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -46,5 +45,3 @@ class RandGen {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_RAND_GEN_H__
diff --git a/source/blender/freestyle/intern/system/RenderMonitor.h b/source/blender/freestyle/intern/system/RenderMonitor.h
index 709df6c2d8e..5d543f32dfb 100644
--- a/source/blender/freestyle/intern/system/RenderMonitor.h
+++ b/source/blender/freestyle/intern/system/RenderMonitor.h
@@ -14,17 +14,14 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_RENDER_MONITOR_H__
-#define __FREESTYLE_RENDER_MONITOR_H__
+#pragma once
/** \file
* \ingroup freestyle
* \brief Classes defining the basic "Iterator" design pattern
*/
-extern "C" {
#include "render_types.h"
-}
#ifdef WITH_CXX_GUARDEDALLOC
# include "MEM_guardedalloc.h"
@@ -73,5 +70,3 @@ class RenderMonitor {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_RENDER_MONITOR_H__
diff --git a/source/blender/freestyle/intern/system/StringUtils.h b/source/blender/freestyle/intern/system/StringUtils.h
index aeacddd64c8..dc63f20f294 100644
--- a/source/blender/freestyle/intern/system/StringUtils.h
+++ b/source/blender/freestyle/intern/system/StringUtils.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STRING_UTILS_H__
-#define __FREESTYLE_STRING_UTILS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -28,10 +27,8 @@
#include <string>
#include <vector>
-extern "C" {
#include "BLI_path_util.h"
#include "BLI_string.h"
-}
using namespace std;
@@ -52,5 +49,3 @@ struct ltstr {
} // end of namespace StringUtils
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STRING_UTILS_H__
diff --git a/source/blender/freestyle/intern/system/TimeStamp.h b/source/blender/freestyle/intern/system/TimeStamp.h
index 2fbf83d226d..5560bf8be8d 100644
--- a/source/blender/freestyle/intern/system/TimeStamp.h
+++ b/source/blender/freestyle/intern/system/TimeStamp.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_TIME_STAMP_H__
-#define __FREESTYLE_TIME_STAMP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -70,5 +69,3 @@ class TimeStamp {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_TIME_STAMP_H__
diff --git a/source/blender/freestyle/intern/system/TimeUtils.h b/source/blender/freestyle/intern/system/TimeUtils.h
index 6d4c56ab15e..3c8a28e9e43 100644
--- a/source/blender/freestyle/intern/system/TimeUtils.h
+++ b/source/blender/freestyle/intern/system/TimeUtils.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_TIME_UTILS_H__
-#define __FREESTYLE_TIME_UTILS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -60,5 +59,3 @@ class Chronometer {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_TIME_UTILS_H__
diff --git a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
index 97aae3d653c..c2d843742df 100644
--- a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
-#define __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -66,5 +65,3 @@ class ArbitraryGridDensityProviderFactory : public GridDensityProviderFactory {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_ARBITRARY_GRID_DENSITY_PROVIDER_H__
diff --git a/source/blender/freestyle/intern/view_map/AutoPtrHelper.h b/source/blender/freestyle/intern/view_map/AutoPtrHelper.h
index fb2a9d73d13..94fd80bc0fb 100644
--- a/source/blender/freestyle/intern/view_map/AutoPtrHelper.h
+++ b/source/blender/freestyle/intern/view_map/AutoPtrHelper.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_AUTOPTR_HELPER_H__
-#define __FREESTYLE_AUTOPTR_HELPER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -47,5 +46,3 @@ template<typename T> class AutoPtr : public std::unique_ptr<T> {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_AUTOPTR_HELPER_H__
diff --git a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
index f530cf35569..5336cc1ff97 100644
--- a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
-#define __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -63,5 +62,3 @@ class AverageAreaGridDensityProviderFactory : public GridDensityProviderFactory
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_AVERAGE_AREA_GRID_DENSITY_PROVIDER_H__
diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.h b/source/blender/freestyle/intern/view_map/BoxGrid.h
index 35b5e4d6b55..581ee0a2340 100644
--- a/source/blender/freestyle/intern/view_map/BoxGrid.h
+++ b/source/blender/freestyle/intern/view_map/BoxGrid.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_BOX_GRID_H__
-#define __FREESTYLE_BOX_GRID_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -422,5 +421,3 @@ inline bool BoxGrid::insertOccluder(OccluderSource &source, OccluderData *&occlu
}
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_BOX_GRID_H__
diff --git a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
index 2df5ecd0867..cb3a297076a 100644
--- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
+++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp
@@ -94,7 +94,7 @@ static inline bool crossesProscenium(real proscenium[4], FEdge *fe)
return GeomUtils::intersect2dSeg2dArea(min, max, A, B);
}
-static inline bool insideProscenium(real proscenium[4], const Vec3r &point)
+static inline bool insideProscenium(const real proscenium[4], const Vec3r &point)
{
return !(point[0] < proscenium[0] || point[0] > proscenium[1] || point[1] < proscenium[2] ||
point[1] > proscenium[3]);
diff --git a/source/blender/freestyle/intern/view_map/CulledOccluderSource.h b/source/blender/freestyle/intern/view_map/CulledOccluderSource.h
index 3457fb6ca10..2bb77bad0f7 100644
--- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.h
+++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
-#define __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -57,5 +56,3 @@ class CulledOccluderSource : public OccluderSource {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_CULLED_OCCLUDER_SOURCE_H__
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
index 2bcf2d3bee8..c4115ee00c4 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_FEDGE_X_DETECTOR_H__
-#define __FREESTYLE_FEDGE_X_DETECTOR_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -246,5 +245,3 @@ class FEdgeXDetector {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_FEDGE_X_DETECTOR_H__
diff --git a/source/blender/freestyle/intern/view_map/Functions0D.h b/source/blender/freestyle/intern/view_map/Functions0D.h
index 7149c1909fd..0364069b631 100644
--- a/source/blender/freestyle/intern/view_map/Functions0D.h
+++ b/source/blender/freestyle/intern/view_map/Functions0D.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_FUNCTIONS_0D_H__
-#define __FREESTYLE_FUNCTIONS_0D_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -509,5 +508,3 @@ ViewShape *getOccludeeF0D(Interface0DIterator &it);
} // end of namespace Functions0D
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_FUNCTIONS_0D_H__
diff --git a/source/blender/freestyle/intern/view_map/Functions1D.h b/source/blender/freestyle/intern/view_map/Functions1D.h
index 20aa9f2a27f..9cf5527ee19 100644
--- a/source/blender/freestyle/intern/view_map/Functions1D.h
+++ b/source/blender/freestyle/intern/view_map/Functions1D.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_FUNCTIONS_1D_H__
-#define __FREESTYLE_FUNCTIONS_1D_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -638,5 +637,3 @@ void getShapeF1D(Interface1D &inter, set<ViewShape *> &oShapes);
} // end of namespace Functions1D
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_FUNCTIONS_1D_H__
diff --git a/source/blender/freestyle/intern/view_map/GridDensityProvider.h b/source/blender/freestyle/intern/view_map/GridDensityProvider.h
index 290d5b0cfba..e663f14d368 100644
--- a/source/blender/freestyle/intern/view_map/GridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/GridDensityProvider.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_GRID_DENSITY_PROVIDER_H__
-#define __FREESTYLE_GRID_DENSITY_PROVIDER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -167,5 +166,3 @@ class GridDensityProviderFactory {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_GRID_DENSITY_PROVIDER_H__
diff --git a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
index b32a284cb61..0ce62572092 100644
--- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
+++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
-#define __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -48,5 +47,3 @@ class HeuristicGridDensityProviderFactory : public GridDensityProviderFactory {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_HEURISTIC_GRID_DENSITY_PROVIDER_FACTORY_H__
diff --git a/source/blender/freestyle/intern/view_map/Interface0D.cpp b/source/blender/freestyle/intern/view_map/Interface0D.cpp
index fc5a797cc87..2961b0f58e5 100644
--- a/source/blender/freestyle/intern/view_map/Interface0D.cpp
+++ b/source/blender/freestyle/intern/view_map/Interface0D.cpp
@@ -24,6 +24,8 @@ extern "C" {
#include "Interface0D.h"
+#include "BLI_utildefines.h"
+
namespace Freestyle {
real Interface0D::getX() const
@@ -74,7 +76,7 @@ Geometry::Vec2r Interface0D::getPoint2D() const
return 0;
}
-FEdge *Interface0D::getFEdge(Interface0D &)
+FEdge *Interface0D::getFEdge(Interface0D &UNUSED(element))
{
PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden");
return 0;
diff --git a/source/blender/freestyle/intern/view_map/Interface0D.h b/source/blender/freestyle/intern/view_map/Interface0D.h
index 724a98f047f..6b4682cc862 100644
--- a/source/blender/freestyle/intern/view_map/Interface0D.h
+++ b/source/blender/freestyle/intern/view_map/Interface0D.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_INTERFACE_0D_H__
-#define __FREESTYLE_INTERFACE_0D_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -341,5 +340,3 @@ class Interface0DIterator : public Iterator {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_INTERFACE_0D_H__
diff --git a/source/blender/freestyle/intern/view_map/Interface1D.h b/source/blender/freestyle/intern/view_map/Interface1D.h
index ab489bff4c9..778deb20a60 100644
--- a/source/blender/freestyle/intern/view_map/Interface1D.h
+++ b/source/blender/freestyle/intern/view_map/Interface1D.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_INTERFACE_1D_H__
-#define __FREESTYLE_INTERFACE_1D_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -203,5 +202,3 @@ class Interface1D {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_INTERFACE_1D_H__
diff --git a/source/blender/freestyle/intern/view_map/OccluderSource.h b/source/blender/freestyle/intern/view_map/OccluderSource.h
index 07df3b95347..befde3c1b1b 100644
--- a/source/blender/freestyle/intern/view_map/OccluderSource.h
+++ b/source/blender/freestyle/intern/view_map/OccluderSource.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_OCCLUDER_SOURCE_H__
-#define __FREESTYLE_OCCLUDER_SOURCE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -70,5 +69,3 @@ class OccluderSource {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_OCCLUDER_SOURCE_H__
diff --git a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
index 52d57e3030e..fec869e0665 100644
--- a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
-#define __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -64,5 +63,3 @@ class Pow23GridDensityProviderFactory : public GridDensityProviderFactory {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_POW_23_GRID_DENSITY_PROVIDER_H__
diff --git a/source/blender/freestyle/intern/view_map/Silhouette.h b/source/blender/freestyle/intern/view_map/Silhouette.h
index 8503836e0ca..6463cd7eb3e 100644
--- a/source/blender/freestyle/intern/view_map/Silhouette.h
+++ b/source/blender/freestyle/intern/view_map/Silhouette.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_SILHOUETTE_H__
-#define __FREESTYLE_SILHOUETTE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -1958,5 +1957,3 @@ class SShape {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_SILHOUETTE_H__
diff --git a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
index 79d863e81e7..124ef35e5b9 100644
--- a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
+++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
-#define __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -135,5 +134,3 @@ class SilhouetteGeomEngine {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_SILHOUETTE_GEOM_ENGINE_H__
diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.h b/source/blender/freestyle/intern/view_map/SphericalGrid.h
index e9074580fb9..0ef68d073ae 100644
--- a/source/blender/freestyle/intern/view_map/SphericalGrid.h
+++ b/source/blender/freestyle/intern/view_map/SphericalGrid.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_SPHERICAL_GRID_H__
-#define __FREESTYLE_SPHERICAL_GRID_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -434,5 +433,3 @@ inline bool SphericalGrid::insertOccluder(OccluderSource &source, OccluderData *
}
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_SPHERICAL_GRID_H__
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
index efda4b7fd2a..7549ebcb258 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
@@ -193,9 +193,7 @@ void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases,
{
for (unsigned int i = 0; i <= _nbOrientations; ++i) {
ImagePyramid *svm = (_imagesPyramids)[i];
- if (svm) {
- delete svm;
- }
+ delete svm;
if (copy) {
svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma);
}
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.h b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
index 537f07f44f4..65633fd85d4 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.h
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_STEERABLE_VIEW_MAP_H__
-#define __FREESTYLE_STEERABLE_VIEW_MAP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -156,5 +155,3 @@ class SteerableViewMap {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_STEERABLE_VIEW_MAP_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
index b1934d08376..f6f54a2d87d 100644
--- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
-#define __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -292,5 +291,3 @@ class ViewEdgeXBuilder {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_VIEW_EDGE_X_BUILDER_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h
index 83c45be8c61..e5e49f17ca5 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.h
+++ b/source/blender/freestyle/intern/view_map/ViewMap.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_VIEW_MAP_H__
-#define __FREESTYLE_VIEW_MAP_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -1830,5 +1829,3 @@ inline real ViewEdge::curvature2d_as_angle(int iCombination) const
#endif
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_VIEW_MAP_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h b/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
index 2ff46e353f3..25d8439173b 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
-#define __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -816,5 +815,3 @@ class vertex_iterator_base : public IteratorBase<Traits, BidirectionalIteratorTa
} // end of namespace ViewEdgeInternal
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_VIEW_MAP_ADVANCED_ITERATORS_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
index b7de3a5b319..8ac272e92b5 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -1084,7 +1084,7 @@ static inline bool crossesProscenium(real proscenium[4], FEdge *fe)
return GeomUtils::intersect2dSeg2dArea(min, max, A, B);
}
-static inline bool insideProscenium(real proscenium[4], const Vec3r &point)
+static inline bool insideProscenium(const real proscenium[4], const Vec3r &point)
{
return !(point[0] < proscenium[0] || point[0] > proscenium[1] || point[1] < proscenium[2] ||
point[1] > proscenium[3]);
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
index a5d967af331..6d919f5561a 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_VIEW_MAP_BUILDER_H__
-#define __FREESTYLE_VIEW_MAP_BUILDER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -284,5 +283,3 @@ class ViewMapBuilder {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_VIEW_MAP_BUILDER_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.h b/source/blender/freestyle/intern/view_map/ViewMapIO.h
index 98d27852c8d..e4c42c094d0 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIO.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapIO.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_VIEW_MAP_IO_H__
-#define __FREESTYLE_VIEW_MAP_IO_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -102,5 +101,3 @@ template<> istream &read<0>(istream &in, char *)
} // End of namespace ViewMapIO
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_VIEW_MAP_IO_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIterators.h b/source/blender/freestyle/intern/view_map/ViewMapIterators.h
index 174e25896cc..9956d47469d 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIterators.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapIterators.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_VIEW_MAP_ITERATORS_H__
-#define __FREESTYLE_VIEW_MAP_ITERATORS_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -590,5 +589,3 @@ class ViewEdgeIterator : public Iterator {
} // end of namespace ViewEdgeInternal
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_VIEW_MAP_ITERATORS_H__
diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp b/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
index ef79384e2af..54de3321b80 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp
@@ -33,7 +33,7 @@ NodeGroup *ViewMapTesselator::Tesselate(ViewMap *iViewMap)
return Tesselate(viewedges.begin(), viewedges.end());
}
-NodeGroup *ViewMapTesselator::Tesselate(WShape *)
+NodeGroup *ViewMapTesselator::Tesselate(WShape *UNUSED(shape))
{
return NULL;
}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
index b6bf51618d8..c6690b1d9dc 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_VIEW_MAP_TESSELATOR_H__
-#define __FREESTYLE_VIEW_MAP_TESSELATOR_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -225,5 +224,3 @@ NodeGroup *ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterat
}
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_VIEW_MAP_TESSELATOR_H__
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
index 96b313d4e01..1702a22c678 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
@@ -59,7 +59,7 @@ static bool angle_obtuse(WVertex *v, WFace *f)
// FIXME
// WVvertex is useless but kept for history reasons
-static bool triangle_obtuse(WVertex *, WFace *f)
+static bool triangle_obtuse(WVertex *UNUSED(v), WFace *f)
{
bool b = false;
for (int i = 0; i < 3; i++) {
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.h b/source/blender/freestyle/intern/winged_edge/Curvature.h
index 32e9ea8b5cf..9ecc92df2ac 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.h
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.h
@@ -27,8 +27,7 @@
* FRANCE
*/
-#ifndef __FREESTYLE_CURVATURE_H__
-#define __FREESTYLE_CURVATURE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -142,5 +141,3 @@ void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle &nc);
} // namespace OGF
} /* namespace Freestyle */
-
-#endif /* __FREESTYLE_CURVATURE_H__ */
diff --git a/source/blender/freestyle/intern/winged_edge/Nature.h b/source/blender/freestyle/intern/winged_edge/Nature.h
index 91f9f63b412..68323d7122c 100644
--- a/source/blender/freestyle/intern/winged_edge/Nature.h
+++ b/source/blender/freestyle/intern/winged_edge/Nature.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_NATURE_H__
-#define __FREESTYLE_NATURE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -67,5 +66,3 @@ static const EdgeNature EDGE_MARK = (1 << 7); // 128
} // end of namespace Nature
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_NATURE_H__
diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h
index 424cd76a6b7..42a8e62990f 100644
--- a/source/blender/freestyle/intern/winged_edge/WEdge.h
+++ b/source/blender/freestyle/intern/winged_edge/WEdge.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_W_EDGE_H__
-#define __FREESTYLE_W_EDGE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -1428,5 +1427,3 @@ inline void WOEdge::setVecAndAngle()
}
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_W_EDGE_H__
diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.h b/source/blender/freestyle/intern/winged_edge/WFillGrid.h
index 918c1f154f3..095a58675c0 100644
--- a/source/blender/freestyle/intern/winged_edge/WFillGrid.h
+++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_W_FILL_GRID_H__
-#define __FREESTYLE_W_FILL_GRID_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -85,5 +84,3 @@ class WFillGrid {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_W_FILL_GRID_H__
diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
index e3deebcd6c2..5393f57d2cd 100644
--- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
+++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_WS_FILL_GRID_H__
-#define __FREESTYLE_WS_FILL_GRID_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -81,5 +80,3 @@ class WSFillGrid {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_WS_FILL_GRID_H__
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h
index 21418c44614..8fe99f9bb93 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdge.h
+++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_WX_EDGE_H__
-#define __FREESTYLE_WX_EDGE_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -845,5 +844,3 @@ bool WXVertex::isFeature()
}
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_WX_EDGE_H__
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
index d223cee5e0e..efba18eb084 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
+++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_WX_EDGE_BUILDER_H__
-#define __FREESTYLE_WX_EDGE_BUILDER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -48,5 +47,3 @@ class WXEdgeBuilder : public WingedEdgeBuilder {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_WX_EDGE_BUILDER_H__
diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
index 63f65988fc9..c989d77a730 100644
--- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
@@ -64,11 +64,9 @@ void WingedEdgeBuilder::visitNodeTransform(NodeTransform &tn)
_current_matrix = new_matrix;
}
-void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform &)
+void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform &UNUSED(transform))
{
- if (_current_matrix) {
- delete _current_matrix;
- }
+ delete _current_matrix;
if (_matrices_stack.empty()) {
_current_matrix = NULL;
diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
index 5c728dea1d8..8cf86a421b7 100644
--- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
+++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FREESTYLE_WINGED_EDGE_BUILDER_H__
-#define __FREESTYLE_WINGED_EDGE_BUILDER_H__
+#pragma once
/** \file
* \ingroup freestyle
@@ -174,5 +173,3 @@ class WingedEdgeBuilder : public SceneVisitor {
};
} /* namespace Freestyle */
-
-#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__
diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt
index 703d3c393e8..ad29dbe6668 100644
--- a/source/blender/functions/CMakeLists.txt
+++ b/source/blender/functions/CMakeLists.txt
@@ -30,19 +30,22 @@ set(SRC
intern/attributes_ref.cc
intern/cpp_types.cc
intern/multi_function.cc
+ intern/multi_function_builder.cc
intern/multi_function_network.cc
intern/multi_function_network_evaluation.cc
+ intern/multi_function_network_optimization.cc
FN_array_spans.hh
FN_attributes_ref.hh
FN_cpp_type.hh
- FN_cpp_types.hh
+ FN_generic_vector_array.hh
FN_multi_function.hh
FN_multi_function_builder.hh
FN_multi_function_context.hh
FN_multi_function_data_type.hh
FN_multi_function_network.hh
FN_multi_function_network_evaluation.hh
+ FN_multi_function_network_optimization.hh
FN_multi_function_param_type.hh
FN_multi_function_params.hh
FN_multi_function_signature.hh
@@ -54,3 +57,20 @@ set(LIB
)
blender_add_lib(bf_functions "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+if(WITH_GTESTS)
+ set(TEST_SRC
+ tests/FN_array_spans_test.cc
+ tests/FN_attributes_ref_test.cc
+ tests/FN_cpp_type_test.cc
+ tests/FN_generic_vector_array_test.cc
+ tests/FN_multi_function_network_test.cc
+ tests/FN_multi_function_test.cc
+ tests/FN_spans_test.cc
+ )
+ set (TEST_LIB
+ bf_functions
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_functions_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
+endif()
diff --git a/source/blender/functions/FN_array_spans.hh b/source/blender/functions/FN_array_spans.hh
index 3f71b36c49c..976b9a44d3e 100644
--- a/source/blender/functions/FN_array_spans.hh
+++ b/source/blender/functions/FN_array_spans.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_ARRAY_SPANS_HH__
-#define __FN_ARRAY_SPANS_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -39,17 +38,17 @@ enum class VArraySpanCategory {
template<typename T> class VArraySpanBase {
protected:
- uint virtual_size_;
+ int64_t virtual_size_;
VArraySpanCategory category_;
union {
struct {
const T *start;
- uint size;
+ int64_t size;
} single_array;
struct {
const T *const *starts;
- const uint *sizes;
+ const int64_t *sizes;
} starts_and_sizes;
} data_;
@@ -71,7 +70,7 @@ template<typename T> class VArraySpanBase {
return this->virtual_size_ == 0;
}
- uint size() const
+ int64_t size() const
{
return this->virtual_size_;
}
@@ -99,15 +98,16 @@ template<typename T> class VArraySpan : public VArraySpanBase<T> {
this->data_.starts_and_sizes.sizes = nullptr;
}
- VArraySpan(Span<T> span, uint virtual_size)
+ VArraySpan(Span<T> span, int64_t virtual_size)
{
+ BLI_assert(virtual_size >= 0);
this->virtual_size_ = virtual_size;
this->category_ = VArraySpanCategory::SingleArray;
this->data_.single_array.start = span.data();
this->data_.single_array.size = span.size();
}
- VArraySpan(Span<const T *> starts, Span<uint> sizes)
+ VArraySpan(Span<const T *> starts, Span<int64_t> sizes)
{
BLI_assert(starts.size() == sizes.size());
this->virtual_size_ = starts.size();
@@ -116,8 +116,9 @@ template<typename T> class VArraySpan : public VArraySpanBase<T> {
this->data_.starts_and_sizes.sizes = sizes.begin();
}
- VSpan<T> operator[](uint index) const
+ VSpan<T> operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->virtual_size_);
switch (this->category_) {
case VArraySpanCategory::SingleArray:
@@ -151,16 +152,16 @@ class GVArraySpan : public VArraySpanBase<void> {
this->data_.starts_and_sizes.sizes = nullptr;
}
- GVArraySpan(GSpan array, uint virtual_size)
+ GVArraySpan(GSpan array, int64_t virtual_size)
{
this->type_ = &array.type();
this->virtual_size_ = virtual_size;
this->category_ = VArraySpanCategory::SingleArray;
- this->data_.single_array.start = array.buffer();
+ this->data_.single_array.start = array.data();
this->data_.single_array.size = array.size();
}
- GVArraySpan(const CPPType &type, Span<const void *> starts, Span<uint> sizes)
+ GVArraySpan(const CPPType &type, Span<const void *> starts, Span<int64_t> sizes)
{
BLI_assert(starts.size() == sizes.size());
this->type_ = &type;
@@ -187,7 +188,7 @@ class GVArraySpan : public VArraySpanBase<void> {
return VArraySpan<T>(*this);
}
- GVSpan operator[](uint index) const
+ GVSpan operator[](int64_t index) const
{
BLI_assert(index < virtual_size_);
switch (category_) {
@@ -203,5 +204,3 @@ class GVArraySpan : public VArraySpanBase<void> {
};
} // namespace blender::fn
-
-#endif /* __FN_ARRAY_SPANS_HH__ */
diff --git a/source/blender/functions/FN_attributes_ref.hh b/source/blender/functions/FN_attributes_ref.hh
index 3c31665e0b5..0cac8d82d26 100644
--- a/source/blender/functions/FN_attributes_ref.hh
+++ b/source/blender/functions/FN_attributes_ref.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_ATTRIBUTES_REF_HH__
-#define __FN_ATTRIBUTES_REF_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -50,12 +49,12 @@ class AttributesInfoBuilder : NonCopyable, NonMovable {
AttributesInfoBuilder() = default;
~AttributesInfoBuilder();
- template<typename T> void add(StringRef name, const T &default_value)
+ template<typename T> bool add(StringRef name, const T &default_value)
{
- this->add(name, CPPType::get<T>(), (const void *)&default_value);
+ return this->add(name, CPPType::get<T>(), (const void *)&default_value);
}
- void add(StringRef name, const CPPType &type, const void *default_value = nullptr);
+ bool add(StringRef name, const CPPType &type, const void *default_value = nullptr);
};
/**
@@ -65,7 +64,7 @@ class AttributesInfoBuilder : NonCopyable, NonMovable {
class AttributesInfo : NonCopyable, NonMovable {
private:
LinearAllocator<> allocator_;
- Map<StringRefNull, uint> index_by_name_;
+ Map<StringRefNull, int> index_by_name_;
Vector<StringRefNull> name_by_index_;
Vector<const CPPType *> type_by_index_;
Vector<void *> defaults_;
@@ -75,7 +74,7 @@ class AttributesInfo : NonCopyable, NonMovable {
AttributesInfo(const AttributesInfoBuilder &builder);
~AttributesInfo();
- uint size() const
+ int size() const
{
return name_by_index_.size();
}
@@ -85,17 +84,17 @@ class AttributesInfo : NonCopyable, NonMovable {
return name_by_index_.index_range();
}
- StringRefNull name_of(uint index) const
+ StringRefNull name_of(int index) const
{
return name_by_index_[index];
}
- uint index_of(StringRef name) const
+ int index_of(StringRef name) const
{
return index_by_name_.lookup_as(name);
}
- const void *default_of(uint index) const
+ const void *default_of(int index) const
{
return defaults_[index];
}
@@ -105,7 +104,7 @@ class AttributesInfo : NonCopyable, NonMovable {
return this->default_of(this->index_of(name));
}
- template<typename T> const T &default_of(uint index) const
+ template<typename T> const T &default_of(int index) const
{
BLI_assert(type_by_index_[index]->is<T>());
return *(T *)defaults_[index];
@@ -116,7 +115,7 @@ class AttributesInfo : NonCopyable, NonMovable {
return this->default_of<T>(this->index_of(name));
}
- const CPPType &type_of(uint index) const
+ const CPPType &type_of(int index) const
{
return *type_by_index_[index];
}
@@ -133,7 +132,7 @@ class AttributesInfo : NonCopyable, NonMovable {
int try_index_of(StringRef name) const
{
- return (int)index_by_name_.lookup_default_as(name, -1);
+ return index_by_name_.lookup_default_as(name, -1);
}
int try_index_of(StringRef name, const CPPType &type) const
@@ -142,7 +141,7 @@ class AttributesInfo : NonCopyable, NonMovable {
if (index == -1) {
return -1;
}
- else if (this->type_of((uint)index) == type) {
+ else if (this->type_of(index) == type) {
return index;
}
else {
@@ -161,8 +160,10 @@ class MutableAttributesRef {
Span<void *> buffers_;
IndexRange range_;
+ friend class AttributesRef;
+
public:
- MutableAttributesRef(const AttributesInfo &info, Span<void *> buffers, uint size)
+ MutableAttributesRef(const AttributesInfo &info, Span<void *> buffers, int64_t size)
: MutableAttributesRef(info, buffers, IndexRange(size))
{
}
@@ -172,17 +173,22 @@ class MutableAttributesRef {
{
}
- uint size() const
+ int64_t size() const
{
return range_.size();
}
+ IndexRange index_range() const
+ {
+ return IndexRange(this->size());
+ }
+
const AttributesInfo &info() const
{
return *info_;
}
- GMutableSpan get(uint index) const
+ GMutableSpan get(int index) const
{
const CPPType &type = info_->type_of(index);
void *ptr = POINTER_OFFSET(buffers_[index], type.size() * range_.start());
@@ -194,7 +200,7 @@ class MutableAttributesRef {
return this->get(info_->index_of(name));
}
- template<typename T> MutableSpan<T> get(uint index) const
+ template<typename T> MutableSpan<T> get(int index) const
{
BLI_assert(info_->type_of(index).is<T>());
return MutableSpan<T>((T *)buffers_[index] + range_.start(), range_.size());
@@ -212,7 +218,7 @@ class MutableAttributesRef {
return {};
}
else {
- return this->get((uint)index);
+ return this->get(index);
}
}
@@ -222,8 +228,8 @@ class MutableAttributesRef {
if (index == -1) {
return {};
}
- else if (info_->type_of((uint)index).is<T>()) {
- return this->get<T>((uint)index);
+ else if (info_->type_of(index).is<T>()) {
+ return this->get<T>(index);
}
else {
return {};
@@ -235,12 +241,101 @@ class MutableAttributesRef {
return this->slice(range.start(), range.size());
}
- MutableAttributesRef slice(uint start, uint size) const
+ MutableAttributesRef slice(int64_t start, int64_t size) const
{
return MutableAttributesRef(*info_, buffers_, range_.slice(start, size));
}
};
-} // namespace blender::fn
+class AttributesRef {
+ private:
+ const AttributesInfo *info_;
+ Span<const void *> buffers_;
+ IndexRange range_;
+
+ public:
+ AttributesRef(const AttributesInfo &info, Span<const void *> buffers, int64_t size)
+ : AttributesRef(info, buffers, IndexRange(size))
+ {
+ }
+
+ AttributesRef(const AttributesInfo &info, Span<const void *> buffers, IndexRange range)
+ : info_(&info), buffers_(buffers), range_(range)
+ {
+ }
+
+ AttributesRef(MutableAttributesRef attributes)
+ : info_(attributes.info_), buffers_(attributes.buffers_), range_(attributes.range_)
+ {
+ }
+
+ int64_t size() const
+ {
+ return range_.size();
+ }
+
+ const AttributesInfo &info() const
+ {
+ return *info_;
+ }
+
+ GSpan get(int index) const
+ {
+ const CPPType &type = info_->type_of(index);
+ const void *ptr = POINTER_OFFSET(buffers_[index], type.size() * range_.start());
+ return GSpan(type, ptr, range_.size());
+ }
+
+ GSpan get(StringRef name) const
+ {
+ return this->get(info_->index_of(name));
+ }
-#endif /* __FN_ATTRIBUTES_REF_HH__ */
+ template<typename T> Span<T> get(int index) const
+ {
+ BLI_assert(info_->type_of(index).is<T>());
+ return Span<T>((T *)buffers_[index] + range_.start(), range_.size());
+ }
+
+ template<typename T> Span<T> get(StringRef name) const
+ {
+ return this->get<T>(info_->index_of(name));
+ }
+
+ std::optional<GSpan> try_get(StringRef name, const CPPType &type) const
+ {
+ int64_t index = info_->try_index_of(name, type);
+ if (index == -1) {
+ return {};
+ }
+ else {
+ return this->get(index);
+ }
+ }
+
+ template<typename T> std::optional<Span<T>> try_get(StringRef name) const
+ {
+ int index = info_->try_index_of(name);
+ if (index == -1) {
+ return {};
+ }
+ else if (info_->type_of(index).is<T>()) {
+ return this->get<T>(index);
+ }
+ else {
+ return {};
+ }
+ }
+
+ AttributesRef slice(IndexRange range) const
+ {
+ return this->slice(range.start(), range.size());
+ }
+
+ AttributesRef slice(int64_t start, int64_t size) const
+ {
+ return AttributesRef(*info_, buffers_, range_.slice(start, size));
+ }
+};
+
+} // namespace blender::fn
diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh
index 1681ff9fe8c..2f1d3f83c63 100644
--- a/source/blender/functions/FN_cpp_type.hh
+++ b/source/blender/functions/FN_cpp_type.hh
@@ -14,16 +14,15 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_CPP_TYPE_HH__
-#define __FN_CPP_TYPE_HH__
+#pragma once
/** \file
- * \ingroup functions
+ * \ingroup fn
*
- * The CPPType class is the core of the runtime-type-system used by the functions system. An
- * instance of this class can represent any C++ type, that is default-constructible, destructible,
- * movable and copyable. Therefore it also works for all C types. This restrictions might need to
- * be removed in the future, but for now every required type has these properties.
+ * The CPPType class is the core of the runtime-type-system used by the functions system. It can
+ * represent C++ types that are default-constructible, destructible, movable, copyable,
+ * equality comparable and hashable. In the future we might want to make some of these properties
+ * optional.
*
* Every type has a size and an alignment. Every function dealing with C++ types in a generic way,
* has to make sure that alignment rules are followed. The methods provided by a CPPType instance
@@ -38,11 +37,11 @@
* methods come in three variants. Using the construct-default methods as example:
* - construct_default(void *ptr):
* Constructs a single instance of that type at the given pointer.
- * - construct_default_n(void *ptr, uint n):
+ * - construct_default_n(void *ptr, int64_t n):
* Constructs n instances of that type in an array that starts at the given pointer.
- * - construct_default_indices(void *ptr, IndexMask index_mask):
+ * - construct_default_indices(void *ptr, IndexMask mask):
* Constructs multiple instances of that type in an array that starts at the given pointer.
- * Only the indices referenced by `index_mask` will by constructed.
+ * Only the indices referenced by `mask` will by constructed.
*
* In some cases default-construction does nothing (e.g. for trivial types like int). The
* `default_value` method provides some default value anyway that can be copied instead. What the
@@ -66,47 +65,97 @@
* pointers to virtual member functions.
*/
+#include "BLI_hash.hh"
#include "BLI_index_mask.hh"
#include "BLI_math_base.h"
#include "BLI_string_ref.hh"
+#include "BLI_utility_mixins.hh"
namespace blender::fn {
-class CPPType {
+class CPPType : NonCopyable, NonMovable {
public:
using ConstructDefaultF = void (*)(void *ptr);
- using ConstructDefaultNF = void (*)(void *ptr, uint n);
- using ConstructDefaultIndicesF = void (*)(void *ptr, IndexMask index_mask);
+ using ConstructDefaultNF = void (*)(void *ptr, int64_t n);
+ using ConstructDefaultIndicesF = void (*)(void *ptr, IndexMask mask);
using DestructF = void (*)(void *ptr);
- using DestructNF = void (*)(void *ptr, uint n);
- using DestructIndicesF = void (*)(void *ptr, IndexMask index_mask);
+ using DestructNF = void (*)(void *ptr, int64_t n);
+ using DestructIndicesF = void (*)(void *ptr, IndexMask mask);
using CopyToInitializedF = void (*)(const void *src, void *dst);
- using CopyToInitializedNF = void (*)(const void *src, void *dst, uint n);
- using CopyToInitializedIndicesF = void (*)(const void *src, void *dst, IndexMask index_mask);
+ using CopyToInitializedNF = void (*)(const void *src, void *dst, int64_t n);
+ using CopyToInitializedIndicesF = void (*)(const void *src, void *dst, IndexMask mask);
using CopyToUninitializedF = void (*)(const void *src, void *dst);
- using CopyToUninitializedNF = void (*)(const void *src, void *dst, uint n);
- using CopyToUninitializedIndicesF = void (*)(const void *src, void *dst, IndexMask index_mask);
+ using CopyToUninitializedNF = void (*)(const void *src, void *dst, int64_t n);
+ using CopyToUninitializedIndicesF = void (*)(const void *src, void *dst, IndexMask mask);
using RelocateToInitializedF = void (*)(void *src, void *dst);
- using RelocateToInitializedNF = void (*)(void *src, void *dst, uint n);
- using RelocateToInitializedIndicesF = void (*)(void *src, void *dst, IndexMask index_mask);
+ using RelocateToInitializedNF = void (*)(void *src, void *dst, int64_t n);
+ using RelocateToInitializedIndicesF = void (*)(void *src, void *dst, IndexMask mask);
using RelocateToUninitializedF = void (*)(void *src, void *dst);
- using RelocateToUninitializedNF = void (*)(void *src, void *dst, uint n);
- using RelocateToUninitializedIndicesF = void (*)(void *src, void *dst, IndexMask index_mask);
+ using RelocateToUninitializedNF = void (*)(void *src, void *dst, int64_t n);
+ using RelocateToUninitializedIndicesF = void (*)(void *src, void *dst, IndexMask mask);
- using FillInitializedF = void (*)(const void *value, void *dst, uint n);
- using FillInitializedIndicesF = void (*)(const void *value, void *dst, IndexMask index_mask);
+ using FillInitializedF = void (*)(const void *value, void *dst, int64_t n);
+ using FillInitializedIndicesF = void (*)(const void *value, void *dst, IndexMask mask);
- using FillUninitializedF = void (*)(const void *value, void *dst, uint n);
- using FillUninitializedIndicesF = void (*)(const void *value, void *dst, IndexMask index_mask);
+ using FillUninitializedF = void (*)(const void *value, void *dst, int64_t n);
+ using FillUninitializedIndicesF = void (*)(const void *value, void *dst, IndexMask mask);
+ using DebugPrintF = void (*)(const void *value, std::stringstream &ss);
+ using IsEqualF = bool (*)(const void *a, const void *b);
+ using HashF = uint64_t (*)(const void *value);
+
+ private:
+ int64_t size_;
+ int64_t alignment_;
+ uintptr_t alignment_mask_;
+ bool is_trivially_destructible_;
+
+ ConstructDefaultF construct_default_;
+ ConstructDefaultNF construct_default_n_;
+ ConstructDefaultIndicesF construct_default_indices_;
+
+ DestructF destruct_;
+ DestructNF destruct_n_;
+ DestructIndicesF destruct_indices_;
+
+ CopyToInitializedF copy_to_initialized_;
+ CopyToInitializedNF copy_to_initialized_n_;
+ CopyToInitializedIndicesF copy_to_initialized_indices_;
+
+ CopyToUninitializedF copy_to_uninitialized_;
+ CopyToUninitializedNF copy_to_uninitialized_n_;
+ CopyToUninitializedIndicesF copy_to_uninitialized_indices_;
+
+ RelocateToInitializedF relocate_to_initialized_;
+ RelocateToInitializedNF relocate_to_initialized_n_;
+ RelocateToInitializedIndicesF relocate_to_initialized_indices_;
+
+ RelocateToUninitializedF relocate_to_uninitialized_;
+ RelocateToUninitializedNF relocate_to_uninitialized_n_;
+ RelocateToUninitializedIndicesF relocate_to_uninitialized_indices_;
+
+ FillInitializedF fill_initialized_;
+ FillInitializedIndicesF fill_initialized_indices_;
+
+ FillUninitializedF fill_uninitialized_;
+ FillUninitializedIndicesF fill_uninitialized_indices_;
+
+ DebugPrintF debug_print_;
+ IsEqualF is_equal_;
+ HashF hash_;
+
+ const void *default_value_;
+ std::string name_;
+
+ public:
CPPType(std::string name,
- uint size,
- uint alignment,
+ int64_t size,
+ int64_t alignment,
bool is_trivially_destructible,
ConstructDefaultF construct_default,
ConstructDefaultNF construct_default_n,
@@ -130,6 +179,9 @@ class CPPType {
FillInitializedIndicesF fill_initialized_indices,
FillUninitializedF fill_uninitialized,
FillUninitializedIndicesF fill_uninitialized_indices,
+ DebugPrintF debug_print,
+ IsEqualF is_equal,
+ HashF hash,
const void *default_value)
: size_(size),
alignment_(alignment),
@@ -156,6 +208,9 @@ class CPPType {
fill_initialized_indices_(fill_initialized_indices),
fill_uninitialized_(fill_uninitialized),
fill_uninitialized_indices_(fill_uninitialized_indices),
+ debug_print_(debug_print),
+ is_equal_(is_equal),
+ hash_(hash),
default_value_(default_value),
name_(name)
{
@@ -164,6 +219,22 @@ class CPPType {
}
/**
+ * Two types only compare equal when their pointer is equal. No two instances of CPPType for the
+ * same C++ type should be created.
+ */
+ friend bool operator==(const CPPType &a, const CPPType &b)
+ {
+ return &a == &b;
+ }
+
+ friend bool operator!=(const CPPType &a, const CPPType &b)
+ {
+ return !(&a == &b);
+ }
+
+ template<typename T> static const CPPType &get();
+
+ /**
* Returns the name of the type for debugging purposes. This name should not be used as
* identifier.
*/
@@ -178,7 +249,7 @@ class CPPType {
* C++ equivalent:
* sizeof(T);
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -189,7 +260,7 @@ class CPPType {
* C++ equivalent:
* alignof(T);
*/
- uint alignment() const
+ int64_t alignment() const
{
return alignment_;
}
@@ -199,7 +270,7 @@ class CPPType {
* for optimization purposes.
*
* C++ equivalent:
- * std::is_trivially_destructible<T>::value;
+ * std::is_trivially_destructible_v<T>;
*/
bool is_trivially_destructible() const
{
@@ -234,18 +305,18 @@ class CPPType {
construct_default_(ptr);
}
- void construct_default_n(void *ptr, uint n) const
+ void construct_default_n(void *ptr, int64_t n) const
{
- BLI_assert(this->pointer_has_valid_alignment(ptr));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(ptr));
construct_default_n_(ptr, n);
}
- void construct_default_indices(void *ptr, IndexMask index_mask) const
+ void construct_default_indices(void *ptr, IndexMask mask) const
{
- BLI_assert(this->pointer_has_valid_alignment(ptr));
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(ptr));
- construct_default_indices_(ptr, index_mask);
+ construct_default_indices_(ptr, mask);
}
/**
@@ -263,18 +334,23 @@ class CPPType {
destruct_(ptr);
}
- void destruct_n(void *ptr, uint n) const
+ void destruct_n(void *ptr, int64_t n) const
{
- BLI_assert(this->pointer_has_valid_alignment(ptr));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(ptr));
destruct_n_(ptr, n);
}
- void destruct_indices(void *ptr, IndexMask index_mask) const
+ void destruct_indices(void *ptr, IndexMask mask) const
{
- BLI_assert(this->pointer_has_valid_alignment(ptr));
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(ptr));
- destruct_indices_(ptr, index_mask);
+ destruct_indices_(ptr, mask);
+ }
+
+ DestructF destruct_cb() const
+ {
+ return destruct_;
}
/**
@@ -292,22 +368,22 @@ class CPPType {
copy_to_initialized_(src, dst);
}
- void copy_to_initialized_n(const void *src, void *dst, uint n) const
+ void copy_to_initialized_n(const void *src, void *dst, int64_t n) const
{
- BLI_assert(src != dst);
- BLI_assert(this->pointer_has_valid_alignment(src));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(n == 0 || src != dst);
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
copy_to_initialized_n_(src, dst, n);
}
- void copy_to_initialized_indices(const void *src, void *dst, IndexMask index_mask) const
+ void copy_to_initialized_indices(const void *src, void *dst, IndexMask mask) const
{
- BLI_assert(src != dst);
- BLI_assert(this->pointer_has_valid_alignment(src));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(mask.size() == 0 || src != dst);
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
- copy_to_initialized_indices_(src, dst, index_mask);
+ copy_to_initialized_indices_(src, dst, mask);
}
/**
@@ -327,22 +403,22 @@ class CPPType {
copy_to_uninitialized_(src, dst);
}
- void copy_to_uninitialized_n(const void *src, void *dst, uint n) const
+ void copy_to_uninitialized_n(const void *src, void *dst, int64_t n) const
{
- BLI_assert(src != dst);
- BLI_assert(this->pointer_has_valid_alignment(src));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(n == 0 || src != dst);
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
copy_to_uninitialized_n_(src, dst, n);
}
- void copy_to_uninitialized_indices(const void *src, void *dst, IndexMask index_mask) const
+ void copy_to_uninitialized_indices(const void *src, void *dst, IndexMask mask) const
{
- BLI_assert(src != dst);
- BLI_assert(this->pointer_has_valid_alignment(src));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(mask.size() == 0 || src != dst);
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
- copy_to_uninitialized_indices_(src, dst, index_mask);
+ copy_to_uninitialized_indices_(src, dst, mask);
}
/**
@@ -362,22 +438,22 @@ class CPPType {
relocate_to_initialized_(src, dst);
}
- void relocate_to_initialized_n(void *src, void *dst, uint n) const
+ void relocate_to_initialized_n(void *src, void *dst, int64_t n) const
{
- BLI_assert(src != dst);
- BLI_assert(this->pointer_has_valid_alignment(src));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(n == 0 || src != dst);
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
relocate_to_initialized_n_(src, dst, n);
}
- void relocate_to_initialized_indices(void *src, void *dst, IndexMask index_mask) const
+ void relocate_to_initialized_indices(void *src, void *dst, IndexMask mask) const
{
- BLI_assert(src != dst);
- BLI_assert(this->pointer_has_valid_alignment(src));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(mask.size() == 0 || src != dst);
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
- relocate_to_initialized_indices_(src, dst, index_mask);
+ relocate_to_initialized_indices_(src, dst, mask);
}
/**
@@ -397,22 +473,22 @@ class CPPType {
relocate_to_uninitialized_(src, dst);
}
- void relocate_to_uninitialized_n(void *src, void *dst, uint n) const
+ void relocate_to_uninitialized_n(void *src, void *dst, int64_t n) const
{
- BLI_assert(src != dst);
- BLI_assert(this->pointer_has_valid_alignment(src));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(n == 0 || src != dst);
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
relocate_to_uninitialized_n_(src, dst, n);
}
- void relocate_to_uninitialized_indices(void *src, void *dst, IndexMask index_mask) const
+ void relocate_to_uninitialized_indices(void *src, void *dst, IndexMask mask) const
{
- BLI_assert(src != dst);
- BLI_assert(this->pointer_has_valid_alignment(src));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(mask.size() == 0 || src != dst);
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
- relocate_to_uninitialized_indices_(src, dst, index_mask);
+ relocate_to_uninitialized_indices_(src, dst, mask);
}
/**
@@ -420,20 +496,20 @@ class CPPType {
*
* Other instances of the same type should live in the array before this method is called.
*/
- void fill_initialized(const void *value, void *dst, uint n) const
+ void fill_initialized(const void *value, void *dst, int64_t n) const
{
- BLI_assert(this->pointer_can_point_to_instance(value));
- BLI_assert(this->pointer_can_point_to_instance(dst));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(value));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
fill_initialized_(value, dst, n);
}
- void fill_initialized_indices(const void *value, void *dst, IndexMask index_mask) const
+ void fill_initialized_indices(const void *value, void *dst, IndexMask mask) const
{
- BLI_assert(this->pointer_has_valid_alignment(value));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(value));
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
- fill_initialized_indices_(value, dst, index_mask);
+ fill_initialized_indices_(value, dst, mask);
}
/**
@@ -441,20 +517,39 @@ class CPPType {
*
* The array should be uninitialized before this method is called.
*/
- void fill_uninitialized(const void *value, void *dst, uint n) const
+ void fill_uninitialized(const void *value, void *dst, int64_t n) const
{
- BLI_assert(this->pointer_can_point_to_instance(value));
- BLI_assert(this->pointer_can_point_to_instance(dst));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(value));
+ BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
fill_uninitialized_(value, dst, n);
}
- void fill_uninitialized_indices(const void *value, void *dst, IndexMask index_mask) const
+ void fill_uninitialized_indices(const void *value, void *dst, IndexMask mask) const
+ {
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(value));
+ BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
+
+ fill_uninitialized_indices_(value, dst, mask);
+ }
+
+ void debug_print(const void *value, std::stringstream &ss) const
+ {
+ BLI_assert(this->pointer_can_point_to_instance(value));
+ debug_print_(value, ss);
+ }
+
+ bool is_equal(const void *a, const void *b) const
{
- BLI_assert(this->pointer_has_valid_alignment(value));
- BLI_assert(this->pointer_has_valid_alignment(dst));
+ BLI_assert(this->pointer_can_point_to_instance(a));
+ BLI_assert(this->pointer_can_point_to_instance(b));
+ return is_equal_(a, b);
+ }
- fill_uninitialized_indices_(value, dst, index_mask);
+ uint64_t hash(const void *value) const
+ {
+ BLI_assert(this->pointer_can_point_to_instance(value));
+ return hash_(value);
}
/**
@@ -466,137 +561,87 @@ class CPPType {
return default_value_;
}
- /**
- * Two types only compare equal when their pointer is equal. No two instances of CPPType for the
- * same C++ type should be created.
- */
- friend bool operator==(const CPPType &a, const CPPType &b)
+ uint64_t hash() const
{
- return &a == &b;
+ return DefaultHash<const CPPType *>{}(this);
}
- friend bool operator!=(const CPPType &a, const CPPType &b)
- {
- return !(&a == &b);
- }
-
- template<typename T> static const CPPType &get();
-
template<typename T> bool is() const
{
return this == &CPPType::get<T>();
}
-
- private:
- uint size_;
- uint alignment_;
- uintptr_t alignment_mask_;
- bool is_trivially_destructible_;
-
- ConstructDefaultF construct_default_;
- ConstructDefaultNF construct_default_n_;
- ConstructDefaultIndicesF construct_default_indices_;
-
- DestructF destruct_;
- DestructNF destruct_n_;
- DestructIndicesF destruct_indices_;
-
- CopyToInitializedF copy_to_initialized_;
- CopyToInitializedNF copy_to_initialized_n_;
- CopyToInitializedIndicesF copy_to_initialized_indices_;
-
- CopyToUninitializedF copy_to_uninitialized_;
- CopyToUninitializedNF copy_to_uninitialized_n_;
- CopyToUninitializedIndicesF copy_to_uninitialized_indices_;
-
- RelocateToInitializedF relocate_to_initialized_;
- RelocateToInitializedNF relocate_to_initialized_n_;
- RelocateToInitializedIndicesF relocate_to_initialized_indices_;
-
- RelocateToUninitializedF relocate_to_uninitialized_;
- RelocateToUninitializedNF relocate_to_uninitialized_n_;
- RelocateToUninitializedIndicesF relocate_to_uninitialized_indices_;
-
- FillInitializedF fill_initialized_;
- FillInitializedIndicesF fill_initialized_indices_;
-
- FillUninitializedF fill_uninitialized_;
- FillUninitializedIndicesF fill_uninitialized_indices_;
-
- const void *default_value_;
- std::string name_;
};
/* --------------------------------------------------------------------
* Utility for creating CPPType instances for C++ types.
*/
-namespace CPPTypeUtil {
+namespace cpp_type_util {
template<typename T> void construct_default_cb(void *ptr)
{
new (ptr) T;
}
-template<typename T> void construct_default_n_cb(void *ptr, uint n)
+template<typename T> void construct_default_n_cb(void *ptr, int64_t n)
{
blender::default_construct_n((T *)ptr, n);
}
-template<typename T> void construct_default_indices_cb(void *ptr, IndexMask index_mask)
+template<typename T> void construct_default_indices_cb(void *ptr, IndexMask mask)
{
- index_mask.foreach_index([&](uint i) { new ((T *)ptr + i) T; });
+ mask.foreach_index([&](int64_t i) { new ((T *)ptr + i) T; });
}
template<typename T> void destruct_cb(void *ptr)
{
((T *)ptr)->~T();
}
-template<typename T> void destruct_n_cb(void *ptr, uint n)
+template<typename T> void destruct_n_cb(void *ptr, int64_t n)
{
blender::destruct_n((T *)ptr, n);
}
-template<typename T> void destruct_indices_cb(void *ptr, IndexMask index_mask)
+template<typename T> void destruct_indices_cb(void *ptr, IndexMask mask)
{
T *ptr_ = (T *)ptr;
- index_mask.foreach_index([&](uint i) { ptr_[i].~T(); });
+ mask.foreach_index([&](int64_t i) { ptr_[i].~T(); });
}
template<typename T> void copy_to_initialized_cb(const void *src, void *dst)
{
*(T *)dst = *(T *)src;
}
-template<typename T> void copy_to_initialized_n_cb(const void *src, void *dst, uint n)
+template<typename T> void copy_to_initialized_n_cb(const void *src, void *dst, int64_t n)
{
const T *src_ = (const T *)src;
T *dst_ = (T *)dst;
- for (uint i = 0; i < n; i++) {
+ for (int64_t i = 0; i < n; i++) {
dst_[i] = src_[i];
}
}
template<typename T>
-void copy_to_initialized_indices_cb(const void *src, void *dst, IndexMask index_mask)
+void copy_to_initialized_indices_cb(const void *src, void *dst, IndexMask mask)
{
const T *src_ = (const T *)src;
T *dst_ = (T *)dst;
- index_mask.foreach_index([&](uint i) { dst_[i] = src_[i]; });
+ mask.foreach_index([&](int64_t i) { dst_[i] = src_[i]; });
}
template<typename T> void copy_to_uninitialized_cb(const void *src, void *dst)
{
blender::uninitialized_copy_n((T *)src, 1, (T *)dst);
}
-template<typename T> void copy_to_uninitialized_n_cb(const void *src, void *dst, uint n)
+template<typename T> void copy_to_uninitialized_n_cb(const void *src, void *dst, int64_t n)
{
blender::uninitialized_copy_n((T *)src, n, (T *)dst);
}
template<typename T>
-void copy_to_uninitialized_indices_cb(const void *src, void *dst, IndexMask index_mask)
+void copy_to_uninitialized_indices_cb(const void *src, void *dst, IndexMask mask)
{
const T *src_ = (const T *)src;
T *dst_ = (T *)dst;
- index_mask.foreach_index([&](uint i) { new (dst_ + i) T(src_[i]); });
+ mask.foreach_index([&](int64_t i) { new (dst_ + i) T(src_[i]); });
}
template<typename T> void relocate_to_initialized_cb(void *src, void *dst)
@@ -607,17 +652,16 @@ template<typename T> void relocate_to_initialized_cb(void *src, void *dst)
*dst_ = std::move(*src_);
src_->~T();
}
-template<typename T> void relocate_to_initialized_n_cb(void *src, void *dst, uint n)
+template<typename T> void relocate_to_initialized_n_cb(void *src, void *dst, int64_t n)
{
blender::initialized_relocate_n((T *)src, n, (T *)dst);
}
-template<typename T>
-void relocate_to_initialized_indices_cb(void *src, void *dst, IndexMask index_mask)
+template<typename T> void relocate_to_initialized_indices_cb(void *src, void *dst, IndexMask mask)
{
T *src_ = (T *)src;
T *dst_ = (T *)dst;
- index_mask.foreach_index([&](uint i) {
+ mask.foreach_index([&](int64_t i) {
dst_[i] = std::move(src_[i]);
src_[i].~T();
});
@@ -631,68 +675,86 @@ template<typename T> void relocate_to_uninitialized_cb(void *src, void *dst)
new (dst_) T(std::move(*src_));
src_->~T();
}
-template<typename T> void relocate_to_uninitialized_n_cb(void *src, void *dst, uint n)
+template<typename T> void relocate_to_uninitialized_n_cb(void *src, void *dst, int64_t n)
{
blender::uninitialized_relocate_n((T *)src, n, (T *)dst);
}
template<typename T>
-void relocate_to_uninitialized_indices_cb(void *src, void *dst, IndexMask index_mask)
+void relocate_to_uninitialized_indices_cb(void *src, void *dst, IndexMask mask)
{
T *src_ = (T *)src;
T *dst_ = (T *)dst;
- index_mask.foreach_index([&](uint i) {
+ mask.foreach_index([&](int64_t i) {
new (dst_ + i) T(std::move(src_[i]));
src_[i].~T();
});
}
-template<typename T> void fill_initialized_cb(const void *value, void *dst, uint n)
+template<typename T> void fill_initialized_cb(const void *value, void *dst, int64_t n)
{
const T &value_ = *(const T *)value;
T *dst_ = (T *)dst;
- for (uint i = 0; i < n; i++) {
+ for (int64_t i = 0; i < n; i++) {
dst_[i] = value_;
}
}
-template<typename T>
-void fill_initialized_indices_cb(const void *value, void *dst, IndexMask index_mask)
+template<typename T> void fill_initialized_indices_cb(const void *value, void *dst, IndexMask mask)
{
const T &value_ = *(const T *)value;
T *dst_ = (T *)dst;
- index_mask.foreach_index([&](uint i) { dst_[i] = value_; });
+ mask.foreach_index([&](int64_t i) { dst_[i] = value_; });
}
-template<typename T> void fill_uninitialized_cb(const void *value, void *dst, uint n)
+template<typename T> void fill_uninitialized_cb(const void *value, void *dst, int64_t n)
{
const T &value_ = *(const T *)value;
T *dst_ = (T *)dst;
- for (uint i = 0; i < n; i++) {
+ for (int64_t i = 0; i < n; i++) {
new (dst_ + i) T(value_);
}
}
template<typename T>
-void fill_uninitialized_indices_cb(const void *value, void *dst, IndexMask index_mask)
+void fill_uninitialized_indices_cb(const void *value, void *dst, IndexMask mask)
{
const T &value_ = *(const T *)value;
T *dst_ = (T *)dst;
- index_mask.foreach_index([&](uint i) { new (dst_ + i) T(value_); });
+ mask.foreach_index([&](int64_t i) { new (dst_ + i) T(value_); });
+}
+
+template<typename T> void debug_print_cb(const void *value, std::stringstream &ss)
+{
+ const T &value_ = *(const T *)value;
+ ss << value_;
+}
+
+template<typename T> bool is_equal_cb(const void *a, const void *b)
+{
+ const T &a_ = *(T *)a;
+ const T &b_ = *(T *)b;
+ return a_ == b_;
}
-} // namespace CPPTypeUtil
+template<typename T> uint64_t hash_cb(const void *value)
+{
+ const T &value_ = *(const T *)value;
+ return DefaultHash<T>{}(value_);
+}
+
+} // namespace cpp_type_util
template<typename T>
-static std::unique_ptr<const CPPType> create_cpp_type(StringRef name, const T &default_value)
+inline std::unique_ptr<const CPPType> create_cpp_type(StringRef name, const T &default_value)
{
- using namespace CPPTypeUtil;
+ using namespace cpp_type_util;
const CPPType *type = new CPPType(name,
sizeof(T),
alignof(T),
- std::is_trivially_destructible<T>::value,
+ std::is_trivially_destructible_v<T>,
construct_default_cb<T>,
construct_default_n_cb<T>,
construct_default_indices_cb<T>,
@@ -715,6 +777,9 @@ static std::unique_ptr<const CPPType> create_cpp_type(StringRef name, const T &d
fill_initialized_indices_cb<T>,
fill_uninitialized_cb<T>,
fill_uninitialized_indices_cb<T>,
+ debug_print_cb<T>,
+ is_equal_cb<T>,
+ hash_cb<T>,
(const void *)&default_value);
return std::unique_ptr<const CPPType>(type);
}
@@ -722,15 +787,10 @@ static std::unique_ptr<const CPPType> create_cpp_type(StringRef name, const T &d
} // namespace blender::fn
#define MAKE_CPP_TYPE(IDENTIFIER, TYPE_NAME) \
- static TYPE_NAME default_value_##IDENTIFIER; \
- static std::unique_ptr<const blender::fn::CPPType> CPPTYPE_##IDENTIFIER##_owner = \
- blender::fn::create_cpp_type<TYPE_NAME>(STRINGIFY(IDENTIFIER), default_value_##IDENTIFIER); \
- const blender::fn::CPPType &CPPType_##IDENTIFIER = *CPPTYPE_##IDENTIFIER##_owner; \
template<> const blender::fn::CPPType &blender::fn::CPPType::get<TYPE_NAME>() \
{ \
- /* This can happen when trying to access a CPPType during static storage initialization. */ \
- BLI_assert(CPPTYPE_##IDENTIFIER##_owner.get() != nullptr); \
- return CPPType_##IDENTIFIER; \
+ static TYPE_NAME default_value; \
+ static std::unique_ptr<const CPPType> cpp_type = blender::fn::create_cpp_type<TYPE_NAME>( \
+ STRINGIFY(IDENTIFIER), default_value); \
+ return *cpp_type; \
}
-
-#endif /* __FN_CPP_TYPE_HH__ */
diff --git a/source/blender/functions/FN_generic_vector_array.hh b/source/blender/functions/FN_generic_vector_array.hh
index f28e94b34ee..0a173d1fbc6 100644
--- a/source/blender/functions/FN_generic_vector_array.hh
+++ b/source/blender/functions/FN_generic_vector_array.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_GENERIC_VECTOR_ARRAY_HH__
-#define __FN_GENERIC_VECTOR_ARRAY_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -42,10 +41,10 @@ template<typename T> class GVectorArrayRef;
class GVectorArray : NonCopyable, NonMovable {
private:
const CPPType &type_;
- uint element_size_;
+ int64_t element_size_;
Array<void *, 1> starts_;
- Array<uint, 1> lengths_;
- Array<uint, 1> capacities_;
+ Array<int64_t, 1> lengths_;
+ Array<int64_t, 1> capacities_;
LinearAllocator<> allocator_;
template<typename T> friend class GVectorArrayRef;
@@ -53,16 +52,16 @@ class GVectorArray : NonCopyable, NonMovable {
public:
GVectorArray() = delete;
- GVectorArray(const CPPType &type, uint array_size)
+ GVectorArray(const CPPType &type, int64_t array_size)
: type_(type),
element_size_(type.size()),
starts_(array_size),
lengths_(array_size),
capacities_(array_size)
{
- starts_.fill(nullptr);
- lengths_.fill(0);
- capacities_.fill(0);
+ starts_.as_mutable_span().fill(nullptr);
+ lengths_.as_mutable_span().fill(0);
+ capacities_.as_mutable_span().fill(0);
}
~GVectorArray()
@@ -71,14 +70,14 @@ class GVectorArray : NonCopyable, NonMovable {
return;
}
- for (uint i : starts_.index_range()) {
+ for (int64_t i : starts_.index_range()) {
type_.destruct_n(starts_[i], lengths_[i]);
}
}
operator GVArraySpan() const
{
- return GVArraySpan(type_, starts_.as_span(), lengths_);
+ return GVArraySpan(type_, starts_, lengths_);
}
bool is_empty() const
@@ -86,7 +85,7 @@ class GVectorArray : NonCopyable, NonMovable {
return starts_.size() == 0;
}
- uint size() const
+ int64_t size() const
{
return starts_.size();
}
@@ -98,17 +97,17 @@ class GVectorArray : NonCopyable, NonMovable {
Span<const void *> starts() const
{
- return starts_.as_span();
+ return starts_;
}
- Span<uint> lengths() const
+ Span<int64_t> lengths() const
{
return lengths_;
}
- void append(uint index, const void *src)
+ void append(int64_t index, const void *src)
{
- uint old_length = lengths_[index];
+ int64_t old_length = lengths_[index];
if (old_length == capacities_[index]) {
this->grow_at_least_one(index);
}
@@ -118,10 +117,10 @@ class GVectorArray : NonCopyable, NonMovable {
lengths_[index]++;
}
- void extend(uint index, GVSpan span)
+ void extend(int64_t index, GVSpan span)
{
BLI_assert(type_ == span.type());
- for (uint i = 0; i < span.size(); i++) {
+ for (int64_t i = 0; i < span.size(); i++) {
this->append(index, span[i]);
}
}
@@ -130,12 +129,12 @@ class GVectorArray : NonCopyable, NonMovable {
{
BLI_assert(type_ == array_span.type());
BLI_assert(mask.min_array_size() <= array_span.size());
- for (uint i : mask) {
+ for (int64_t i : mask) {
this->extend(i, array_span[i]);
}
}
- GMutableSpan operator[](uint index)
+ GMutableSpan operator[](int64_t index)
{
BLI_assert(index < starts_.size());
return GMutableSpan(type_, starts_[index], lengths_[index]);
@@ -146,10 +145,10 @@ class GVectorArray : NonCopyable, NonMovable {
}
private:
- void grow_at_least_one(uint index)
+ void grow_at_least_one(int64_t index)
{
BLI_assert(lengths_[index] == capacities_[index]);
- uint new_capacity = lengths_[index] * 2 + 1;
+ int64_t new_capacity = lengths_[index] * 2 + 1;
void *new_buffer = allocator_.allocate(element_size_ * new_capacity, type_.alignment());
type_.relocate_to_uninitialized_n(starts_[index], new_buffer, lengths_[index]);
@@ -169,28 +168,28 @@ template<typename T> class GVectorArrayRef {
BLI_assert(vector_array.type_.is<T>());
}
- void append(uint index, const T &value)
+ void append(int64_t index, const T &value)
{
vector_array_->append(index, &value);
}
- void extend(uint index, Span<T> values)
+ void extend(int64_t index, Span<T> values)
{
vector_array_->extend(index, values);
}
- void extend(uint index, VSpan<T> values)
+ void extend(int64_t index, VSpan<T> values)
{
vector_array_->extend(index, GVSpan(values));
}
- MutableSpan<T> operator[](uint index)
+ MutableSpan<T> operator[](int64_t index)
{
BLI_assert(index < vector_array_->starts_.size());
return MutableSpan<T>((T *)vector_array_->starts_[index], vector_array_->lengths_[index]);
}
- uint size() const
+ int64_t size() const
{
return vector_array_->size();
}
@@ -202,5 +201,3 @@ template<typename T> class GVectorArrayRef {
};
} // namespace blender::fn
-
-#endif /* __FN_GENERIC_VECTOR_ARRAY_HH__ */
diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh
index 452fd5472ce..bf431984946 100644
--- a/source/blender/functions/FN_multi_function.hh
+++ b/source/blender/functions/FN_multi_function.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_MULTI_FUNCTION_HH__
-#define __FN_MULTI_FUNCTION_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -45,6 +44,8 @@
* 3. Override the `call` function.
*/
+#include "BLI_hash.hh"
+
#include "FN_multi_function_context.hh"
#include "FN_multi_function_params.hh"
@@ -61,17 +62,32 @@ class MultiFunction {
virtual void call(IndexMask mask, MFParams params, MFContext context) const = 0;
+ virtual uint64_t hash() const
+ {
+ return DefaultHash<const MultiFunction *>{}(this);
+ }
+
+ virtual bool equals(const MultiFunction &UNUSED(other)) const
+ {
+ return false;
+ }
+
+ int param_amount() const
+ {
+ return signature_.param_types.size();
+ }
+
IndexRange param_indices() const
{
return signature_.param_types.index_range();
}
- MFParamType param_type(uint param_index) const
+ MFParamType param_type(int param_index) const
{
return signature_.param_types[param_index];
}
- StringRefNull param_name(uint param_index) const
+ StringRefNull param_name(int param_index) const
{
return signature_.param_names[param_index];
}
@@ -81,6 +97,11 @@ class MultiFunction {
return signature_.function_name;
}
+ bool depends_on_context() const
+ {
+ return signature_.depends_on_context;
+ }
+
const MFSignature &signature() const
{
return signature_;
@@ -94,7 +115,7 @@ class MultiFunction {
}
};
-inline MFParamsBuilder::MFParamsBuilder(const class MultiFunction &fn, uint min_array_size)
+inline MFParamsBuilder::MFParamsBuilder(const class MultiFunction &fn, int64_t min_array_size)
: MFParamsBuilder(fn.signature(), min_array_size)
{
}
@@ -102,5 +123,3 @@ inline MFParamsBuilder::MFParamsBuilder(const class MultiFunction &fn, uint min_
extern const MultiFunction &dummy_multi_function;
} // namespace blender::fn
-
-#endif /* __FN_MULTI_FUNCTION_HH__ */
diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh
index abc1e5d0723..dee0938eb3a 100644
--- a/source/blender/functions/FN_multi_function_builder.hh
+++ b/source/blender/functions/FN_multi_function_builder.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_MULTI_FUNCTION_BUILDER_HH__
-#define __FN_MULTI_FUNCTION_BUILDER_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -59,7 +58,7 @@ template<typename In1, typename Out1> class CustomMF_SI_SO : public MultiFunctio
template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
{
return [=](IndexMask mask, VSpan<In1> in1, MutableSpan<Out1> out1) {
- mask.foreach_index([&](uint i) { new ((void *)&out1[i]) Out1(element_fn(in1[i])); });
+ mask.foreach_index([&](int i) { new ((void *)&out1[i]) Out1(element_fn(in1[i])); });
};
}
@@ -101,7 +100,7 @@ class CustomMF_SI_SI_SO : public MultiFunction {
template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
{
return [=](IndexMask mask, VSpan<In1> in1, VSpan<In2> in2, MutableSpan<Out1> out1) {
- mask.foreach_index([&](uint i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i])); });
+ mask.foreach_index([&](int i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i])); });
};
}
@@ -152,7 +151,7 @@ class CustomMF_SI_SI_SI_SO : public MultiFunction {
VSpan<In3> in3,
MutableSpan<Out1> out1) {
mask.foreach_index(
- [&](uint i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i], in3[i])); });
+ [&](int i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i], in3[i])); });
};
}
@@ -191,7 +190,7 @@ template<typename Mut1> class CustomMF_SM : public MultiFunction {
template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
{
return [=](IndexMask mask, MutableSpan<Mut1> mut1) {
- mask.foreach_index([&](uint i) { element_fn(mut1[i]); });
+ mask.foreach_index([&](int i) { element_fn(mut1[i]); });
};
}
@@ -203,6 +202,61 @@ template<typename Mut1> class CustomMF_SM : public MultiFunction {
};
/**
+ * Generates a multi-function that converts between two types.
+ */
+template<typename From, typename To> class CustomMF_Convert : public MultiFunction {
+ public:
+ CustomMF_Convert()
+ {
+ std::string name = CPPType::get<From>().name() + " to " + CPPType::get<To>().name();
+ MFSignatureBuilder signature = this->get_builder(std::move(name));
+ signature.single_input<From>("Input");
+ signature.single_output<To>("Output");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<From> inputs = params.readonly_single_input<From>(0);
+ MutableSpan<To> outputs = params.uninitialized_single_output<To>(1);
+
+ for (int64_t i : mask) {
+ new ((void *)&outputs[i]) To(inputs[i]);
+ }
+ }
+};
+
+/**
+ * A multi-function that outputs the same value every time. The value is not owned by an instance
+ * of this function. The caller is responsible for destructing and freeing the value.
+ */
+class CustomMF_GenericConstant : public MultiFunction {
+ private:
+ const CPPType &type_;
+ const void *value_;
+
+ template<typename T> friend class CustomMF_Constant;
+
+ public:
+ CustomMF_GenericConstant(const CPPType &type, const void *value);
+ void call(IndexMask mask, MFParams params, MFContext context) const override;
+ uint64_t hash() const override;
+ bool equals(const MultiFunction &other) const override;
+};
+
+/**
+ * A multi-function that outputs the same array every time. The array is not owned by in instance
+ * of this function. The caller is responsible for destructing and freeing the values.
+ */
+class CustomMF_GenericConstantArray : public MultiFunction {
+ private:
+ GSpan array_;
+
+ public:
+ CustomMF_GenericConstantArray(GSpan array);
+ void call(IndexMask mask, MFParams params, MFContext context) const override;
+};
+
+/**
* Generates a multi-function that outputs a constant value.
*/
template<typename T> class CustomMF_Constant : public MultiFunction {
@@ -221,10 +275,41 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
{
MutableSpan<T> output = params.uninitialized_single_output<T>(0);
- mask.foreach_index([&](uint i) { new (&output[i]) T(value_); });
+ mask.foreach_index([&](int i) { new (&output[i]) T(value_); });
+ }
+
+ uint64_t hash() const override
+ {
+ return DefaultHash<T>{}(value_);
+ }
+
+ bool equals(const MultiFunction &other) const override
+ {
+ const CustomMF_Constant *other1 = dynamic_cast<const CustomMF_Constant *>(&other);
+ if (other1 != nullptr) {
+ return value_ == other1->value_;
+ }
+ const CustomMF_GenericConstant *other2 = dynamic_cast<const CustomMF_GenericConstant *>(
+ &other);
+ if (other2 != nullptr) {
+ const CPPType &type = CPPType::get<T>();
+ if (type == other2->type_) {
+ return type.is_equal((const void *)&value_, other2->value_);
+ }
+ }
+ return false;
}
};
-} // namespace blender::fn
+class CustomMF_DefaultOutput : public MultiFunction {
+ private:
+ int output_amount_;
-#endif /* __FN_MULTI_FUNCTION_BUILDER_HH__ */
+ public:
+ CustomMF_DefaultOutput(StringRef name,
+ Span<MFDataType> input_types,
+ Span<MFDataType> output_types);
+ void call(IndexMask mask, MFParams params, MFContext context) const override;
+};
+
+} // namespace blender::fn
diff --git a/source/blender/functions/FN_multi_function_context.hh b/source/blender/functions/FN_multi_function_context.hh
index 3a448cc2c6e..eec6b21ae7c 100644
--- a/source/blender/functions/FN_multi_function_context.hh
+++ b/source/blender/functions/FN_multi_function_context.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_MULTI_FUNCTION_CONTEXT_HH__
-#define __FN_MULTI_FUNCTION_CONTEXT_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -29,18 +28,40 @@
#include "BLI_utildefines.h"
+#include "BLI_map.hh"
+
namespace blender::fn {
+class MFContext;
+
class MFContextBuilder {
+ private:
+ Map<std::string, const void *> global_contexts_;
+
+ friend MFContext;
+
+ public:
+ template<typename T> void add_global_context(std::string name, const T *context)
+ {
+ global_contexts_.add_new(std::move(name), (const void *)context);
+ }
};
class MFContext {
+ private:
+ MFContextBuilder &builder_;
+
public:
- MFContext(MFContextBuilder &UNUSED(builder))
+ MFContext(MFContextBuilder &builder) : builder_(builder)
+ {
+ }
+
+ template<typename T> const T *get_global_context(StringRef name) const
{
+ const void *context = builder_.global_contexts_.lookup_default_as(name, nullptr);
+ /* TODO: Implement type checking. */
+ return (const T *)context;
}
};
} // namespace blender::fn
-
-#endif /* __FN_MULTI_FUNCTION_CONTEXT_HH__ */
diff --git a/source/blender/functions/FN_multi_function_data_type.hh b/source/blender/functions/FN_multi_function_data_type.hh
index 78f0d96fb80..34997703432 100644
--- a/source/blender/functions/FN_multi_function_data_type.hh
+++ b/source/blender/functions/FN_multi_function_data_type.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_MULTI_FUNCTION_DATA_TYPE_HH__
-#define __FN_MULTI_FUNCTION_DATA_TYPE_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -108,6 +107,11 @@ class MFDataType {
BLI_assert(false);
return "";
}
+
+ uint64_t hash() const
+ {
+ return DefaultHash<CPPType>{}(*type_) + (uint64_t)category_;
+ }
};
inline bool operator==(const MFDataType &a, const MFDataType &b)
@@ -121,5 +125,3 @@ inline bool operator!=(const MFDataType &a, const MFDataType &b)
}
} // namespace blender::fn
-
-#endif /* __FN_MULTI_FUNCTION_DATA_TYPE_HH__ */
diff --git a/source/blender/functions/FN_multi_function_network.hh b/source/blender/functions/FN_multi_function_network.hh
index a9d8508cdb8..7a9f5b4cfaf 100644
--- a/source/blender/functions/FN_multi_function_network.hh
+++ b/source/blender/functions/FN_multi_function_network.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_MULTI_FUNCTION_NETWORK_HH__
-#define __FN_MULTI_FUNCTION_NETWORK_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -62,14 +61,14 @@ class MFNode : NonCopyable, NonMovable {
Span<MFInputSocket *> inputs_;
Span<MFOutputSocket *> outputs_;
bool is_dummy_;
- uint id_;
+ int id_;
friend MFNetwork;
public:
StringRefNull name() const;
- uint id() const;
+ int id() const;
MFNetwork &network();
const MFNetwork &network() const;
@@ -83,11 +82,11 @@ class MFNode : NonCopyable, NonMovable {
MFFunctionNode &as_function();
const MFFunctionNode &as_function() const;
- MFInputSocket &input(uint index);
- const MFInputSocket &input(uint index) const;
+ MFInputSocket &input(int index);
+ const MFInputSocket &input(int index) const;
- MFOutputSocket &output(uint index);
- const MFOutputSocket &output(uint index) const;
+ MFOutputSocket &output(int index);
+ const MFOutputSocket &output(int index) const;
Span<MFInputSocket *> inputs();
Span<const MFInputSocket *> inputs() const;
@@ -95,9 +94,7 @@ class MFNode : NonCopyable, NonMovable {
Span<MFOutputSocket *> outputs();
Span<const MFOutputSocket *> outputs() const;
- template<typename FuncT> void foreach_origin_socket(const FuncT &func) const;
-
- bool all_inputs_have_origin() const;
+ bool has_unlinked_inputs() const;
private:
void destruct_sockets();
@@ -106,8 +103,8 @@ class MFNode : NonCopyable, NonMovable {
class MFFunctionNode : public MFNode {
private:
const MultiFunction *function_;
- Span<uint> input_param_indices_;
- Span<uint> output_param_indices_;
+ Span<int> input_param_indices_;
+ Span<int> output_param_indices_;
friend MFNetwork;
@@ -116,8 +113,8 @@ class MFFunctionNode : public MFNode {
const MultiFunction &function() const;
- const MFInputSocket &input_for_param(uint param_index) const;
- const MFOutputSocket &output_for_param(uint param_index) const;
+ const MFInputSocket &input_for_param(int param_index) const;
+ const MFOutputSocket &output_for_param(int param_index) const;
};
class MFDummyNode : public MFNode {
@@ -139,9 +136,9 @@ class MFSocket : NonCopyable, NonMovable {
protected:
MFNode *node_;
bool is_output_;
- uint index_;
+ int index_;
MFDataType data_type_;
- uint id_;
+ int id_;
StringRefNull name_;
friend MFNetwork;
@@ -149,7 +146,8 @@ class MFSocket : NonCopyable, NonMovable {
public:
StringRefNull name() const;
- uint id() const;
+ int id() const;
+ int index() const;
const MFDataType &data_type() const;
@@ -216,10 +214,27 @@ class MFNetwork : NonCopyable, NonMovable {
void relink(MFOutputSocket &old_output, MFOutputSocket &new_output);
void remove(MFNode &node);
+ void remove(Span<MFNode *> nodes);
+
+ int socket_id_amount() const;
+ int node_id_amount() const;
+
+ Span<MFDummyNode *> dummy_nodes();
+ Span<MFFunctionNode *> function_nodes();
+
+ MFNode *node_or_null_by_id(int id);
+ const MFNode *node_or_null_by_id(int id) const;
+
+ MFSocket *socket_or_null_by_id(int id);
+ const MFSocket *socket_or_null_by_id(int id) const;
- uint max_socket_id() const;
+ void find_dependencies(Span<const MFInputSocket *> sockets,
+ VectorSet<const MFOutputSocket *> &r_dummy_sockets,
+ VectorSet<const MFInputSocket *> &r_unlinked_inputs) const;
- std::string to_dot() const;
+ bool have_dummy_or_unlinked_dependencies(Span<const MFInputSocket *> sockets) const;
+
+ std::string to_dot(Span<const MFNode *> marked_nodes = {}) const;
};
/* --------------------------------------------------------------------
@@ -236,7 +251,7 @@ inline StringRefNull MFNode::name() const
}
}
-inline uint MFNode::id() const
+inline int MFNode::id() const
{
return id_;
}
@@ -285,22 +300,22 @@ inline const MFFunctionNode &MFNode::as_function() const
return *(const MFFunctionNode *)this;
}
-inline MFInputSocket &MFNode::input(uint index)
+inline MFInputSocket &MFNode::input(int index)
{
return *inputs_[index];
}
-inline const MFInputSocket &MFNode::input(uint index) const
+inline const MFInputSocket &MFNode::input(int index) const
{
return *inputs_[index];
}
-inline MFOutputSocket &MFNode::output(uint index)
+inline MFOutputSocket &MFNode::output(int index)
{
return *outputs_[index];
}
-inline const MFOutputSocket &MFNode::output(uint index) const
+inline const MFOutputSocket &MFNode::output(int index) const
{
return *outputs_[index];
}
@@ -325,24 +340,14 @@ inline Span<const MFOutputSocket *> MFNode::outputs() const
return outputs_;
}
-template<typename FuncT> void MFNode::foreach_origin_socket(const FuncT &func) const
-{
- for (const MFInputSocket *socket : inputs_) {
- const MFOutputSocket *origin = socket->origin();
- if (origin != nullptr) {
- func(*origin);
- }
- }
-}
-
-inline bool MFNode::all_inputs_have_origin() const
+inline bool MFNode::has_unlinked_inputs() const
{
for (const MFInputSocket *socket : inputs_) {
if (socket->origin() == nullptr) {
- return false;
+ return true;
}
}
- return true;
+ return false;
}
/* --------------------------------------------------------------------
@@ -359,12 +364,12 @@ inline const MultiFunction &MFFunctionNode::function() const
return *function_;
}
-inline const MFInputSocket &MFFunctionNode::input_for_param(uint param_index) const
+inline const MFInputSocket &MFFunctionNode::input_for_param(int param_index) const
{
return this->input(input_param_indices_.first_index(param_index));
}
-inline const MFOutputSocket &MFFunctionNode::output_for_param(uint param_index) const
+inline const MFOutputSocket &MFFunctionNode::output_for_param(int param_index) const
{
return this->output(output_param_indices_.first_index(param_index));
}
@@ -397,11 +402,16 @@ inline StringRefNull MFSocket::name() const
return name_;
}
-inline uint MFSocket::id() const
+inline int MFSocket::id() const
{
return id_;
}
+inline int MFSocket::index() const
+{
+ return index_;
+}
+
inline const MFDataType &MFSocket::data_type() const
{
return data_type_;
@@ -476,18 +486,51 @@ inline Span<MFInputSocket *> MFOutputSocket::targets()
inline Span<const MFInputSocket *> MFOutputSocket::targets() const
{
- return targets_.as_span();
+ return targets_;
}
/* --------------------------------------------------------------------
* MFNetwork inline methods.
*/
-inline uint MFNetwork::max_socket_id() const
+inline Span<MFDummyNode *> MFNetwork::dummy_nodes()
{
- return socket_or_null_by_id_.size() - 1;
+ return dummy_nodes_;
}
-} // namespace blender::fn
+inline Span<MFFunctionNode *> MFNetwork::function_nodes()
+{
+ return function_nodes_;
+}
-#endif /* __FN_MULTI_FUNCTION_NETWORK_HH__ */
+inline MFNode *MFNetwork::node_or_null_by_id(int id)
+{
+ return node_or_null_by_id_[id];
+}
+
+inline const MFNode *MFNetwork::node_or_null_by_id(int id) const
+{
+ return node_or_null_by_id_[id];
+}
+
+inline MFSocket *MFNetwork::socket_or_null_by_id(int id)
+{
+ return socket_or_null_by_id_[id];
+}
+
+inline const MFSocket *MFNetwork::socket_or_null_by_id(int id) const
+{
+ return socket_or_null_by_id_[id];
+}
+
+inline int MFNetwork::socket_id_amount() const
+{
+ return socket_or_null_by_id_.size();
+}
+
+inline int MFNetwork::node_id_amount() const
+{
+ return node_or_null_by_id_.size();
+}
+
+} // namespace blender::fn
diff --git a/source/blender/functions/FN_multi_function_network_evaluation.hh b/source/blender/functions/FN_multi_function_network_evaluation.hh
index 11606869ca2..2c0d94615b0 100644
--- a/source/blender/functions/FN_multi_function_network_evaluation.hh
+++ b/source/blender/functions/FN_multi_function_network_evaluation.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_MULTI_FUNCTION_NETWORK_EVALUATION_HH__
-#define __FN_MULTI_FUNCTION_NETWORK_EVALUATION_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -60,5 +59,3 @@ class MFNetworkEvaluator : public MultiFunction {
};
} // namespace blender::fn
-
-#endif /* __FN_MULTI_FUNCTION_NETWORK_EVALUATION_HH__ */
diff --git a/source/blender/functions/FN_multi_function_network_optimization.hh b/source/blender/functions/FN_multi_function_network_optimization.hh
new file mode 100644
index 00000000000..6d0165643ce
--- /dev/null
+++ b/source/blender/functions/FN_multi_function_network_optimization.hh
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "FN_multi_function_network.hh"
+
+#include "BLI_resource_collector.hh"
+
+namespace blender::fn::mf_network_optimization {
+
+void dead_node_removal(MFNetwork &network);
+void constant_folding(MFNetwork &network, ResourceCollector &resources);
+void common_subnetwork_elimination(MFNetwork &network);
+
+} // namespace blender::fn::mf_network_optimization
diff --git a/source/blender/functions/FN_multi_function_param_type.hh b/source/blender/functions/FN_multi_function_param_type.hh
index 0e43e355b53..5b35cbe365b 100644
--- a/source/blender/functions/FN_multi_function_param_type.hh
+++ b/source/blender/functions/FN_multi_function_param_type.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_MULTI_FUNCTION_PARAM_TYPE_HH__
-#define __FN_MULTI_FUNCTION_PARAM_TYPE_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -144,6 +143,11 @@ class MFParamType {
return ELEM(interface_type_, Output, Mutable);
}
+ bool is_output() const
+ {
+ return interface_type_ == Output;
+ }
+
friend bool operator==(const MFParamType &a, const MFParamType &b);
friend bool operator!=(const MFParamType &a, const MFParamType &b);
};
@@ -159,5 +163,3 @@ inline bool operator!=(const MFParamType &a, const MFParamType &b)
}
} // namespace blender::fn
-
-#endif /* __FN_MULTI_FUNCTION_PARAM_TYPE_HH__ */
diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh
index e6683693a0a..ba2d1d0edd3 100644
--- a/source/blender/functions/FN_multi_function_params.hh
+++ b/source/blender/functions/FN_multi_function_params.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_MULTI_FUNCTION_PARAMS_HH__
-#define __FN_MULTI_FUNCTION_PARAMS_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -34,7 +33,7 @@ namespace blender::fn {
class MFParamsBuilder {
private:
const MFSignature *signature_;
- uint min_array_size_;
+ int64_t min_array_size_;
Vector<GVSpan> virtual_spans_;
Vector<GMutableSpan> mutable_spans_;
Vector<GVArraySpan> virtual_array_spans_;
@@ -43,89 +42,103 @@ class MFParamsBuilder {
friend class MFParams;
public:
- MFParamsBuilder(const MFSignature &signature, uint min_array_size)
+ MFParamsBuilder(const MFSignature &signature, int64_t min_array_size)
: signature_(&signature), min_array_size_(min_array_size)
{
}
- MFParamsBuilder(const class MultiFunction &fn, uint min_array_size);
+ MFParamsBuilder(const class MultiFunction &fn, int64_t min_array_size);
- template<typename T> void add_readonly_single_input(const T *value)
+ template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "")
{
- this->add_readonly_single_input(GVSpan::FromSingle(CPPType::get<T>(), value, min_array_size_));
+ this->add_readonly_single_input(GVSpan::FromSingle(CPPType::get<T>(), value, min_array_size_),
+ expected_name);
}
- void add_readonly_single_input(GVSpan ref)
+ void add_readonly_single_input(GVSpan ref, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForSingleInput(ref.type()));
+ this->assert_current_param_type(MFParamType::ForSingleInput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
virtual_spans_.append(ref);
}
- void add_readonly_vector_input(GVArraySpan ref)
+ void add_readonly_vector_input(GVArraySpan ref, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()));
+ this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
virtual_array_spans_.append(ref);
}
- void add_uninitialized_single_output(GMutableSpan ref)
+ template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()));
+ this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1),
+ expected_name);
+ }
+ void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name = "")
+ {
+ this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
mutable_spans_.append(ref);
}
- void add_vector_output(GVectorArray &vector_array)
+ void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()));
+ this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()),
+ expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
vector_arrays_.append(&vector_array);
}
- void add_single_mutable(GMutableSpan ref)
+ void add_single_mutable(GMutableSpan ref, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()));
+ this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
mutable_spans_.append(ref);
}
- void add_vector_mutable(GVectorArray &vector_array)
+ void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()));
+ this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()),
+ expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
vector_arrays_.append(&vector_array);
}
- GMutableSpan computed_array(uint param_index)
+ GMutableSpan computed_array(int param_index)
{
BLI_assert(ELEM(signature_->param_types[param_index].category(),
MFParamType::SingleOutput,
MFParamType::SingleMutable));
- uint data_index = signature_->data_index(param_index);
+ int data_index = signature_->data_index(param_index);
return mutable_spans_[data_index];
}
- GVectorArray &computed_vector_array(uint param_index)
+ GVectorArray &computed_vector_array(int param_index)
{
BLI_assert(ELEM(signature_->param_types[param_index].category(),
MFParamType::VectorOutput,
MFParamType::VectorMutable));
- uint data_index = signature_->data_index(param_index);
+ int data_index = signature_->data_index(param_index);
return *vector_arrays_[data_index];
}
private:
- void assert_current_param_type(MFParamType param_type)
+ void assert_current_param_type(MFParamType param_type, StringRef expected_name = "")
{
- UNUSED_VARS_NDEBUG(param_type);
+ UNUSED_VARS_NDEBUG(param_type, expected_name);
#ifdef DEBUG
- uint param_index = this->current_param_index();
+ int param_index = this->current_param_index();
+
+ if (expected_name != "") {
+ StringRef actual_name = signature_->param_names[param_index];
+ BLI_assert(actual_name == expected_name);
+ }
+
MFParamType expected_type = signature_->param_types[param_index];
BLI_assert(expected_type == param_type);
#endif
}
- uint current_param_index() const
+ int current_param_index() const
{
return virtual_spans_.size() + mutable_spans_.size() + virtual_array_spans_.size() +
vector_arrays_.size();
@@ -141,75 +154,75 @@ class MFParams {
{
}
- template<typename T> VSpan<T> readonly_single_input(uint param_index, StringRef name = "")
+ template<typename T> VSpan<T> readonly_single_input(int param_index, StringRef name = "")
{
return this->readonly_single_input(param_index, name).typed<T>();
}
- GVSpan readonly_single_input(uint param_index, StringRef name = "")
+ GVSpan readonly_single_input(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::SingleInput);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return builder_->virtual_spans_[data_index];
}
template<typename T>
- MutableSpan<T> uninitialized_single_output(uint param_index, StringRef name = "")
+ MutableSpan<T> uninitialized_single_output(int param_index, StringRef name = "")
{
return this->uninitialized_single_output(param_index, name).typed<T>();
}
- GMutableSpan uninitialized_single_output(uint param_index, StringRef name = "")
+ GMutableSpan uninitialized_single_output(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::SingleOutput);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return builder_->mutable_spans_[data_index];
}
- template<typename T> VArraySpan<T> readonly_vector_input(uint param_index, StringRef name = "")
+ template<typename T> VArraySpan<T> readonly_vector_input(int param_index, StringRef name = "")
{
return this->readonly_vector_input(param_index, name).typed<T>();
}
- GVArraySpan readonly_vector_input(uint param_index, StringRef name = "")
+ GVArraySpan readonly_vector_input(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::VectorInput);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return builder_->virtual_array_spans_[data_index];
}
- template<typename T> GVectorArrayRef<T> vector_output(uint param_index, StringRef name = "")
+ template<typename T> GVectorArrayRef<T> vector_output(int param_index, StringRef name = "")
{
return this->vector_output(param_index, name).typed<T>();
}
- GVectorArray &vector_output(uint param_index, StringRef name = "")
+ GVectorArray &vector_output(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::VectorOutput);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return *builder_->vector_arrays_[data_index];
}
- template<typename T> MutableSpan<T> single_mutable(uint param_index, StringRef name = "")
+ template<typename T> MutableSpan<T> single_mutable(int param_index, StringRef name = "")
{
return this->single_mutable(param_index, name).typed<T>();
}
- GMutableSpan single_mutable(uint param_index, StringRef name = "")
+ GMutableSpan single_mutable(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::SingleMutable);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return builder_->mutable_spans_[data_index];
}
- template<typename T> GVectorArrayRef<T> vector_mutable(uint param_index, StringRef name = "")
+ template<typename T> GVectorArrayRef<T> vector_mutable(int param_index, StringRef name = "")
{
return this->vector_mutable(param_index, name).typed<T>();
}
- GVectorArray &vector_mutable(uint param_index, StringRef name = "")
+ GVectorArray &vector_mutable(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::VectorMutable);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return *builder_->vector_arrays_[data_index];
}
private:
- void assert_correct_param(uint param_index, StringRef name, MFParamType param_type)
+ void assert_correct_param(int param_index, StringRef name, MFParamType param_type)
{
UNUSED_VARS_NDEBUG(param_index, name, param_type);
#ifdef DEBUG
@@ -220,7 +233,7 @@ class MFParams {
#endif
}
- void assert_correct_param(uint param_index, StringRef name, MFParamType::Category category)
+ void assert_correct_param(int param_index, StringRef name, MFParamType::Category category)
{
UNUSED_VARS_NDEBUG(param_index, name, category);
#ifdef DEBUG
@@ -233,5 +246,3 @@ class MFParams {
};
} // namespace blender::fn
-
-#endif /* __FN_MULTI_FUNCTION_PARAMS_HH__ */
diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh
index e2cf783753e..ef51ddbaf24 100644
--- a/source/blender/functions/FN_multi_function_signature.hh
+++ b/source/blender/functions/FN_multi_function_signature.hh
@@ -14,14 +14,13 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_MULTI_FUNCTION_SIGNATURE_HH__
-#define __FN_MULTI_FUNCTION_SIGNATURE_HH__
+#pragma once
/** \file
* \ingroup fn
*
* The signature of a multi-function contains the functions name and expected parameters. New
- * signatures should be build using the MFSignatureBuilder class.
+ * signatures should be build using the #MFSignatureBuilder class.
*/
#include "FN_multi_function_param_type.hh"
@@ -32,12 +31,12 @@ namespace blender::fn {
struct MFSignature {
std::string function_name;
- /* Use RawAllocator so that a MultiFunction can have static storage duration. */
- Vector<std::string, 4, RawAllocator> param_names;
- Vector<MFParamType, 4, RawAllocator> param_types;
- Vector<uint, 4, RawAllocator> param_data_indices;
+ Vector<std::string> param_names;
+ Vector<MFParamType> param_types;
+ Vector<int> param_data_indices;
+ bool depends_on_context = false;
- uint data_index(uint param_index) const
+ int data_index(int param_index) const
{
return param_data_indices[param_index];
}
@@ -46,10 +45,10 @@ struct MFSignature {
class MFSignatureBuilder {
private:
MFSignature &data_;
- uint span_count_ = 0;
- uint virtual_span_count_ = 0;
- uint virtual_array_span_count_ = 0;
- uint vector_array_count_ = 0;
+ int span_count_ = 0;
+ int virtual_span_count_ = 0;
+ int virtual_array_span_count_ = 0;
+ int vector_array_count_ = 0;
public:
MFSignatureBuilder(MFSignature &data) : data_(data)
@@ -59,7 +58,7 @@ class MFSignatureBuilder {
BLI_assert(data.param_data_indices.is_empty());
}
- /* Input Param Types */
+ /* Input Parameter Types */
template<typename T> void single_input(StringRef name)
{
@@ -92,7 +91,7 @@ class MFSignatureBuilder {
}
}
- /* Output Param Types */
+ /* Output Parameter Types */
template<typename T> void single_output(StringRef name)
{
@@ -125,7 +124,7 @@ class MFSignatureBuilder {
}
}
- /* Mutable Param Types */
+ /* Mutable Parameter Types */
template<typename T> void single_mutable(StringRef name)
{
@@ -157,8 +156,15 @@ class MFSignatureBuilder {
break;
}
}
+
+ /* Context */
+
+ /** This indicates that the function accesses the context. This disables optimizations that
+ * depend on the fact that the function always performers the same operation. */
+ void depends_on_context()
+ {
+ data_.depends_on_context = true;
+ }
};
} // namespace blender::fn
-
-#endif /* __FN_MULTI_FUNCTION_SIGNATURE_HH__ */
diff --git a/source/blender/functions/FN_spans.hh b/source/blender/functions/FN_spans.hh
index b2622eab95f..76380f46e91 100644
--- a/source/blender/functions/FN_spans.hh
+++ b/source/blender/functions/FN_spans.hh
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FN_SPANS_HH__
-#define __FN_SPANS_HH__
+#pragma once
/** \file
* \ingroup fn
@@ -51,13 +50,14 @@ namespace blender::fn {
class GSpan {
private:
const CPPType *type_;
- const void *buffer_;
- uint size_;
+ const void *data_;
+ int64_t size_;
public:
- GSpan(const CPPType &type, const void *buffer, uint size)
- : type_(&type), buffer_(buffer), size_(size)
+ GSpan(const CPPType &type, const void *buffer, int64_t size)
+ : type_(&type), data_(buffer), size_(size)
{
+ BLI_assert(size >= 0);
BLI_assert(buffer != nullptr || size == 0);
BLI_assert(type.pointer_has_valid_alignment(buffer));
}
@@ -81,26 +81,26 @@ class GSpan {
return size_ == 0;
}
- uint size() const
+ int64_t size() const
{
return size_;
}
- const void *buffer() const
+ const void *data() const
{
- return buffer_;
+ return data_;
}
- const void *operator[](uint index) const
+ const void *operator[](int64_t index) const
{
BLI_assert(index < size_);
- return POINTER_OFFSET(buffer_, type_->size() * index);
+ return POINTER_OFFSET(data_, type_->size() * index);
}
template<typename T> Span<T> typed() const
{
BLI_assert(type_->is<T>());
- return Span<T>((const T *)buffer_, size_);
+ return Span<T>((const T *)data_, size_);
}
};
@@ -111,13 +111,14 @@ class GSpan {
class GMutableSpan {
private:
const CPPType *type_;
- void *buffer_;
- uint size_;
+ void *data_;
+ int64_t size_;
public:
- GMutableSpan(const CPPType &type, void *buffer, uint size)
- : type_(&type), buffer_(buffer), size_(size)
+ GMutableSpan(const CPPType &type, void *buffer, int64_t size)
+ : type_(&type), data_(buffer), size_(size)
{
+ BLI_assert(size >= 0);
BLI_assert(buffer != nullptr || size == 0);
BLI_assert(type.pointer_has_valid_alignment(buffer));
}
@@ -134,7 +135,7 @@ class GMutableSpan {
operator GSpan() const
{
- return GSpan(*type_, buffer_, size_);
+ return GSpan(*type_, data_, size_);
}
const CPPType &type() const
@@ -147,26 +148,26 @@ class GMutableSpan {
return size_ == 0;
}
- uint size() const
+ int64_t size() const
{
return size_;
}
- void *buffer()
+ void *data()
{
- return buffer_;
+ return data_;
}
- void *operator[](uint index)
+ void *operator[](int64_t index)
{
BLI_assert(index < size_);
- return POINTER_OFFSET(buffer_, type_->size() * index);
+ return POINTER_OFFSET(data_, type_->size() * index);
}
template<typename T> MutableSpan<T> typed()
{
BLI_assert(type_->is<T>());
- return MutableSpan<T>((T *)buffer_, size_);
+ return MutableSpan<T>((T *)data_, size_);
}
};
@@ -178,7 +179,7 @@ enum class VSpanCategory {
template<typename T> struct VSpanBase {
protected:
- uint virtual_size_;
+ int64_t virtual_size_;
VSpanCategory category_;
union {
struct {
@@ -207,12 +208,26 @@ template<typename T> struct VSpanBase {
return false;
}
+ bool is_full_array() const
+ {
+ switch (category_) {
+ case VSpanCategory::Single:
+ return virtual_size_ == 1;
+ case VSpanCategory::FullArray:
+ return true;
+ case VSpanCategory::FullPointerArray:
+ return virtual_size_ <= 1;
+ }
+ BLI_assert(false);
+ return false;
+ }
+
bool is_empty() const
{
return this->virtual_size_ == 0;
}
- uint size() const
+ int64_t size() const
{
return this->virtual_size_;
}
@@ -259,7 +274,7 @@ template<typename T> class VSpan : public VSpanBase<T> {
this->data_.full_pointer_array.data = values.begin();
}
- static VSpan FromSingle(const T *value, uint virtual_size)
+ static VSpan FromSingle(const T *value, int64_t virtual_size)
{
VSpan ref;
ref.virtual_size_ = virtual_size;
@@ -268,8 +283,9 @@ template<typename T> class VSpan : public VSpanBase<T> {
return ref;
}
- const T &operator[](uint index) const
+ const T &operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->virtual_size_);
switch (this->category_) {
case VSpanCategory::Single:
@@ -282,6 +298,22 @@ template<typename T> class VSpan : public VSpanBase<T> {
BLI_assert(false);
return *this->data_.single.data;
}
+
+ const T &as_single_element() const
+ {
+ BLI_assert(this->is_single_element());
+ return (*this)[0];
+ }
+
+ Span<T> as_full_array() const
+ {
+ BLI_assert(this->is_full_array());
+ if (this->virtual_size_ == 0) {
+ return Span<T>();
+ }
+ const T *data = &(*this)[0];
+ return Span<T>(data, this->virtual_size_);
+ }
};
/**
@@ -308,7 +340,7 @@ class GVSpan : public VSpanBase<void> {
this->type_ = &values.type();
this->virtual_size_ = values.size();
this->category_ = VSpanCategory::FullArray;
- this->data_.full_array.data = values.buffer();
+ this->data_.full_array.data = values.data();
}
GVSpan(GMutableSpan values) : GVSpan(GSpan(values))
@@ -329,7 +361,7 @@ class GVSpan : public VSpanBase<void> {
{
}
- static GVSpan FromSingle(const CPPType &type, const void *value, uint virtual_size)
+ static GVSpan FromSingle(const CPPType &type, const void *value, int64_t virtual_size)
{
GVSpan ref;
ref.type_ = &type;
@@ -339,7 +371,17 @@ class GVSpan : public VSpanBase<void> {
return ref;
}
- static GVSpan FromFullPointerArray(const CPPType &type, const void *const *values, uint size)
+ static GVSpan FromSingleWithMaxSize(const CPPType &type, const void *value)
+ {
+ return GVSpan::FromSingle(type, value, INT64_MAX);
+ }
+
+ static GVSpan FromDefault(const CPPType &type)
+ {
+ return GVSpan::FromSingleWithMaxSize(type, type.default_value());
+ }
+
+ static GVSpan FromFullPointerArray(const CPPType &type, const void *const *values, int64_t size)
{
GVSpan ref;
ref.type_ = &type;
@@ -354,8 +396,9 @@ class GVSpan : public VSpanBase<void> {
return *this->type_;
}
- const void *operator[](uint index) const
+ const void *operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->virtual_size_);
switch (this->category_) {
case VSpanCategory::Single:
@@ -381,6 +424,16 @@ class GVSpan : public VSpanBase<void> {
return (*this)[0];
}
+ GSpan as_full_array() const
+ {
+ BLI_assert(this->is_full_array());
+ if (this->virtual_size_ == 0) {
+ return GSpan(*this->type_);
+ }
+ const void *data = (*this)[0];
+ return GSpan(*this->type_, data, this->virtual_size_);
+ }
+
void materialize_to_uninitialized(void *dst) const
{
this->materialize_to_uninitialized(IndexRange(virtual_size_), dst);
@@ -390,13 +443,11 @@ class GVSpan : public VSpanBase<void> {
{
BLI_assert(this->size() >= mask.min_array_size());
- uint element_size = type_->size();
- for (uint i : mask) {
+ int64_t element_size = type_->size();
+ for (int64_t i : mask) {
type_->copy_to_uninitialized((*this)[i], POINTER_OFFSET(dst, element_size * i));
}
}
};
} // namespace blender::fn
-
-#endif /* __FN_SPANS_HH__ */
diff --git a/source/blender/functions/intern/attributes_ref.cc b/source/blender/functions/intern/attributes_ref.cc
index f61a9165c47..8f7f41be079 100644
--- a/source/blender/functions/intern/attributes_ref.cc
+++ b/source/blender/functions/intern/attributes_ref.cc
@@ -20,13 +20,17 @@ namespace blender::fn {
AttributesInfoBuilder::~AttributesInfoBuilder()
{
- for (uint i : defaults_.index_range()) {
+ for (int i : defaults_.index_range()) {
types_[i]->destruct(defaults_[i]);
}
}
-void AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void *default_value)
+bool AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void *default_value)
{
+ if (name.size() == 0) {
+ std::cout << "Warning: Tried to add an attribute with empty name.\n";
+ return false;
+ }
if (names_.add_as(name)) {
types_.append(&type);
@@ -36,16 +40,21 @@ void AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void
void *dst = allocator_.allocate(type.size(), type.alignment());
type.copy_to_uninitialized(default_value, dst);
defaults_.append(dst);
+ return true;
}
else {
- /* The same name can be added more than once as long as the type is always the same. */
- BLI_assert(types_[names_.index_of_as(name)] == &type);
+ const CPPType &stored_type = *types_[names_.index_of_as(name)];
+ if (stored_type != type) {
+ std::cout << "Warning: Tried to add an attribute twice with different types (" << name
+ << ": " << stored_type.name() << ", " << type.name() << ").\n";
+ }
+ return false;
}
}
AttributesInfo::AttributesInfo(const AttributesInfoBuilder &builder)
{
- for (uint i : builder.types_.index_range()) {
+ for (int i : builder.types_.index_range()) {
StringRefNull name = allocator_.copy_string(builder.names_[i]);
const CPPType &type = *builder.types_[i];
const void *default_value = builder.defaults_[i];
@@ -62,7 +71,7 @@ AttributesInfo::AttributesInfo(const AttributesInfoBuilder &builder)
AttributesInfo::~AttributesInfo()
{
- for (uint i : defaults_.index_range()) {
+ for (int i : defaults_.index_range()) {
type_by_index_[i]->destruct(defaults_[i]);
}
}
diff --git a/source/blender/functions/intern/cpp_types.cc b/source/blender/functions/intern/cpp_types.cc
index 052278afd65..3bf4683d815 100644
--- a/source/blender/functions/intern/cpp_types.cc
+++ b/source/blender/functions/intern/cpp_types.cc
@@ -14,7 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "FN_cpp_types.hh"
+#include "FN_cpp_type.hh"
#include "BLI_color.hh"
#include "BLI_float2.hh"
diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc
new file mode 100644
index 00000000000..c9e8b88ba03
--- /dev/null
+++ b/source/blender/functions/intern/multi_function_builder.cc
@@ -0,0 +1,119 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "FN_multi_function_builder.hh"
+
+#include "BLI_hash.hh"
+
+namespace blender::fn {
+
+CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, const void *value)
+ : type_(type), value_(value)
+{
+ MFSignatureBuilder signature = this->get_builder("Constant " + type.name());
+ std::stringstream ss;
+ type.debug_print(value, ss);
+ signature.single_output(ss.str(), type);
+}
+
+void CustomMF_GenericConstant::call(IndexMask mask,
+ MFParams params,
+ MFContext UNUSED(context)) const
+{
+ GMutableSpan output = params.uninitialized_single_output(0);
+ type_.fill_uninitialized_indices(value_, output.data(), mask);
+}
+
+uint64_t CustomMF_GenericConstant::hash() const
+{
+ return type_.hash(value_);
+}
+
+bool CustomMF_GenericConstant::equals(const MultiFunction &other) const
+{
+ const CustomMF_GenericConstant *_other = dynamic_cast<const CustomMF_GenericConstant *>(&other);
+ if (_other == nullptr) {
+ return false;
+ }
+ if (type_ != _other->type_) {
+ return false;
+ }
+ return type_.is_equal(value_, _other->value_);
+}
+
+static std::string gspan_to_string(GSpan array)
+{
+ std::stringstream ss;
+ ss << "[";
+ const int64_t max_amount = 5;
+ for (int64_t i : IndexRange(std::min(max_amount, array.size()))) {
+ array.type().debug_print(array[i], ss);
+ ss << ", ";
+ }
+ if (max_amount < array.size()) {
+ ss << "...";
+ }
+ ss << "]";
+ return ss.str();
+}
+
+CustomMF_GenericConstantArray::CustomMF_GenericConstantArray(GSpan array) : array_(array)
+{
+ const CPPType &type = array.type();
+ MFSignatureBuilder signature = this->get_builder("Constant " + type.name() + " Vector");
+ signature.vector_output(gspan_to_string(array), type);
+}
+
+void CustomMF_GenericConstantArray::call(IndexMask mask,
+ MFParams params,
+ MFContext UNUSED(context)) const
+{
+ GVectorArray &vectors = params.vector_output(0);
+ for (int64_t i : mask) {
+ vectors.extend(i, array_);
+ }
+}
+
+CustomMF_DefaultOutput::CustomMF_DefaultOutput(StringRef name,
+ Span<MFDataType> input_types,
+ Span<MFDataType> output_types)
+ : output_amount_(output_types.size())
+{
+ MFSignatureBuilder signature = this->get_builder(name);
+ for (MFDataType data_type : input_types) {
+ signature.input("Input", data_type);
+ }
+ for (MFDataType data_type : output_types) {
+ signature.output("Output", data_type);
+ }
+}
+void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const
+{
+ for (int param_index : this->param_indices()) {
+ MFParamType param_type = this->param_type(param_index);
+ if (!param_type.is_output()) {
+ continue;
+ }
+
+ if (param_type.data_type().is_single()) {
+ GMutableSpan span = params.uninitialized_single_output(param_index);
+ const CPPType &type = span.type();
+ type.fill_uninitialized_indices(type.default_value(), span.data(), mask);
+ }
+ }
+}
+
+} // namespace blender::fn
diff --git a/source/blender/functions/intern/multi_function_network.cc b/source/blender/functions/intern/multi_function_network.cc
index 5df70d92a4e..cd3c38dd09f 100644
--- a/source/blender/functions/intern/multi_function_network.cc
+++ b/source/blender/functions/intern/multi_function_network.cc
@@ -15,6 +15,8 @@
*/
#include "BLI_dot_export.hh"
+#include "BLI_stack.hh"
+
#include "FN_multi_function_network.hh"
namespace blender::fn {
@@ -48,9 +50,9 @@ void MFNode::destruct_sockets()
*/
MFFunctionNode &MFNetwork::add_function(const MultiFunction &function)
{
- Vector<uint, 16> input_param_indices, output_param_indices;
+ Vector<int, 16> input_param_indices, output_param_indices;
- for (uint param_index : function.param_indices()) {
+ for (int param_index : function.param_indices()) {
switch (function.param_type(param_index).interface_type()) {
case MFParamType::Input: {
input_param_indices.append(param_index);
@@ -75,16 +77,16 @@ MFFunctionNode &MFNetwork::add_function(const MultiFunction &function)
node.is_dummy_ = false;
node.id_ = node_or_null_by_id_.append_and_get_index(&node);
node.function_ = &function;
- node.input_param_indices_ = allocator_.construct_array_copy<uint>(input_param_indices);
- node.output_param_indices_ = allocator_.construct_array_copy<uint>(output_param_indices);
+ node.input_param_indices_ = allocator_.construct_array_copy<int>(input_param_indices);
+ node.output_param_indices_ = allocator_.construct_array_copy<int>(output_param_indices);
node.inputs_ = allocator_.construct_elements_and_pointer_array<MFInputSocket>(
input_param_indices.size());
node.outputs_ = allocator_.construct_elements_and_pointer_array<MFOutputSocket>(
output_param_indices.size());
- for (uint i : input_param_indices.index_range()) {
- uint param_index = input_param_indices[i];
+ for (int i : input_param_indices.index_range()) {
+ int param_index = input_param_indices[i];
MFParamType param = function.param_type(param_index);
BLI_assert(param.is_input_or_mutable());
@@ -98,8 +100,8 @@ MFFunctionNode &MFNetwork::add_function(const MultiFunction &function)
socket.id_ = socket_or_null_by_id_.append_and_get_index(&socket);
}
- for (uint i : output_param_indices.index_range()) {
- uint param_index = output_param_indices[i];
+ for (int i : output_param_indices.index_range()) {
+ int param_index = output_param_indices[i];
MFParamType param = function.param_type(param_index);
BLI_assert(param.is_output_or_mutable());
@@ -143,7 +145,7 @@ MFDummyNode &MFNetwork::add_dummy(StringRef name,
node.input_names_ = allocator_.allocate_array<StringRefNull>(input_types.size());
node.output_names_ = allocator_.allocate_array<StringRefNull>(output_types.size());
- for (uint i : input_types.index_range()) {
+ for (int i : input_types.index_range()) {
MFInputSocket &socket = *node.inputs_[i];
socket.data_type_ = input_types[i];
socket.node_ = &node;
@@ -154,7 +156,7 @@ MFDummyNode &MFNetwork::add_dummy(StringRef name,
node.input_names_[i] = socket.name_;
}
- for (uint i : output_types.index_range()) {
+ for (int i : output_types.index_range()) {
MFOutputSocket &socket = *node.outputs_[i];
socket.data_type_ = output_types[i];
socket.node_ = &node;
@@ -184,17 +186,18 @@ void MFNetwork::add_link(MFOutputSocket &from, MFInputSocket &to)
MFOutputSocket &MFNetwork::add_input(StringRef name, MFDataType data_type)
{
- return this->add_dummy(name, {}, {data_type}, {}, {name}).output(0);
+ return this->add_dummy(name, {}, {data_type}, {}, {"Value"}).output(0);
}
MFInputSocket &MFNetwork::add_output(StringRef name, MFDataType data_type)
{
- return this->add_dummy(name, {data_type}, {}, {name}, {}).input(0);
+ return this->add_dummy(name, {data_type}, {}, {"Value"}, {}).input(0);
}
void MFNetwork::relink(MFOutputSocket &old_output, MFOutputSocket &new_output)
{
BLI_assert(&old_output != &new_output);
+ BLI_assert(old_output.data_type_ == new_output.data_type_);
for (MFInputSocket *input : old_output.targets()) {
input->origin_ = &new_output;
}
@@ -230,7 +233,51 @@ void MFNetwork::remove(MFNode &node)
node_or_null_by_id_[node.id_] = nullptr;
}
-std::string MFNetwork::to_dot() const
+void MFNetwork::remove(Span<MFNode *> nodes)
+{
+ for (MFNode *node : nodes) {
+ this->remove(*node);
+ }
+}
+
+void MFNetwork::find_dependencies(Span<const MFInputSocket *> sockets,
+ VectorSet<const MFOutputSocket *> &r_dummy_sockets,
+ VectorSet<const MFInputSocket *> &r_unlinked_inputs) const
+{
+ Set<const MFNode *> visited_nodes;
+ Stack<const MFInputSocket *> sockets_to_check;
+ sockets_to_check.push_multiple(sockets);
+
+ while (!sockets_to_check.is_empty()) {
+ const MFInputSocket &socket = *sockets_to_check.pop();
+ const MFOutputSocket *origin_socket = socket.origin();
+ if (origin_socket == nullptr) {
+ r_unlinked_inputs.add(&socket);
+ continue;
+ }
+
+ const MFNode &origin_node = origin_socket->node();
+
+ if (origin_node.is_dummy()) {
+ r_dummy_sockets.add(origin_socket);
+ continue;
+ }
+
+ if (visited_nodes.add(&origin_node)) {
+ sockets_to_check.push_multiple(origin_node.inputs());
+ }
+ }
+}
+
+bool MFNetwork::have_dummy_or_unlinked_dependencies(Span<const MFInputSocket *> sockets) const
+{
+ VectorSet<const MFOutputSocket *> dummy_sockets;
+ VectorSet<const MFInputSocket *> unlinked_inputs;
+ this->find_dependencies(sockets, dummy_sockets, unlinked_inputs);
+ return dummy_sockets.size() + unlinked_inputs.size() > 0;
+}
+
+std::string MFNetwork::to_dot(Span<const MFNode *> marked_nodes) const
{
dot::DirectedGraph digraph;
digraph.set_rankdir(dot::Attr_rankdir::LeftToRight);
@@ -256,6 +303,13 @@ std::string MFNetwork::to_dot() const
dot_nodes.add_new(node, dot_node_ref);
}
+ for (const MFDummyNode *node : dummy_nodes_) {
+ dot_nodes.lookup(node).node().set_background_color("#77EE77");
+ }
+ for (const MFNode *node : marked_nodes) {
+ dot_nodes.lookup(node).node().set_background_color("#7777EE");
+ }
+
for (const MFNode *to_node : all_nodes) {
dot::NodeWithSocketsRef to_dot_node = dot_nodes.lookup(to_node);
diff --git a/source/blender/functions/intern/multi_function_network_evaluation.cc b/source/blender/functions/intern/multi_function_network_evaluation.cc
index 08a254dc300..25e983d2eeb 100644
--- a/source/blender/functions/intern/multi_function_network_evaluation.cc
+++ b/source/blender/functions/intern/multi_function_network_evaluation.cc
@@ -55,10 +55,10 @@ class MFNetworkEvaluationStorage {
LinearAllocator<> allocator_;
IndexMask mask_;
Array<Value *> value_per_output_id_;
- uint min_array_size_;
+ int64_t min_array_size_;
public:
- MFNetworkEvaluationStorage(IndexMask mask, uint max_socket_id);
+ MFNetworkEvaluationStorage(IndexMask mask, int socket_id_amount);
~MFNetworkEvaluationStorage();
/* Add the values that have been provided by the caller of the multi-function network. */
@@ -106,30 +106,30 @@ MFNetworkEvaluator::MFNetworkEvaluator(Vector<const MFOutputSocket *> inputs,
BLI_assert(outputs_.size() > 0);
MFSignatureBuilder signature = this->get_builder("Function Tree");
- for (auto socket : inputs_) {
+ for (const MFOutputSocket *socket : inputs_) {
BLI_assert(socket->node().is_dummy());
MFDataType type = socket->data_type();
switch (type.category()) {
case MFDataType::Single:
- signature.single_input("Input", type.single_type());
+ signature.single_input(socket->name(), type.single_type());
break;
case MFDataType::Vector:
- signature.vector_input("Input", type.vector_base_type());
+ signature.vector_input(socket->name(), type.vector_base_type());
break;
}
}
- for (auto socket : outputs_) {
+ for (const MFInputSocket *socket : outputs_) {
BLI_assert(socket->node().is_dummy());
MFDataType type = socket->data_type();
switch (type.category()) {
case MFDataType::Single:
- signature.single_output("Output", type.single_type());
+ signature.single_output(socket->name(), type.single_type());
break;
case MFDataType::Vector:
- signature.vector_output("Output", type.vector_base_type());
+ signature.vector_output(socket->name(), type.vector_base_type());
break;
}
}
@@ -142,7 +142,7 @@ void MFNetworkEvaluator::call(IndexMask mask, MFParams params, MFContext context
}
const MFNetwork &network = outputs_[0]->node().network();
- Storage storage(mask, network.max_socket_id());
+ Storage storage(mask, network.socket_id_amount());
Vector<const MFInputSocket *> outputs_to_initialize_in_the_end;
@@ -155,8 +155,8 @@ void MFNetworkEvaluator::call(IndexMask mask, MFParams params, MFContext context
BLI_NOINLINE void MFNetworkEvaluator::copy_inputs_to_storage(MFParams params,
Storage &storage) const
{
- for (uint input_index : inputs_.index_range()) {
- uint param_index = input_index + 0;
+ for (int input_index : inputs_.index_range()) {
+ int param_index = input_index + 0;
const MFOutputSocket &socket = *inputs_[input_index];
switch (socket.data_type().category()) {
case MFDataType::Single: {
@@ -178,8 +178,8 @@ BLI_NOINLINE void MFNetworkEvaluator::copy_outputs_to_storage(
Storage &storage,
Vector<const MFInputSocket *> &outputs_to_initialize_in_the_end) const
{
- for (uint output_index : outputs_.index_range()) {
- uint param_index = output_index + inputs_.size();
+ for (int output_index : outputs_.index_range()) {
+ int param_index = output_index + inputs_.size();
const MFInputSocket &socket = *outputs_[output_index];
const MFOutputSocket &origin = *socket.origin();
@@ -219,8 +219,6 @@ BLI_NOINLINE void MFNetworkEvaluator::evaluate_network_to_compute_outputs(
sockets_to_compute.push(socket->origin());
}
- Vector<const MFOutputSocket *, 32> missing_sockets;
-
/* This is the main loop that traverses the MFNetwork. */
while (!sockets_to_compute.is_empty()) {
const MFOutputSocket &socket = *sockets_to_compute.peek();
@@ -232,20 +230,21 @@ BLI_NOINLINE void MFNetworkEvaluator::evaluate_network_to_compute_outputs(
}
BLI_assert(node.is_function());
- BLI_assert(node.all_inputs_have_origin());
+ BLI_assert(!node.has_unlinked_inputs());
const MFFunctionNode &function_node = node.as_function();
- missing_sockets.clear();
- function_node.foreach_origin_socket([&](const MFOutputSocket &origin) {
- if (!storage.socket_is_computed(origin)) {
- missing_sockets.append(&origin);
+ bool all_origins_are_computed = true;
+ for (const MFInputSocket *input_socket : function_node.inputs()) {
+ const MFOutputSocket *origin = input_socket->origin();
+ if (origin != nullptr) {
+ if (!storage.socket_is_computed(*origin)) {
+ sockets_to_compute.push(origin);
+ all_origins_are_computed = false;
+ }
}
- });
-
- sockets_to_compute.push_multiple(missing_sockets);
+ }
- bool all_inputs_are_computed = missing_sockets.size() == 0;
- if (all_inputs_are_computed) {
+ if (all_origins_are_computed) {
this->evaluate_function(global_context, function_node, storage);
sockets_to_compute.pop();
}
@@ -264,7 +263,7 @@ BLI_NOINLINE void MFNetworkEvaluator::evaluate_function(MFContext &global_contex
* function only on a single element. This can avoid many duplicate computations. */
MFParamsBuilder params{function, 1};
- for (uint param_index : function.param_indices()) {
+ for (int param_index : function.param_indices()) {
MFParamType param_type = function.param_type(param_index);
switch (param_type.category()) {
case MFParamType::SingleInput: {
@@ -313,7 +312,7 @@ BLI_NOINLINE void MFNetworkEvaluator::evaluate_function(MFContext &global_contex
else {
MFParamsBuilder params{function, storage.mask().min_array_size()};
- for (uint param_index : function.param_indices()) {
+ for (int param_index : function.param_indices()) {
MFParamType param_type = function.param_type(param_index);
switch (param_type.category()) {
case MFParamType::SingleInput: {
@@ -385,13 +384,13 @@ BLI_NOINLINE void MFNetworkEvaluator::initialize_remaining_outputs(
MFParams params, Storage &storage, Span<const MFInputSocket *> remaining_outputs) const
{
for (const MFInputSocket *socket : remaining_outputs) {
- uint param_index = inputs_.size() + outputs_.first_index_of(socket);
+ int param_index = inputs_.size() + outputs_.first_index_of(socket);
switch (socket->data_type().category()) {
case MFDataType::Single: {
GVSpan values = storage.get_single_input__full(*socket);
GMutableSpan output_values = params.uninitialized_single_output(param_index);
- values.materialize_to_uninitialized(storage.mask(), output_values.buffer());
+ values.materialize_to_uninitialized(storage.mask(), output_values.data());
break;
}
case MFDataType::Vector: {
@@ -507,9 +506,9 @@ struct OwnVectorValue : public Value {
/** \name Storage methods
* \{ */
-MFNetworkEvaluationStorage::MFNetworkEvaluationStorage(IndexMask mask, uint max_socket_id)
+MFNetworkEvaluationStorage::MFNetworkEvaluationStorage(IndexMask mask, int socket_id_amount)
: mask_(mask),
- value_per_output_id_(max_socket_id + 1, nullptr),
+ value_per_output_id_(socket_id_amount, nullptr),
min_array_size_(mask.min_array_size())
{
}
@@ -525,11 +524,11 @@ MFNetworkEvaluationStorage::~MFNetworkEvaluationStorage()
GMutableSpan span = value->span;
const CPPType &type = span.type();
if (value->is_single_allocated) {
- type.destruct(span.buffer());
+ type.destruct(span.data());
}
else {
- type.destruct_indices(span.buffer(), mask_);
- MEM_freeN(span.buffer());
+ type.destruct_indices(span.data(), mask_);
+ MEM_freeN(span.data());
}
}
else if (any_value->type == ValueType::OwnVector) {
@@ -635,11 +634,11 @@ void MFNetworkEvaluationStorage::finish_input_socket(const MFInputSocket &socket
GMutableSpan span = value->span;
const CPPType &type = span.type();
if (value->is_single_allocated) {
- type.destruct(span.buffer());
+ type.destruct(span.data());
}
else {
- type.destruct_indices(span.buffer(), mask_);
- MEM_freeN(span.buffer());
+ type.destruct_indices(span.data(), mask_);
+ MEM_freeN(span.data());
}
value_per_output_id_[origin.id()] = nullptr;
}
@@ -792,7 +791,7 @@ GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__full(const MFInputS
BLI_assert(to_any_value->type == ValueType::OutputSingle);
GMutableSpan span = ((OutputSingleValue *)to_any_value)->span;
GVSpan virtual_span = this->get_single_input__full(input);
- virtual_span.materialize_to_uninitialized(mask_, span.buffer());
+ virtual_span.materialize_to_uninitialized(mask_, span.data());
return span;
}
@@ -809,7 +808,7 @@ GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__full(const MFInputS
GVSpan virtual_span = this->get_single_input__full(input);
void *new_buffer = MEM_mallocN_aligned(min_array_size_ * type.size(), type.alignment(), AT);
GMutableSpan new_array_ref(type, new_buffer, min_array_size_);
- virtual_span.materialize_to_uninitialized(mask_, new_array_ref.buffer());
+ virtual_span.materialize_to_uninitialized(mask_, new_array_ref.data());
OwnSingleValue *new_value = allocator_.construct<OwnSingleValue>(
new_array_ref, to.targets().size(), false);
@@ -954,7 +953,7 @@ GVSpan MFNetworkEvaluationStorage::get_single_input__full(const MFInputSocket &s
if (any_value->type == ValueType::OwnSingle) {
OwnSingleValue *value = (OwnSingleValue *)any_value;
if (value->is_single_allocated) {
- return GVSpan::FromSingle(value->span.type(), value->span.buffer(), min_array_size_);
+ return GVSpan::FromSingle(value->span.type(), value->span.data(), min_array_size_);
}
else {
return value->span;
diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc
new file mode 100644
index 00000000000..af1e77aa355
--- /dev/null
+++ b/source/blender/functions/intern/multi_function_network_optimization.cc
@@ -0,0 +1,504 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup fn
+ */
+
+/* Used to check if two multi-functions have the exact same type. */
+#include <typeinfo>
+
+#include "FN_multi_function_builder.hh"
+#include "FN_multi_function_network_evaluation.hh"
+#include "FN_multi_function_network_optimization.hh"
+
+#include "BLI_disjoint_set.hh"
+#include "BLI_ghash.h"
+#include "BLI_map.hh"
+#include "BLI_multi_value_map.hh"
+#include "BLI_rand.h"
+#include "BLI_stack.hh"
+
+namespace blender::fn::mf_network_optimization {
+
+/* -------------------------------------------------------------------- */
+/** \name Utility functions to find nodes in a network.
+ *
+ * \{ */
+
+static bool set_tag_and_check_if_modified(bool &tag, bool new_value)
+{
+ if (tag != new_value) {
+ tag = new_value;
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+static Array<bool> mask_nodes_to_the_left(MFNetwork &network, Span<MFNode *> nodes)
+{
+ Array<bool> is_to_the_left(network.node_id_amount(), false);
+ Stack<MFNode *> nodes_to_check;
+
+ for (MFNode *node : nodes) {
+ is_to_the_left[node->id()] = true;
+ nodes_to_check.push(node);
+ }
+
+ while (!nodes_to_check.is_empty()) {
+ MFNode &node = *nodes_to_check.pop();
+
+ for (MFInputSocket *input_socket : node.inputs()) {
+ MFOutputSocket *origin = input_socket->origin();
+ if (origin != nullptr) {
+ MFNode &origin_node = origin->node();
+ if (set_tag_and_check_if_modified(is_to_the_left[origin_node.id()], true)) {
+ nodes_to_check.push(&origin_node);
+ }
+ }
+ }
+ }
+
+ return is_to_the_left;
+}
+
+static Array<bool> mask_nodes_to_the_right(MFNetwork &network, Span<MFNode *> nodes)
+{
+ Array<bool> is_to_the_right(network.node_id_amount(), false);
+ Stack<MFNode *> nodes_to_check;
+
+ for (MFNode *node : nodes) {
+ is_to_the_right[node->id()] = true;
+ nodes_to_check.push(node);
+ }
+
+ while (!nodes_to_check.is_empty()) {
+ MFNode &node = *nodes_to_check.pop();
+
+ for (MFOutputSocket *output_socket : node.outputs()) {
+ for (MFInputSocket *target_socket : output_socket->targets()) {
+ MFNode &target_node = target_socket->node();
+ if (set_tag_and_check_if_modified(is_to_the_right[target_node.id()], true)) {
+ nodes_to_check.push(&target_node);
+ }
+ }
+ }
+ }
+
+ return is_to_the_right;
+}
+
+static Vector<MFNode *> find_nodes_based_on_mask(MFNetwork &network,
+ Span<bool> id_mask,
+ bool mask_value)
+{
+ Vector<MFNode *> nodes;
+ for (int id : id_mask.index_range()) {
+ if (id_mask[id] == mask_value) {
+ MFNode *node = network.node_or_null_by_id(id);
+ if (node != nullptr) {
+ nodes.append(node);
+ }
+ }
+ }
+ return nodes;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Dead Node Removal
+ *
+ * \{ */
+
+/**
+ * Unused nodes are all those nodes that no dummy node depends upon.
+ */
+void dead_node_removal(MFNetwork &network)
+{
+ Array<bool> node_is_used_mask = mask_nodes_to_the_left(network, network.dummy_nodes());
+ Vector<MFNode *> nodes_to_remove = find_nodes_based_on_mask(network, node_is_used_mask, false);
+ network.remove(nodes_to_remove);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Constant Folding
+ *
+ * \{ */
+
+static bool function_node_can_be_constant(MFFunctionNode *node)
+{
+ if (node->has_unlinked_inputs()) {
+ return false;
+ }
+ if (node->function().depends_on_context()) {
+ return false;
+ }
+ return true;
+}
+
+static Vector<MFNode *> find_non_constant_nodes(MFNetwork &network)
+{
+ Vector<MFNode *> non_constant_nodes;
+ non_constant_nodes.extend(network.dummy_nodes());
+
+ for (MFFunctionNode *node : network.function_nodes()) {
+ if (!function_node_can_be_constant(node)) {
+ non_constant_nodes.append(node);
+ }
+ }
+ return non_constant_nodes;
+}
+
+static bool output_has_non_constant_target_node(MFOutputSocket *output_socket,
+ Span<bool> is_not_constant_mask)
+{
+ for (MFInputSocket *target_socket : output_socket->targets()) {
+ MFNode &target_node = target_socket->node();
+ bool target_is_not_constant = is_not_constant_mask[target_node.id()];
+ if (target_is_not_constant) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static MFInputSocket *try_find_dummy_target_socket(MFOutputSocket *output_socket)
+{
+ for (MFInputSocket *target_socket : output_socket->targets()) {
+ if (target_socket->node().is_dummy()) {
+ return target_socket;
+ }
+ }
+ return nullptr;
+}
+
+static Vector<MFInputSocket *> find_constant_inputs_to_fold(
+ MFNetwork &network, Vector<MFDummyNode *> &r_temporary_nodes)
+{
+ Vector<MFNode *> non_constant_nodes = find_non_constant_nodes(network);
+ Array<bool> is_not_constant_mask = mask_nodes_to_the_right(network, non_constant_nodes);
+ Vector<MFNode *> constant_nodes = find_nodes_based_on_mask(network, is_not_constant_mask, false);
+
+ Vector<MFInputSocket *> sockets_to_compute;
+ for (MFNode *node : constant_nodes) {
+ if (node->inputs().size() == 0) {
+ continue;
+ }
+
+ for (MFOutputSocket *output_socket : node->outputs()) {
+ MFDataType data_type = output_socket->data_type();
+ if (output_has_non_constant_target_node(output_socket, is_not_constant_mask)) {
+ MFInputSocket *dummy_target = try_find_dummy_target_socket(output_socket);
+ if (dummy_target == nullptr) {
+ dummy_target = &network.add_output("Dummy", data_type);
+ network.add_link(*output_socket, *dummy_target);
+ r_temporary_nodes.append(&dummy_target->node().as_dummy());
+ }
+
+ sockets_to_compute.append(dummy_target);
+ }
+ }
+ }
+ return sockets_to_compute;
+}
+
+static void prepare_params_for_constant_folding(const MultiFunction &network_fn,
+ MFParamsBuilder &params,
+ ResourceCollector &resources)
+{
+ for (int param_index : network_fn.param_indices()) {
+ MFParamType param_type = network_fn.param_type(param_index);
+ MFDataType data_type = param_type.data_type();
+
+ switch (data_type.category()) {
+ case MFDataType::Single: {
+ /* Allocates memory for a single constant folded value. */
+ const CPPType &cpp_type = data_type.single_type();
+ void *buffer = resources.linear_allocator().allocate(cpp_type.size(),
+ cpp_type.alignment());
+ GMutableSpan array{cpp_type, buffer, 1};
+ params.add_uninitialized_single_output(array);
+ break;
+ }
+ case MFDataType::Vector: {
+ /* Allocates memory for a constant folded vector. */
+ const CPPType &cpp_type = data_type.vector_base_type();
+ GVectorArray &vector_array = resources.construct<GVectorArray>(AT, cpp_type, 1);
+ params.add_vector_output(vector_array);
+ break;
+ }
+ }
+ }
+}
+
+static Array<MFOutputSocket *> add_constant_folded_sockets(const MultiFunction &network_fn,
+ MFParamsBuilder &params,
+ ResourceCollector &resources,
+ MFNetwork &network)
+{
+ Array<MFOutputSocket *> folded_sockets{network_fn.param_indices().size(), nullptr};
+
+ for (int param_index : network_fn.param_indices()) {
+ MFParamType param_type = network_fn.param_type(param_index);
+ MFDataType data_type = param_type.data_type();
+
+ const MultiFunction *constant_fn = nullptr;
+
+ switch (data_type.category()) {
+ case MFDataType::Single: {
+ const CPPType &cpp_type = data_type.single_type();
+ GMutableSpan array = params.computed_array(param_index);
+ void *buffer = array.data();
+ resources.add(buffer, array.type().destruct_cb(), AT);
+
+ constant_fn = &resources.construct<CustomMF_GenericConstant>(AT, cpp_type, buffer);
+ break;
+ }
+ case MFDataType::Vector: {
+ GVectorArray &vector_array = params.computed_vector_array(param_index);
+ GSpan array = vector_array[0];
+ constant_fn = &resources.construct<CustomMF_GenericConstantArray>(AT, array);
+ break;
+ }
+ }
+
+ MFFunctionNode &folded_node = network.add_function(*constant_fn);
+ folded_sockets[param_index] = &folded_node.output(0);
+ }
+ return folded_sockets;
+}
+
+static Array<MFOutputSocket *> compute_constant_sockets_and_add_folded_nodes(
+ MFNetwork &network,
+ Span<const MFInputSocket *> sockets_to_compute,
+ ResourceCollector &resources)
+{
+ MFNetworkEvaluator network_fn{{}, sockets_to_compute};
+
+ MFContextBuilder context;
+ MFParamsBuilder params{network_fn, 1};
+ prepare_params_for_constant_folding(network_fn, params, resources);
+ network_fn.call({0}, params, context);
+ return add_constant_folded_sockets(network_fn, params, resources, network);
+}
+
+/**
+ * Find function nodes that always output the same value and replace those with constant nodes.
+ */
+void constant_folding(MFNetwork &network, ResourceCollector &resources)
+{
+ Vector<MFDummyNode *> temporary_nodes;
+ Vector<MFInputSocket *> inputs_to_fold = find_constant_inputs_to_fold(network, temporary_nodes);
+ if (inputs_to_fold.size() == 0) {
+ return;
+ }
+
+ Array<MFOutputSocket *> folded_sockets = compute_constant_sockets_and_add_folded_nodes(
+ network, inputs_to_fold, resources);
+
+ for (int i : inputs_to_fold.index_range()) {
+ MFOutputSocket &original_socket = *inputs_to_fold[i]->origin();
+ network.relink(original_socket, *folded_sockets[i]);
+ }
+
+ network.remove(temporary_nodes);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Common Sub-network Elimination
+ *
+ * \{ */
+
+static uint64_t compute_node_hash(MFFunctionNode &node, RNG *rng, Span<uint64_t> node_hashes)
+{
+ if (node.function().depends_on_context()) {
+ return BLI_rng_get_uint(rng);
+ }
+ if (node.has_unlinked_inputs()) {
+ return BLI_rng_get_uint(rng);
+ }
+
+ uint64_t combined_inputs_hash = 394659347u;
+ for (MFInputSocket *input_socket : node.inputs()) {
+ MFOutputSocket *origin_socket = input_socket->origin();
+ uint64_t input_hash = BLI_ghashutil_combine_hash(node_hashes[origin_socket->node().id()],
+ origin_socket->index());
+ combined_inputs_hash = BLI_ghashutil_combine_hash(combined_inputs_hash, input_hash);
+ }
+
+ uint64_t function_hash = node.function().hash();
+ uint64_t node_hash = BLI_ghashutil_combine_hash(combined_inputs_hash, function_hash);
+ return node_hash;
+}
+
+/**
+ * Produces a hash for every node. Two nodes with the same hash should have a high probability of
+ * outputting the same values.
+ */
+static Array<uint64_t> compute_node_hashes(MFNetwork &network)
+{
+ RNG *rng = BLI_rng_new(0);
+ Array<uint64_t> node_hashes(network.node_id_amount());
+ Array<bool> node_is_hashed(network.node_id_amount(), false);
+
+ /* No dummy nodes are not assumed to output the same values. */
+ for (MFDummyNode *node : network.dummy_nodes()) {
+ uint64_t node_hash = BLI_rng_get_uint(rng);
+ node_hashes[node->id()] = node_hash;
+ node_is_hashed[node->id()] = true;
+ }
+
+ Stack<MFFunctionNode *> nodes_to_check;
+ nodes_to_check.push_multiple(network.function_nodes());
+
+ while (!nodes_to_check.is_empty()) {
+ MFFunctionNode &node = *nodes_to_check.peek();
+ if (node_is_hashed[node.id()]) {
+ nodes_to_check.pop();
+ continue;
+ }
+
+ /* Make sure that origin nodes are hashed first. */
+ bool all_dependencies_ready = true;
+ for (MFInputSocket *input_socket : node.inputs()) {
+ MFOutputSocket *origin_socket = input_socket->origin();
+ if (origin_socket != nullptr) {
+ MFNode &origin_node = origin_socket->node();
+ if (!node_is_hashed[origin_node.id()]) {
+ all_dependencies_ready = false;
+ nodes_to_check.push(&origin_node.as_function());
+ }
+ }
+ }
+ if (!all_dependencies_ready) {
+ continue;
+ }
+
+ uint64_t node_hash = compute_node_hash(node, rng, node_hashes);
+ node_hashes[node.id()] = node_hash;
+ node_is_hashed[node.id()] = true;
+ nodes_to_check.pop();
+ }
+
+ BLI_rng_free(rng);
+ return node_hashes;
+}
+
+static MultiValueMap<uint64_t, MFNode *> group_nodes_by_hash(MFNetwork &network,
+ Span<uint64_t> node_hashes)
+{
+ MultiValueMap<uint64_t, MFNode *> nodes_by_hash;
+ for (int id : IndexRange(network.node_id_amount())) {
+ MFNode *node = network.node_or_null_by_id(id);
+ if (node != nullptr) {
+ uint64_t node_hash = node_hashes[id];
+ nodes_by_hash.add(node_hash, node);
+ }
+ }
+ return nodes_by_hash;
+}
+
+static bool functions_are_equal(const MultiFunction &a, const MultiFunction &b)
+{
+ if (&a == &b) {
+ return true;
+ }
+ if (typeid(a) == typeid(b)) {
+ return a.equals(b);
+ }
+ return false;
+}
+
+static bool nodes_output_same_values(DisjointSet &cache, const MFNode &a, const MFNode &b)
+{
+ if (cache.in_same_set(a.id(), b.id())) {
+ return true;
+ }
+
+ if (a.is_dummy() || b.is_dummy()) {
+ return false;
+ }
+ if (!functions_are_equal(a.as_function().function(), b.as_function().function())) {
+ return false;
+ }
+ for (int i : a.inputs().index_range()) {
+ const MFOutputSocket *origin_a = a.input(i).origin();
+ const MFOutputSocket *origin_b = b.input(i).origin();
+ if (origin_a == nullptr || origin_b == nullptr) {
+ return false;
+ }
+ if (!nodes_output_same_values(cache, origin_a->node(), origin_b->node())) {
+ return false;
+ }
+ }
+
+ cache.join(a.id(), b.id());
+ return true;
+}
+
+static void relink_duplicate_nodes(MFNetwork &network,
+ MultiValueMap<uint64_t, MFNode *> &nodes_by_hash)
+{
+ DisjointSet same_node_cache{network.node_id_amount()};
+
+ for (Span<MFNode *> nodes_with_same_hash : nodes_by_hash.values()) {
+ if (nodes_with_same_hash.size() <= 1) {
+ continue;
+ }
+
+ Vector<MFNode *, 16> nodes_to_check = nodes_with_same_hash;
+ while (nodes_to_check.size() >= 2) {
+ Vector<MFNode *, 16> remaining_nodes;
+
+ MFNode &deduplicated_node = *nodes_to_check[0];
+ for (MFNode *node : nodes_to_check.as_span().drop_front(1)) {
+ /* This is true with fairly high probability, but hash collisions can happen. So we have to
+ * check if the node actually output the same values. */
+ if (nodes_output_same_values(same_node_cache, deduplicated_node, *node)) {
+ for (int i : deduplicated_node.outputs().index_range()) {
+ network.relink(node->output(i), deduplicated_node.output(i));
+ }
+ }
+ else {
+ remaining_nodes.append(node);
+ }
+ }
+ nodes_to_check = std::move(remaining_nodes);
+ }
+ }
+}
+
+/**
+ * Tries to detect duplicate sub-networks and eliminates them. This can help quite a lot when node
+ * groups were used to create the network.
+ */
+void common_subnetwork_elimination(MFNetwork &network)
+{
+ Array<uint64_t> node_hashes = compute_node_hashes(network);
+ MultiValueMap<uint64_t, MFNode *> nodes_by_hash = group_nodes_by_hash(network, node_hashes);
+ relink_duplicate_nodes(network, nodes_by_hash);
+}
+
+/** \} */
+
+} // namespace blender::fn::mf_network_optimization
diff --git a/source/blender/functions/tests/FN_array_spans_test.cc b/source/blender/functions/tests/FN_array_spans_test.cc
new file mode 100644
index 00000000000..9a632b58be8
--- /dev/null
+++ b/source/blender/functions/tests/FN_array_spans_test.cc
@@ -0,0 +1,132 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_array_spans.hh"
+#include "FN_generic_vector_array.hh"
+
+#include "BLI_array.hh"
+
+namespace blender::fn::tests {
+
+TEST(virtual_array_span, EmptyConstructor)
+{
+ VArraySpan<int> span;
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+
+ GVArraySpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(virtual_array_span, SingleArrayConstructor)
+{
+ std::array<int, 4> values = {3, 4, 5, 6};
+ VArraySpan<int> span{Span<int>(values), 3};
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0].size(), 4);
+ EXPECT_EQ(span[1].size(), 4);
+ EXPECT_EQ(span[2].size(), 4);
+ EXPECT_EQ(span[0][0], 3);
+ EXPECT_EQ(span[0][1], 4);
+ EXPECT_EQ(span[0][2], 5);
+ EXPECT_EQ(span[0][3], 6);
+ EXPECT_EQ(span[1][3], 6);
+ EXPECT_EQ(span[2][1], 4);
+
+ GVArraySpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0].size(), 4);
+ EXPECT_EQ(converted[1].size(), 4);
+ EXPECT_EQ(converted[1][2], &values[2]);
+}
+
+TEST(virtual_array_span, MultipleArrayConstructor)
+{
+ std::array<int, 4> values0 = {1, 2, 3, 4};
+ std::array<int, 2> values1 = {6, 7};
+ std::array<int, 1> values2 = {8};
+ std::array<const int *, 3> starts = {values0.data(), values1.data(), values2.data()};
+ std::array<int64_t, 3> sizes{values0.size(), values1.size(), values2.size()};
+
+ VArraySpan<int> span{starts, sizes};
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0].size(), 4);
+ EXPECT_EQ(span[1].size(), 2);
+ EXPECT_EQ(span[2].size(), 1);
+ EXPECT_EQ(&span[0][0], values0.data());
+ EXPECT_EQ(&span[1][0], values1.data());
+ EXPECT_EQ(&span[2][0], values2.data());
+ EXPECT_EQ(span[2][0], 8);
+ EXPECT_EQ(span[1][1], 7);
+
+ GVArraySpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0].size(), 4);
+ EXPECT_EQ(converted[1].size(), 2);
+ EXPECT_EQ(converted[2].size(), 1);
+ EXPECT_EQ(converted[0][0], values0.data());
+ EXPECT_EQ(converted[1][1], values1.data() + 1);
+}
+
+TEST(generic_virtual_array_span, TypeConstructor)
+{
+ GVArraySpan span{CPPType::get<int32_t>()};
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+
+ VArraySpan converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(generic_virtual_array_span, GSpanConstructor)
+{
+ std::array<std::string, 3> values = {"hello", "world", "test"};
+ GVArraySpan span{GSpan(CPPType::get<std::string>(), values.data(), 3), 5};
+ EXPECT_EQ(span.size(), 5);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0][0], values.data());
+ EXPECT_EQ(span[1][0], values.data());
+ EXPECT_EQ(span[4][0], values.data());
+ EXPECT_EQ(span[0].size(), 3);
+ EXPECT_EQ(span[2].size(), 3);
+ EXPECT_EQ(*(std::string *)span[3][1], "world");
+
+ VArraySpan converted = span.typed<std::string>();
+ EXPECT_EQ(converted.size(), 5);
+ EXPECT_EQ(converted[0][0], "hello");
+ EXPECT_EQ(converted[1][0], "hello");
+ EXPECT_EQ(converted[4][0], "hello");
+ EXPECT_EQ(converted[0].size(), 3);
+ EXPECT_EQ(converted[2].size(), 3);
+}
+
+TEST(generic_virtual_array_span, IsSingleArray1)
+{
+ Array<int> values = {5, 6, 7};
+ GVArraySpan span{GSpan(values.as_span()), 4};
+ EXPECT_TRUE(span.is_single_array());
+
+ VArraySpan converted = span.typed<int>();
+ EXPECT_TRUE(converted.is_single_array());
+}
+
+TEST(generic_virtual_array_span, IsSingleArray2)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 3};
+ GVectorArrayRef<int> vectors_ref = vectors;
+ vectors_ref.append(1, 4);
+
+ GVArraySpan span = vectors;
+ EXPECT_FALSE(span.is_single_array());
+
+ VArraySpan converted = span.typed<int>();
+ EXPECT_FALSE(converted.is_single_array());
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_attributes_ref_test.cc b/source/blender/functions/tests/FN_attributes_ref_test.cc
new file mode 100644
index 00000000000..3a5e4743c1e
--- /dev/null
+++ b/source/blender/functions/tests/FN_attributes_ref_test.cc
@@ -0,0 +1,97 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_float3.hh"
+#include "FN_attributes_ref.hh"
+
+#include "testing/testing.h"
+
+namespace blender::fn::tests {
+
+TEST(attributes_info, BuildEmpty)
+{
+ AttributesInfoBuilder info_builder;
+ AttributesInfo info{info_builder};
+
+ EXPECT_EQ(info.size(), 0);
+}
+
+TEST(attributes_info, AddSameNameTwice)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add<int>("A", 4);
+ info_builder.add<int>("A", 5);
+ AttributesInfo info{info_builder};
+ EXPECT_EQ(info.size(), 1);
+ EXPECT_TRUE(info.has_attribute("A", CPPType::get<int>()));
+ EXPECT_FALSE(info.has_attribute("B", CPPType::get<int>()));
+ EXPECT_FALSE(info.has_attribute("A", CPPType::get<float>()));
+ EXPECT_EQ(info.default_of<int>("A"), 4);
+ EXPECT_EQ(info.name_of(0), "A");
+ EXPECT_EQ(info.index_range().start(), 0);
+ EXPECT_EQ(info.index_range().one_after_last(), 1);
+}
+
+TEST(attributes_info, BuildWithDefaultString)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add("A", CPPType::get<std::string>());
+ AttributesInfo info{info_builder};
+ EXPECT_EQ(info.default_of<std::string>("A"), "");
+}
+
+TEST(attributes_info, BuildWithGivenDefault)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add<std::string>("A", "hello world");
+ AttributesInfo info{info_builder};
+ const void *default_value = info.default_of("A");
+ EXPECT_EQ(*(const std::string *)default_value, "hello world");
+ EXPECT_EQ(info.type_of("A"), CPPType::get<std::string>());
+}
+
+TEST(mutable_attributes_ref, ComplexTest)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add<float3>("Position", {0, 0, 10});
+ info_builder.add<uint>("ID", 0);
+ info_builder.add<float>("Size", 0.5f);
+ info_builder.add<std::string>("Name", "<no name>");
+ AttributesInfo info{info_builder};
+
+ int amount = 5;
+ Array<float3> positions(amount);
+ Array<uint> ids(amount, 0);
+ Array<float> sizes(amount);
+ Array<std::string> names(amount);
+
+ Array<void *> buffers = {positions.data(), ids.data(), sizes.data(), names.data()};
+ MutableAttributesRef attributes{info, buffers, IndexRange(1, 3)};
+ EXPECT_EQ(attributes.size(), 3);
+ EXPECT_EQ(attributes.info().size(), 4);
+ EXPECT_EQ(attributes.get("Position").data(), positions.data() + 1);
+ EXPECT_EQ(attributes.get("ID").data(), ids.data() + 1);
+ EXPECT_EQ(attributes.get("Size").data(), sizes.data() + 1);
+ EXPECT_EQ(attributes.get("Name").data(), names.data() + 1);
+
+ EXPECT_EQ(attributes.get("ID").size(), 3);
+ EXPECT_EQ(attributes.get<uint>("ID").size(), 3);
+
+ EXPECT_EQ(ids[2], 0);
+ MutableSpan<uint> ids_span = attributes.get<uint>("ID");
+ ids_span[1] = 42;
+ EXPECT_EQ(ids[2], 42);
+
+ EXPECT_FALSE(attributes.try_get<int>("not existant").has_value());
+ EXPECT_FALSE(attributes.try_get<int>("Position").has_value());
+ EXPECT_TRUE(attributes.try_get<float3>("Position").has_value());
+ EXPECT_FALSE(attributes.try_get("not existant", CPPType::get<int>()).has_value());
+ EXPECT_FALSE(attributes.try_get("Position", CPPType::get<int>()).has_value());
+ EXPECT_TRUE(attributes.try_get("Position", CPPType::get<float3>()).has_value());
+
+ MutableAttributesRef sliced = attributes.slice(IndexRange(1, 2));
+ EXPECT_EQ(sliced.size(), 2);
+ sliced.get<uint>("ID")[0] = 100;
+ EXPECT_EQ(ids[2], 100);
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_cpp_type_test.cc b/source/blender/functions/tests/FN_cpp_type_test.cc
new file mode 100644
index 00000000000..29368b251cc
--- /dev/null
+++ b/source/blender/functions/tests/FN_cpp_type_test.cc
@@ -0,0 +1,325 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_cpp_type.hh"
+
+namespace blender::fn::tests {
+
+static const int default_constructed_value = 1;
+static const int copy_constructed_value = 2;
+static const int move_constructed_value = 3;
+static const int copy_constructed_from_value = 4;
+static const int move_constructed_from_value = 5;
+static const int copy_assigned_value = 6;
+static const int copy_assigned_from_value = 7;
+static const int move_assigned_value = 8;
+static const int move_assigned_from_value = 9;
+static const int destructed_value = 10;
+
+struct TestType {
+ mutable volatile int value;
+
+ TestType()
+ {
+ value = default_constructed_value;
+ }
+
+ ~TestType()
+ {
+ value = destructed_value;
+ }
+
+ TestType(const TestType &other)
+ {
+ value = copy_constructed_value;
+ other.value = copy_constructed_from_value;
+ }
+
+ TestType(TestType &&other) noexcept
+ {
+ value = move_constructed_value;
+ other.value = move_constructed_from_value;
+ }
+
+ TestType &operator=(const TestType &other)
+ {
+ value = copy_assigned_value;
+ other.value = copy_assigned_from_value;
+ return *this;
+ }
+
+ TestType &operator=(TestType &&other) noexcept
+ {
+ value = move_assigned_value;
+ other.value = move_assigned_from_value;
+ return *this;
+ }
+
+ friend std::ostream &operator<<(std::ostream &stream, const TestType &value)
+ {
+ stream << value.value;
+ return stream;
+ }
+
+ friend bool operator==(const TestType &UNUSED(a), const TestType &UNUSED(b))
+ {
+ return false;
+ }
+
+ uint64_t hash() const
+ {
+ return 0;
+ }
+};
+
+} // namespace blender::fn::tests
+
+MAKE_CPP_TYPE(TestType, blender::fn::tests::TestType)
+
+namespace blender::fn::tests {
+
+const CPPType &CPPType_TestType = CPPType::get<TestType>();
+
+TEST(cpp_type, Size)
+{
+ EXPECT_EQ(CPPType_TestType.size(), sizeof(TestType));
+}
+
+TEST(cpp_type, Alignment)
+{
+ EXPECT_EQ(CPPType_TestType.alignment(), alignof(TestType));
+}
+
+TEST(cpp_type, Is)
+{
+ EXPECT_TRUE(CPPType_TestType.is<TestType>());
+ EXPECT_FALSE(CPPType_TestType.is<int>());
+}
+
+TEST(cpp_type, DefaultConstruction)
+{
+ int buffer[10] = {0};
+ CPPType_TestType.construct_default((void *)buffer);
+ EXPECT_EQ(buffer[0], default_constructed_value);
+ EXPECT_EQ(buffer[1], 0);
+ CPPType_TestType.construct_default_n((void *)buffer, 3);
+ EXPECT_EQ(buffer[0], default_constructed_value);
+ EXPECT_EQ(buffer[1], default_constructed_value);
+ EXPECT_EQ(buffer[2], default_constructed_value);
+ EXPECT_EQ(buffer[3], 0);
+ CPPType_TestType.construct_default_indices((void *)buffer, {2, 5, 7});
+ EXPECT_EQ(buffer[2], default_constructed_value);
+ EXPECT_EQ(buffer[4], 0);
+ EXPECT_EQ(buffer[5], default_constructed_value);
+ EXPECT_EQ(buffer[6], 0);
+ EXPECT_EQ(buffer[7], default_constructed_value);
+ EXPECT_EQ(buffer[8], 0);
+}
+
+TEST(cpp_type, Destruct)
+{
+ int buffer[10] = {0};
+ CPPType_TestType.destruct((void *)buffer);
+ EXPECT_EQ(buffer[0], destructed_value);
+ EXPECT_EQ(buffer[1], 0);
+ CPPType_TestType.destruct_n((void *)buffer, 3);
+ EXPECT_EQ(buffer[0], destructed_value);
+ EXPECT_EQ(buffer[1], destructed_value);
+ EXPECT_EQ(buffer[2], destructed_value);
+ EXPECT_EQ(buffer[3], 0);
+ CPPType_TestType.destruct_indices((void *)buffer, {2, 5, 7});
+ EXPECT_EQ(buffer[2], destructed_value);
+ EXPECT_EQ(buffer[4], 0);
+ EXPECT_EQ(buffer[5], destructed_value);
+ EXPECT_EQ(buffer[6], 0);
+ EXPECT_EQ(buffer[7], destructed_value);
+ EXPECT_EQ(buffer[8], 0);
+}
+
+TEST(cpp_type, CopyToUninitialized)
+{
+ int buffer1[10] = {0};
+ int buffer2[10] = {0};
+ CPPType_TestType.copy_to_uninitialized((void *)buffer1, (void *)buffer2);
+ EXPECT_EQ(buffer1[0], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[0], copy_constructed_value);
+ CPPType_TestType.copy_to_uninitialized_n((void *)buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1[0], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[0], copy_constructed_value);
+ EXPECT_EQ(buffer1[1], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[1], copy_constructed_value);
+ EXPECT_EQ(buffer1[2], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[2], copy_constructed_value);
+ EXPECT_EQ(buffer1[3], 0);
+ EXPECT_EQ(buffer2[3], 0);
+ CPPType_TestType.copy_to_uninitialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
+ EXPECT_EQ(buffer1[2], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[2], copy_constructed_value);
+ EXPECT_EQ(buffer1[4], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer1[5], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[5], copy_constructed_value);
+ EXPECT_EQ(buffer1[6], 0);
+ EXPECT_EQ(buffer2[6], 0);
+ EXPECT_EQ(buffer1[7], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[7], copy_constructed_value);
+ EXPECT_EQ(buffer1[8], 0);
+ EXPECT_EQ(buffer2[8], 0);
+}
+
+TEST(cpp_type, CopyToInitialized)
+{
+ int buffer1[10] = {0};
+ int buffer2[10] = {0};
+ CPPType_TestType.copy_to_initialized((void *)buffer1, (void *)buffer2);
+ EXPECT_EQ(buffer1[0], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[0], copy_assigned_value);
+ CPPType_TestType.copy_to_initialized_n((void *)buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1[0], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[0], copy_assigned_value);
+ EXPECT_EQ(buffer1[1], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[1], copy_assigned_value);
+ EXPECT_EQ(buffer1[2], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[2], copy_assigned_value);
+ EXPECT_EQ(buffer1[3], 0);
+ EXPECT_EQ(buffer2[3], 0);
+ CPPType_TestType.copy_to_initialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
+ EXPECT_EQ(buffer1[2], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[2], copy_assigned_value);
+ EXPECT_EQ(buffer1[4], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer1[5], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[5], copy_assigned_value);
+ EXPECT_EQ(buffer1[6], 0);
+ EXPECT_EQ(buffer2[6], 0);
+ EXPECT_EQ(buffer1[7], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[7], copy_assigned_value);
+ EXPECT_EQ(buffer1[8], 0);
+ EXPECT_EQ(buffer2[8], 0);
+}
+
+TEST(cpp_type, RelocateToUninitialized)
+{
+ int buffer1[10] = {0};
+ int buffer2[10] = {0};
+ CPPType_TestType.relocate_to_uninitialized((void *)buffer1, (void *)buffer2);
+ EXPECT_EQ(buffer1[0], destructed_value);
+ EXPECT_EQ(buffer2[0], move_constructed_value);
+ CPPType_TestType.relocate_to_uninitialized_n((void *)buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1[0], destructed_value);
+ EXPECT_EQ(buffer2[0], move_constructed_value);
+ EXPECT_EQ(buffer1[1], destructed_value);
+ EXPECT_EQ(buffer2[1], move_constructed_value);
+ EXPECT_EQ(buffer1[2], destructed_value);
+ EXPECT_EQ(buffer2[2], move_constructed_value);
+ EXPECT_EQ(buffer1[3], 0);
+ EXPECT_EQ(buffer2[3], 0);
+ CPPType_TestType.relocate_to_uninitialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
+ EXPECT_EQ(buffer1[2], destructed_value);
+ EXPECT_EQ(buffer2[2], move_constructed_value);
+ EXPECT_EQ(buffer1[4], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer1[5], destructed_value);
+ EXPECT_EQ(buffer2[5], move_constructed_value);
+ EXPECT_EQ(buffer1[6], 0);
+ EXPECT_EQ(buffer2[6], 0);
+ EXPECT_EQ(buffer1[7], destructed_value);
+ EXPECT_EQ(buffer2[7], move_constructed_value);
+ EXPECT_EQ(buffer1[8], 0);
+ EXPECT_EQ(buffer2[8], 0);
+}
+
+TEST(cpp_type, RelocateToInitialized)
+{
+ int buffer1[10] = {0};
+ int buffer2[10] = {0};
+ CPPType_TestType.relocate_to_initialized((void *)buffer1, (void *)buffer2);
+ EXPECT_EQ(buffer1[0], destructed_value);
+ EXPECT_EQ(buffer2[0], move_assigned_value);
+ CPPType_TestType.relocate_to_initialized_n((void *)buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1[0], destructed_value);
+ EXPECT_EQ(buffer2[0], move_assigned_value);
+ EXPECT_EQ(buffer1[1], destructed_value);
+ EXPECT_EQ(buffer2[1], move_assigned_value);
+ EXPECT_EQ(buffer1[2], destructed_value);
+ EXPECT_EQ(buffer2[2], move_assigned_value);
+ EXPECT_EQ(buffer1[3], 0);
+ EXPECT_EQ(buffer2[3], 0);
+ CPPType_TestType.relocate_to_initialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
+ EXPECT_EQ(buffer1[2], destructed_value);
+ EXPECT_EQ(buffer2[2], move_assigned_value);
+ EXPECT_EQ(buffer1[4], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer1[5], destructed_value);
+ EXPECT_EQ(buffer2[5], move_assigned_value);
+ EXPECT_EQ(buffer1[6], 0);
+ EXPECT_EQ(buffer2[6], 0);
+ EXPECT_EQ(buffer1[7], destructed_value);
+ EXPECT_EQ(buffer2[7], move_assigned_value);
+ EXPECT_EQ(buffer1[8], 0);
+ EXPECT_EQ(buffer2[8], 0);
+}
+
+TEST(cpp_type, FillInitialized)
+{
+ int buffer1 = 0;
+ int buffer2[10] = {0};
+ CPPType_TestType.fill_initialized((void *)&buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1, copy_assigned_from_value);
+ EXPECT_EQ(buffer2[0], copy_assigned_value);
+ EXPECT_EQ(buffer2[1], copy_assigned_value);
+ EXPECT_EQ(buffer2[2], copy_assigned_value);
+ EXPECT_EQ(buffer2[3], 0);
+
+ buffer1 = 0;
+ CPPType_TestType.fill_initialized_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8});
+ EXPECT_EQ(buffer1, copy_assigned_from_value);
+ EXPECT_EQ(buffer2[0], copy_assigned_value);
+ EXPECT_EQ(buffer2[1], copy_assigned_value);
+ EXPECT_EQ(buffer2[2], copy_assigned_value);
+ EXPECT_EQ(buffer2[3], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer2[5], 0);
+ EXPECT_EQ(buffer2[6], copy_assigned_value);
+ EXPECT_EQ(buffer2[7], 0);
+ EXPECT_EQ(buffer2[8], copy_assigned_value);
+ EXPECT_EQ(buffer2[9], 0);
+}
+
+TEST(cpp_type, FillUninitialized)
+{
+ int buffer1 = 0;
+ int buffer2[10] = {0};
+ CPPType_TestType.fill_uninitialized((void *)&buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1, copy_constructed_from_value);
+ EXPECT_EQ(buffer2[0], copy_constructed_value);
+ EXPECT_EQ(buffer2[1], copy_constructed_value);
+ EXPECT_EQ(buffer2[2], copy_constructed_value);
+ EXPECT_EQ(buffer2[3], 0);
+
+ buffer1 = 0;
+ CPPType_TestType.fill_uninitialized_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8});
+ EXPECT_EQ(buffer1, copy_constructed_from_value);
+ EXPECT_EQ(buffer2[0], copy_constructed_value);
+ EXPECT_EQ(buffer2[1], copy_constructed_value);
+ EXPECT_EQ(buffer2[2], copy_constructed_value);
+ EXPECT_EQ(buffer2[3], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer2[5], 0);
+ EXPECT_EQ(buffer2[6], copy_constructed_value);
+ EXPECT_EQ(buffer2[7], 0);
+ EXPECT_EQ(buffer2[8], copy_constructed_value);
+ EXPECT_EQ(buffer2[9], 0);
+}
+
+TEST(cpp_type, DebugPrint)
+{
+ int value = 42;
+ std::stringstream ss;
+ CPPType::get<int32_t>().debug_print((void *)&value, ss);
+ std::string text = ss.str();
+ EXPECT_EQ(text, "42");
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_generic_vector_array_test.cc b/source/blender/functions/tests/FN_generic_vector_array_test.cc
new file mode 100644
index 00000000000..77ec05f12dc
--- /dev/null
+++ b/source/blender/functions/tests/FN_generic_vector_array_test.cc
@@ -0,0 +1,101 @@
+/* Apache License, Version 2.0 */
+
+#include "FN_generic_vector_array.hh"
+
+#include "testing/testing.h"
+
+namespace blender::fn::tests {
+
+TEST(generic_vector_array, Constructor)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 3};
+ EXPECT_EQ(vectors.size(), 3);
+ EXPECT_EQ(vectors.lengths().size(), 3);
+ EXPECT_EQ(vectors.starts().size(), 3);
+ EXPECT_EQ(vectors.lengths()[0], 0);
+ EXPECT_EQ(vectors.lengths()[1], 0);
+ EXPECT_EQ(vectors.lengths()[2], 0);
+ EXPECT_EQ(vectors.type(), CPPType::get<int32_t>());
+}
+
+TEST(generic_vector_array, Append)
+{
+ GVectorArray vectors{CPPType::get<std::string>(), 3};
+ std::string value = "hello";
+ vectors.append(0, &value);
+ value = "world";
+ vectors.append(0, &value);
+ vectors.append(2, &value);
+
+ EXPECT_EQ(vectors.lengths()[0], 2);
+ EXPECT_EQ(vectors.lengths()[1], 0);
+ EXPECT_EQ(vectors.lengths()[2], 1);
+ EXPECT_EQ(vectors[0].size(), 2);
+ EXPECT_EQ(vectors[0].typed<std::string>()[0], "hello");
+ EXPECT_EQ(vectors[0].typed<std::string>()[1], "world");
+ EXPECT_EQ(vectors[2].typed<std::string>()[0], "world");
+}
+
+TEST(generic_vector_array, AsArraySpan)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 3};
+ int value = 3;
+ vectors.append(0, &value);
+ vectors.append(0, &value);
+ value = 5;
+ vectors.append(2, &value);
+ vectors.append(2, &value);
+ vectors.append(2, &value);
+
+ GVArraySpan span = vectors;
+ EXPECT_EQ(span.type(), CPPType::get<int32_t>());
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_EQ(span[0].size(), 2);
+ EXPECT_EQ(span[1].size(), 0);
+ EXPECT_EQ(span[2].size(), 3);
+ EXPECT_EQ(span[0].typed<int>()[1], 3);
+ EXPECT_EQ(span[2].typed<int>()[0], 5);
+}
+
+TEST(generic_vector_array, TypedRef)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 4};
+ GVectorArrayRef<int> ref = vectors.typed<int>();
+ ref.append(0, 2);
+ ref.append(0, 6);
+ ref.append(0, 7);
+ ref.append(2, 1);
+ ref.append(2, 1);
+ ref.append(3, 5);
+ ref.append(3, 6);
+
+ EXPECT_EQ(ref[0].size(), 3);
+ EXPECT_EQ(vectors[0].size(), 3);
+ EXPECT_EQ(ref[0][0], 2);
+ EXPECT_EQ(ref[0][1], 6);
+ EXPECT_EQ(ref[0][2], 7);
+ EXPECT_EQ(ref[1].size(), 0);
+ EXPECT_EQ(ref[2][0], 1);
+ EXPECT_EQ(ref[2][1], 1);
+ EXPECT_EQ(ref[3][0], 5);
+ EXPECT_EQ(ref[3][1], 6);
+}
+
+TEST(generic_vector_array, Extend)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 3};
+ GVectorArrayRef<int> ref = vectors;
+
+ ref.extend(1, {5, 6, 7});
+ ref.extend(0, {3});
+
+ EXPECT_EQ(vectors[0].size(), 1);
+ EXPECT_EQ(vectors[1].size(), 3);
+ EXPECT_EQ(vectors[2].size(), 0);
+ EXPECT_EQ(ref[1][0], 5);
+ EXPECT_EQ(ref[1][1], 6);
+ EXPECT_EQ(ref[1][2], 7);
+ EXPECT_EQ(ref[0][0], 3);
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_multi_function_network_test.cc b/source/blender/functions/tests/FN_multi_function_network_test.cc
new file mode 100644
index 00000000000..f226e0eac2e
--- /dev/null
+++ b/source/blender/functions/tests/FN_multi_function_network_test.cc
@@ -0,0 +1,255 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_multi_function_builder.hh"
+#include "FN_multi_function_network.hh"
+#include "FN_multi_function_network_evaluation.hh"
+
+namespace blender::fn::tests {
+namespace {
+
+TEST(multi_function_network, Test1)
+{
+ CustomMF_SI_SO<int, int> add_10_fn("add 10", [](int value) { return value + 10; });
+ CustomMF_SI_SI_SO<int, int, int> multiply_fn("multiply", [](int a, int b) { return a * b; });
+
+ MFNetwork network;
+
+ MFNode &node1 = network.add_function(add_10_fn);
+ MFNode &node2 = network.add_function(multiply_fn);
+ MFOutputSocket &input_socket = network.add_input("Input", MFDataType::ForSingle<int>());
+ MFInputSocket &output_socket = network.add_output("Output", MFDataType::ForSingle<int>());
+ network.add_link(node1.output(0), node2.input(0));
+ network.add_link(node1.output(0), node2.input(1));
+ network.add_link(node2.output(0), output_socket);
+ network.add_link(input_socket, node1.input(0));
+
+ MFNetworkEvaluator network_fn{{&input_socket}, {&output_socket}};
+
+ {
+ Array<int> values = {4, 6, 1, 2, 0};
+ Array<int> results(values.size(), 0);
+
+ MFParamsBuilder params(network_fn, values.size());
+ params.add_readonly_single_input(values.as_span());
+ params.add_uninitialized_single_output(results.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({0, 2, 3, 4}, params, context);
+
+ EXPECT_EQ(results[0], 14 * 14);
+ EXPECT_EQ(results[1], 0);
+ EXPECT_EQ(results[2], 11 * 11);
+ EXPECT_EQ(results[3], 12 * 12);
+ EXPECT_EQ(results[4], 10 * 10);
+ }
+ {
+ int value = 3;
+ Array<int> results(5, 0);
+
+ MFParamsBuilder params(network_fn, results.size());
+ params.add_readonly_single_input(&value);
+ params.add_uninitialized_single_output(results.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({1, 2, 4}, params, context);
+
+ EXPECT_EQ(results[0], 0);
+ EXPECT_EQ(results[1], 13 * 13);
+ EXPECT_EQ(results[2], 13 * 13);
+ EXPECT_EQ(results[3], 0);
+ EXPECT_EQ(results[4], 13 * 13);
+ }
+}
+
+class ConcatVectorsFunction : public MultiFunction {
+ public:
+ ConcatVectorsFunction()
+ {
+ MFSignatureBuilder signature = this->get_builder("Concat Vectors");
+ signature.vector_mutable<int>("A");
+ signature.vector_input<int>("B");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ GVectorArrayRef<int> a = params.vector_mutable<int>(0);
+ VArraySpan<int> b = params.readonly_vector_input<int>(1);
+
+ for (int64_t i : mask) {
+ a.extend(i, b[i]);
+ }
+ }
+};
+
+class AppendFunction : public MultiFunction {
+ public:
+ AppendFunction()
+ {
+ MFSignatureBuilder signature = this->get_builder("Append");
+ signature.vector_mutable<int>("Vector");
+ signature.single_input<int>("Value");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ GVectorArrayRef<int> vectors = params.vector_mutable<int>(0);
+ VSpan<int> values = params.readonly_single_input<int>(1);
+
+ for (int64_t i : mask) {
+ vectors.append(i, values[i]);
+ }
+ }
+};
+
+class SumVectorFunction : public MultiFunction {
+ public:
+ SumVectorFunction()
+ {
+ MFSignatureBuilder signature = this->get_builder("Sum Vector");
+ signature.vector_input<int>("Vector");
+ signature.single_output<int>("Sum");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VArraySpan<int> vectors = params.readonly_vector_input<int>(0);
+ MutableSpan<int> sums = params.uninitialized_single_output<int>(1);
+
+ for (int64_t i : mask) {
+ int sum = 0;
+ VSpan<int> vector = vectors[i];
+ for (int j = 0; j < vector.size(); j++) {
+ sum += vector[j];
+ }
+ sums[i] = sum;
+ }
+ }
+};
+
+class CreateRangeFunction : public MultiFunction {
+ public:
+ CreateRangeFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Create Range");
+ builder.single_input<int>("Size");
+ builder.vector_output<int>("Range");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<int> sizes = params.readonly_single_input<int>(0, "Size");
+ GVectorArrayRef<int> ranges = params.vector_output<int>(1, "Range");
+
+ for (int64_t i : mask) {
+ int size = sizes[i];
+ for (int j : IndexRange(size)) {
+ ranges.append(i, j);
+ }
+ }
+ }
+};
+
+TEST(multi_function_network, Test2)
+{
+ CustomMF_SI_SO<int, int> add_3_fn("add 3", [](int value) { return value + 3; });
+
+ ConcatVectorsFunction concat_vectors_fn;
+ AppendFunction append_fn;
+ SumVectorFunction sum_fn;
+ CreateRangeFunction create_range_fn;
+
+ MFNetwork network;
+
+ MFOutputSocket &input1 = network.add_input("Input 1", MFDataType::ForVector<int>());
+ MFOutputSocket &input2 = network.add_input("Input 2", MFDataType::ForSingle<int>());
+ MFInputSocket &output1 = network.add_output("Output 1", MFDataType::ForVector<int>());
+ MFInputSocket &output2 = network.add_output("Output 2", MFDataType::ForSingle<int>());
+
+ MFNode &node1 = network.add_function(add_3_fn);
+ MFNode &node2 = network.add_function(create_range_fn);
+ MFNode &node3 = network.add_function(concat_vectors_fn);
+ MFNode &node4 = network.add_function(sum_fn);
+ MFNode &node5 = network.add_function(append_fn);
+ MFNode &node6 = network.add_function(sum_fn);
+
+ network.add_link(input2, node1.input(0));
+ network.add_link(node1.output(0), node2.input(0));
+ network.add_link(node2.output(0), node3.input(1));
+ network.add_link(input1, node3.input(0));
+ network.add_link(input1, node4.input(0));
+ network.add_link(node4.output(0), node5.input(1));
+ network.add_link(node3.output(0), node5.input(0));
+ network.add_link(node5.output(0), node6.input(0));
+ network.add_link(node3.output(0), output1);
+ network.add_link(node6.output(0), output2);
+
+ // std::cout << network.to_dot() << "\n\n";
+
+ MFNetworkEvaluator network_fn{{&input1, &input2}, {&output1, &output2}};
+
+ {
+ Array<int> input_value_1 = {3, 6};
+ int input_value_2 = 4;
+
+ GVectorArray output_value_1(CPPType::get<int32_t>(), 5);
+ Array<int> output_value_2(5, -1);
+
+ MFParamsBuilder params(network_fn, 5);
+ params.add_readonly_vector_input(GVArraySpan(input_value_1.as_span(), 5));
+ params.add_readonly_single_input(&input_value_2);
+ params.add_vector_output(output_value_1);
+ params.add_uninitialized_single_output(output_value_2.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({1, 2, 4}, params, context);
+
+ EXPECT_EQ(output_value_1[0].size(), 0);
+ EXPECT_EQ(output_value_1[1].size(), 9);
+ EXPECT_EQ(output_value_1[2].size(), 9);
+ EXPECT_EQ(output_value_1[3].size(), 0);
+ EXPECT_EQ(output_value_1[4].size(), 9);
+
+ EXPECT_EQ(output_value_2[0], -1);
+ EXPECT_EQ(output_value_2[1], 39);
+ EXPECT_EQ(output_value_2[2], 39);
+ EXPECT_EQ(output_value_2[3], -1);
+ EXPECT_EQ(output_value_2[4], 39);
+ }
+ {
+ GVectorArray input_value_1(CPPType::get<int32_t>(), 3);
+ GVectorArrayRef<int> input_value_ref_1 = input_value_1;
+ input_value_ref_1.extend(0, {3, 4, 5});
+ input_value_ref_1.extend(1, {1, 2});
+
+ Array<int> input_value_2 = {4, 2, 3};
+
+ GVectorArray output_value_1(CPPType::get<int32_t>(), 3);
+ Array<int> output_value_2(3, -1);
+
+ MFParamsBuilder params(network_fn, 3);
+ params.add_readonly_vector_input(input_value_1);
+ params.add_readonly_single_input(input_value_2.as_span());
+ params.add_vector_output(output_value_1);
+ params.add_uninitialized_single_output(output_value_2.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({0, 1, 2}, params, context);
+
+ EXPECT_EQ(output_value_1[0].size(), 10);
+ EXPECT_EQ(output_value_1[1].size(), 7);
+ EXPECT_EQ(output_value_1[2].size(), 6);
+
+ EXPECT_EQ(output_value_2[0], 45);
+ EXPECT_EQ(output_value_2[1], 16);
+ EXPECT_EQ(output_value_2[2], 15);
+ }
+}
+
+} // namespace
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_multi_function_test.cc b/source/blender/functions/tests/FN_multi_function_test.cc
new file mode 100644
index 00000000000..cc023bce597
--- /dev/null
+++ b/source/blender/functions/tests/FN_multi_function_test.cc
@@ -0,0 +1,387 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_multi_function.hh"
+#include "FN_multi_function_builder.hh"
+
+namespace blender::fn::tests {
+namespace {
+
+class AddFunction : public MultiFunction {
+ public:
+ AddFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Add");
+ builder.single_input<int>("A");
+ builder.single_input<int>("B");
+ builder.single_output<int>("Result");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<int> a = params.readonly_single_input<int>(0, "A");
+ VSpan<int> b = params.readonly_single_input<int>(1, "B");
+ MutableSpan<int> result = params.uninitialized_single_output<int>(2, "Result");
+
+ for (int64_t i : mask) {
+ result[i] = a[i] + b[i];
+ }
+ }
+};
+
+TEST(multi_function, AddFunction)
+{
+ AddFunction fn;
+
+ Array<int> input1 = {4, 5, 6};
+ Array<int> input2 = {10, 20, 30};
+ Array<int> output(3, -1);
+
+ MFParamsBuilder params(fn, 3);
+ params.add_readonly_single_input(input1.as_span());
+ params.add_readonly_single_input(input2.as_span());
+ params.add_uninitialized_single_output(output.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 2}, params, context);
+
+ EXPECT_EQ(output[0], 14);
+ EXPECT_EQ(output[1], -1);
+ EXPECT_EQ(output[2], 36);
+}
+
+class AddPrefixFunction : public MultiFunction {
+ public:
+ AddPrefixFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Add Prefix");
+ builder.single_input<std::string>("Prefix");
+ builder.single_mutable<std::string>("Strings");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<std::string> prefixes = params.readonly_single_input<std::string>(0, "Prefix");
+ MutableSpan<std::string> strings = params.single_mutable<std::string>(1, "Strings");
+
+ for (int64_t i : mask) {
+ strings[i] = prefixes[i] + strings[i];
+ }
+ }
+};
+
+TEST(multi_function, AddPrefixFunction)
+{
+ AddPrefixFunction fn;
+
+ Array<std::string> strings = {
+ "Hello",
+ "World",
+ "This is a test",
+ "Another much longer string to trigger an allocation",
+ };
+
+ std::string prefix = "AB";
+
+ MFParamsBuilder params(fn, strings.size());
+ params.add_readonly_single_input(&prefix);
+ params.add_single_mutable(strings.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 2, 3}, params, context);
+
+ EXPECT_EQ(strings[0], "ABHello");
+ EXPECT_EQ(strings[1], "World");
+ EXPECT_EQ(strings[2], "ABThis is a test");
+ EXPECT_EQ(strings[3], "ABAnother much longer string to trigger an allocation");
+}
+
+class CreateRangeFunction : public MultiFunction {
+ public:
+ CreateRangeFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Create Range");
+ builder.single_input<uint>("Size");
+ builder.vector_output<uint>("Range");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<uint> sizes = params.readonly_single_input<uint>(0, "Size");
+ GVectorArrayRef<uint> ranges = params.vector_output<uint>(1, "Range");
+
+ for (int64_t i : mask) {
+ uint size = sizes[i];
+ for (uint j : IndexRange(size)) {
+ ranges.append(i, j);
+ }
+ }
+ }
+};
+
+TEST(multi_function, CreateRangeFunction)
+{
+ CreateRangeFunction fn;
+
+ GVectorArray ranges(CPPType::get<uint>(), 5);
+ GVectorArrayRef<uint> ranges_ref(ranges);
+ Array<uint> sizes = {3, 0, 6, 1, 4};
+
+ MFParamsBuilder params(fn, ranges.size());
+ params.add_readonly_single_input(sizes.as_span());
+ params.add_vector_output(ranges);
+
+ MFContextBuilder context;
+
+ fn.call({0, 1, 2, 3}, params, context);
+
+ EXPECT_EQ(ranges_ref[0].size(), 3);
+ EXPECT_EQ(ranges_ref[1].size(), 0);
+ EXPECT_EQ(ranges_ref[2].size(), 6);
+ EXPECT_EQ(ranges_ref[3].size(), 1);
+ EXPECT_EQ(ranges_ref[4].size(), 0);
+
+ EXPECT_EQ(ranges_ref[0][0], 0);
+ EXPECT_EQ(ranges_ref[0][1], 1);
+ EXPECT_EQ(ranges_ref[0][2], 2);
+ EXPECT_EQ(ranges_ref[2][0], 0);
+ EXPECT_EQ(ranges_ref[2][1], 1);
+}
+
+class GenericAppendFunction : public MultiFunction {
+ public:
+ GenericAppendFunction(const CPPType &type)
+ {
+ MFSignatureBuilder builder = this->get_builder("Append");
+ builder.vector_mutable("Vector", type);
+ builder.single_input("Value", type);
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ GVectorArray &vectors = params.vector_mutable(0, "Vector");
+ GVSpan values = params.readonly_single_input(1, "Value");
+
+ for (int64_t i : mask) {
+ vectors.append(i, values[i]);
+ }
+ }
+};
+
+TEST(multi_function, GenericAppendFunction)
+{
+ GenericAppendFunction fn(CPPType::get<int32_t>());
+
+ GVectorArray vectors(CPPType::get<int32_t>(), 4);
+ GVectorArrayRef<int> vectors_ref(vectors);
+ vectors_ref.append(0, 1);
+ vectors_ref.append(0, 2);
+ vectors_ref.append(2, 6);
+ Array<int> values = {5, 7, 3, 1};
+
+ MFParamsBuilder params(fn, vectors.size());
+ params.add_vector_mutable(vectors);
+ params.add_readonly_single_input(values.as_span());
+
+ MFContextBuilder context;
+
+ fn.call(IndexRange(vectors.size()), params, context);
+
+ EXPECT_EQ(vectors_ref[0].size(), 3);
+ EXPECT_EQ(vectors_ref[1].size(), 1);
+ EXPECT_EQ(vectors_ref[2].size(), 2);
+ EXPECT_EQ(vectors_ref[3].size(), 1);
+
+ EXPECT_EQ(vectors_ref[0][0], 1);
+ EXPECT_EQ(vectors_ref[0][1], 2);
+ EXPECT_EQ(vectors_ref[0][2], 5);
+ EXPECT_EQ(vectors_ref[1][0], 7);
+ EXPECT_EQ(vectors_ref[2][0], 6);
+ EXPECT_EQ(vectors_ref[2][1], 3);
+ EXPECT_EQ(vectors_ref[3][0], 1);
+}
+
+TEST(multi_function, CustomMF_SI_SO)
+{
+ CustomMF_SI_SO<std::string, uint> fn("strlen",
+ [](const std::string &str) { return str.size(); });
+
+ Array<std::string> strings = {"hello", "world", "test", "another test"};
+ Array<uint> sizes(strings.size(), 0);
+
+ MFParamsBuilder params(fn, strings.size());
+ params.add_readonly_single_input(strings.as_span());
+ params.add_uninitialized_single_output(sizes.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call(IndexRange(strings.size()), params, context);
+
+ EXPECT_EQ(sizes[0], 5);
+ EXPECT_EQ(sizes[1], 5);
+ EXPECT_EQ(sizes[2], 4);
+ EXPECT_EQ(sizes[3], 12);
+}
+
+TEST(multi_function, CustomMF_SI_SI_SO)
+{
+ CustomMF_SI_SI_SO<int, int, int> fn("mul", [](int a, int b) { return a * b; });
+
+ Array<int> values_a = {4, 6, 8, 9};
+ int value_b = 10;
+ Array<int> outputs(values_a.size(), -1);
+
+ MFParamsBuilder params(fn, values_a.size());
+ params.add_readonly_single_input(values_a.as_span());
+ params.add_readonly_single_input(&value_b);
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 1, 3}, params, context);
+
+ EXPECT_EQ(outputs[0], 40);
+ EXPECT_EQ(outputs[1], 60);
+ EXPECT_EQ(outputs[2], -1);
+ EXPECT_EQ(outputs[3], 90);
+}
+
+TEST(multi_function, CustomMF_SI_SI_SI_SO)
+{
+ CustomMF_SI_SI_SI_SO<int, std::string, bool, uint> fn{
+ "custom",
+ [](int a, const std::string &b, bool c) { return (uint)((uint)a + b.size() + (uint)c); }};
+
+ Array<int> values_a = {5, 7, 3, 8};
+ Array<std::string> values_b = {"hello", "world", "another", "test"};
+ Array<bool> values_c = {true, false, false, true};
+ Array<uint> outputs(values_a.size(), 0);
+
+ MFParamsBuilder params(fn, values_a.size());
+ params.add_readonly_single_input(values_a.as_span());
+ params.add_readonly_single_input(values_b.as_span());
+ params.add_readonly_single_input(values_c.as_span());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({1, 2, 3}, params, context);
+
+ EXPECT_EQ(outputs[0], 0);
+ EXPECT_EQ(outputs[1], 12);
+ EXPECT_EQ(outputs[2], 10);
+ EXPECT_EQ(outputs[3], 13);
+}
+
+TEST(multi_function, CustomMF_SM)
+{
+ CustomMF_SM<std::string> fn("AddSuffix", [](std::string &value) { value += " test"; });
+
+ Array<std::string> values = {"a", "b", "c", "d", "e"};
+
+ MFParamsBuilder params(fn, values.size());
+ params.add_single_mutable(values.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({1, 2, 3}, params, context);
+
+ EXPECT_EQ(values[0], "a");
+ EXPECT_EQ(values[1], "b test");
+ EXPECT_EQ(values[2], "c test");
+ EXPECT_EQ(values[3], "d test");
+ EXPECT_EQ(values[4], "e");
+}
+
+TEST(multi_function, CustomMF_Constant)
+{
+ CustomMF_Constant<int> fn{42};
+
+ Array<int> outputs(4, 0);
+
+ MFParamsBuilder params(fn, outputs.size());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 2, 3}, params, context);
+
+ EXPECT_EQ(outputs[0], 42);
+ EXPECT_EQ(outputs[1], 0);
+ EXPECT_EQ(outputs[2], 42);
+ EXPECT_EQ(outputs[3], 42);
+}
+
+TEST(multi_function, CustomMF_GenericConstant)
+{
+ int value = 42;
+ CustomMF_GenericConstant fn{CPPType::get<int32_t>(), (const void *)&value};
+ EXPECT_EQ(fn.param_name(0), "42");
+
+ Array<int> outputs(4, 0);
+
+ MFParamsBuilder params(fn, outputs.size());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 1, 2}, params, context);
+
+ EXPECT_EQ(outputs[0], 42);
+ EXPECT_EQ(outputs[1], 42);
+ EXPECT_EQ(outputs[2], 42);
+ EXPECT_EQ(outputs[3], 0);
+}
+
+TEST(multi_function, CustomMF_GenericConstantArray)
+{
+ std::array<int, 4> values = {3, 4, 5, 6};
+ CustomMF_GenericConstantArray fn{GSpan(Span(values))};
+ EXPECT_EQ(fn.param_name(0), "[3, 4, 5, 6, ]");
+
+ GVectorArray g_vector_array{CPPType::get<int32_t>(), 4};
+ GVectorArrayRef<int> vector_array = g_vector_array;
+
+ MFParamsBuilder params(fn, g_vector_array.size());
+ params.add_vector_output(g_vector_array);
+
+ MFContextBuilder context;
+
+ fn.call({1, 2, 3}, params, context);
+
+ EXPECT_EQ(vector_array[0].size(), 0);
+ EXPECT_EQ(vector_array[1].size(), 4);
+ EXPECT_EQ(vector_array[2].size(), 4);
+ EXPECT_EQ(vector_array[3].size(), 4);
+ for (int i = 1; i < 4; i++) {
+ EXPECT_EQ(vector_array[i][0], 3);
+ EXPECT_EQ(vector_array[i][1], 4);
+ EXPECT_EQ(vector_array[i][2], 5);
+ EXPECT_EQ(vector_array[i][3], 6);
+ }
+}
+
+TEST(multi_function, CustomMF_Convert)
+{
+ CustomMF_Convert<float, int> fn;
+
+ Array<float> inputs = {5.4f, 7.1f, 9.0f};
+ Array<int> outputs(inputs.size(), 0);
+
+ MFParamsBuilder params(fn, inputs.size());
+ params.add_readonly_single_input(inputs.as_span());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+ fn.call({0, 2}, params, context);
+
+ EXPECT_EQ(outputs[0], 5);
+ EXPECT_EQ(outputs[1], 0);
+ EXPECT_EQ(outputs[2], 9);
+}
+
+} // namespace
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_spans_test.cc b/source/blender/functions/tests/FN_spans_test.cc
new file mode 100644
index 00000000000..fbcf1fda71e
--- /dev/null
+++ b/source/blender/functions/tests/FN_spans_test.cc
@@ -0,0 +1,222 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_spans.hh"
+
+namespace blender::fn::tests {
+
+TEST(generic_span, TypeConstructor)
+{
+ GSpan span(CPPType::get<float>());
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_EQ(span.typed<float>().size(), 0);
+ EXPECT_TRUE(span.is_empty());
+}
+
+TEST(generic_span, BufferAndSizeConstructor)
+{
+ int values[4] = {6, 7, 3, 2};
+ void *buffer = (void *)values;
+ GSpan span(CPPType::get<int32_t>(), buffer, 4);
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span.typed<int>().size(), 4);
+ EXPECT_EQ(span[0], &values[0]);
+ EXPECT_EQ(span[1], &values[1]);
+ EXPECT_EQ(span[2], &values[2]);
+ EXPECT_EQ(span[3], &values[3]);
+}
+
+TEST(generic_mutable_span, TypeConstructor)
+{
+ GMutableSpan span(CPPType::get<int32_t>());
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+}
+
+TEST(generic_mutable_span, BufferAndSizeConstructor)
+{
+ int values[4] = {4, 7, 3, 5};
+ void *buffer = (void *)values;
+ GMutableSpan span(CPPType::get<int32_t>(), buffer, 4);
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span.typed<int>().size(), 4);
+ EXPECT_EQ(values[2], 3);
+ *(int *)span[2] = 10;
+ EXPECT_EQ(values[2], 10);
+ span.typed<int>()[2] = 20;
+ EXPECT_EQ(values[2], 20);
+}
+
+TEST(virtual_span, EmptyConstructor)
+{
+ VSpan<int> span;
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_TRUE(span.is_full_array());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(virtual_span, SpanConstructor)
+{
+ std::array<int, 5> values = {7, 3, 8, 6, 4};
+ Span<int> span = values;
+ VSpan<int> virtual_span = span;
+ EXPECT_EQ(virtual_span.size(), 5);
+ EXPECT_FALSE(virtual_span.is_empty());
+ EXPECT_EQ(virtual_span[0], 7);
+ EXPECT_EQ(virtual_span[2], 8);
+ EXPECT_EQ(virtual_span[3], 6);
+ EXPECT_FALSE(virtual_span.is_single_element());
+ EXPECT_TRUE(virtual_span.is_full_array());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 5);
+}
+
+TEST(virtual_span, PointerSpanConstructor)
+{
+ int x0 = 3;
+ int x1 = 6;
+ int x2 = 7;
+ std::array<const int *, 3> pointers = {&x0, &x2, &x1};
+ VSpan<int> span = Span<const int *>(pointers);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], 3);
+ EXPECT_EQ(span[1], 7);
+ EXPECT_EQ(span[2], 6);
+ EXPECT_EQ(&span[1], &x2);
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_FALSE(span.is_full_array());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], &x0);
+ EXPECT_EQ(converted[1], &x2);
+ EXPECT_EQ(converted[2], &x1);
+}
+
+TEST(virtual_span, SingleConstructor)
+{
+ int value = 5;
+ VSpan<int> span = VSpan<int>::FromSingle(&value, 3);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], 5);
+ EXPECT_EQ(span[1], 5);
+ EXPECT_EQ(span[2], 5);
+ EXPECT_EQ(&span[0], &value);
+ EXPECT_EQ(&span[1], &value);
+ EXPECT_EQ(&span[2], &value);
+ EXPECT_TRUE(span.is_single_element());
+ EXPECT_FALSE(span.is_full_array());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], &value);
+ EXPECT_EQ(converted[1], &value);
+ EXPECT_EQ(converted[2], &value);
+}
+
+TEST(generic_virtual_span, TypeConstructor)
+{
+ GVSpan span(CPPType::get<int32_t>());
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_TRUE(span.is_full_array());
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(generic_virtual_span, GenericSpanConstructor)
+{
+ int values[4] = {3, 4, 5, 6};
+ GVSpan span{GSpan(CPPType::get<int32_t>(), values, 4)};
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], &values[0]);
+ EXPECT_EQ(span[1], &values[1]);
+ EXPECT_EQ(span[2], &values[2]);
+ EXPECT_EQ(span[3], &values[3]);
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_TRUE(span.is_full_array());
+
+ int materialized[4] = {0};
+ span.materialize_to_uninitialized(materialized);
+ EXPECT_EQ(materialized[0], 3);
+ EXPECT_EQ(materialized[1], 4);
+ EXPECT_EQ(materialized[2], 5);
+ EXPECT_EQ(materialized[3], 6);
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 4);
+ EXPECT_EQ(converted[0], 3);
+ EXPECT_EQ(converted[1], 4);
+ EXPECT_EQ(converted[2], 5);
+ EXPECT_EQ(converted[3], 6);
+}
+
+TEST(generic_virtual_span, SpanConstructor)
+{
+ std::array<int, 3> values = {6, 7, 8};
+ GVSpan span{Span<int>(values)};
+ EXPECT_EQ(span.type(), CPPType::get<int32_t>());
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_EQ(span[0], &values[0]);
+ EXPECT_EQ(span[1], &values[1]);
+ EXPECT_EQ(span[2], &values[2]);
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_TRUE(span.is_full_array());
+
+ int materialized[3] = {0};
+ span.materialize_to_uninitialized(materialized);
+ EXPECT_EQ(materialized[0], 6);
+ EXPECT_EQ(materialized[1], 7);
+ EXPECT_EQ(materialized[2], 8);
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], 6);
+ EXPECT_EQ(converted[1], 7);
+ EXPECT_EQ(converted[2], 8);
+}
+
+TEST(generic_virtual_span, SingleConstructor)
+{
+ int value = 5;
+ GVSpan span = GVSpan::FromSingle(CPPType::get<int32_t>(), &value, 3);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], &value);
+ EXPECT_EQ(span[1], &value);
+ EXPECT_EQ(span[2], &value);
+ EXPECT_TRUE(span.is_single_element());
+ EXPECT_EQ(span.as_single_element(), &value);
+ EXPECT_FALSE(span.is_full_array());
+
+ int materialized[3] = {0};
+ span.materialize_to_uninitialized({1, 2}, materialized);
+ EXPECT_EQ(materialized[0], 0);
+ EXPECT_EQ(materialized[1], 5);
+ EXPECT_EQ(materialized[2], 5);
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], 5);
+ EXPECT_EQ(converted[1], 5);
+ EXPECT_EQ(converted[2], 5);
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt
index 92aacc74190..497cb4a10a5 100644
--- a/source/blender/gpencil_modifiers/CMakeLists.txt
+++ b/source/blender/gpencil_modifiers/CMakeLists.txt
@@ -42,7 +42,6 @@ set(INC_SYS
)
set(SRC
- intern/MOD_gpencil_util.h
intern/MOD_gpencil_ui_common.c
intern/MOD_gpencil_util.c
@@ -65,8 +64,9 @@ set(SRC
intern/MOD_gpenciltime.c
intern/MOD_gpenciltint.c
- intern/MOD_gpencil_ui_common.h
MOD_gpencil_modifiertypes.h
+ intern/MOD_gpencil_ui_common.h
+ intern/MOD_gpencil_util.h
)
set(LIB
diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
index a7a4333d82e..3f167ac6785 100644
--- a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
+++ b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
@@ -18,8 +18,7 @@
* \ingroup modifiers
*/
-#ifndef __MOD_GPENCIL_MODIFIERTYPES_H__
-#define __MOD_GPENCIL_MODIFIERTYPES_H__
+#pragma once
#include "BKE_gpencil_modifier.h"
@@ -47,5 +46,3 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_Texture;
/* MOD_gpencil_util.c */
void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]);
-
-#endif /* __MOD_GPENCIL_MODIFIERTYPES_H__ */
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.c
index c15bef1f748..a9afbc4b6ae 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.c
@@ -34,7 +34,6 @@
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
#include "ED_object.h"
@@ -50,23 +49,12 @@
#include "MOD_gpencil_ui_common.h" /* Self include */
-static Object *get_gpencilmodifier_object(const bContext *C)
-{
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
- if (sbuts != NULL && (sbuts->pinid != NULL) && GS(sbuts->pinid->name) == ID_OB) {
- return (Object *)sbuts->pinid;
- }
- else {
- return CTX_data_active_object(C);
- }
-}
-
/**
* Poll function so these modifier panels only show for grease pencil objects.
*/
static bool gpencil_modifier_ui_poll(const bContext *C, PanelType *UNUSED(pt))
{
- Object *ob = get_gpencilmodifier_object(C);
+ Object *ob = ED_object_active_context(C);
return (ob != NULL) && (ob->type == OB_GPENCIL);
}
@@ -80,7 +68,7 @@ static bool gpencil_modifier_ui_poll(const bContext *C, PanelType *UNUSED(pt))
*/
static void gpencil_modifier_reorder(bContext *C, Panel *panel, int new_index)
{
- Object *ob = get_gpencilmodifier_object(C);
+ Object *ob = ED_object_active_context(C);
GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, panel->runtime.list_index);
PointerRNA props_ptr;
@@ -94,7 +82,7 @@ static void gpencil_modifier_reorder(bContext *C, Panel *panel, int new_index)
static short get_gpencil_modifier_expand_flag(const bContext *C, Panel *panel)
{
- Object *ob = get_gpencilmodifier_object(C);
+ Object *ob = ED_object_active_context(C);
GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, panel->runtime.list_index);
return md->ui_expand_flag;
return 0;
@@ -102,7 +90,7 @@ static short get_gpencil_modifier_expand_flag(const bContext *C, Panel *panel)
static void set_gpencil_modifier_expand_flag(const bContext *C, Panel *panel, short expand_flag)
{
- Object *ob = get_gpencilmodifier_object(C);
+ Object *ob = ED_object_active_context(C);
GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, panel->runtime.list_index);
md->ui_expand_flag = expand_flag;
}
@@ -245,7 +233,7 @@ void gpencil_modifier_panel_get_property_pointers(const bContext *C,
PointerRNA *r_ob_ptr,
PointerRNA *r_md_ptr)
{
- Object *ob = get_gpencilmodifier_object(C);
+ Object *ob = ED_object_active_context(C);
GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, panel->runtime.list_index);
RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, r_md_ptr);
@@ -269,7 +257,7 @@ static void gpencil_modifier_ops_extra_draw(bContext *C, uiLayout *layout, void
const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
PointerRNA ptr;
- Object *ob = get_gpencilmodifier_object(C);
+ Object *ob = ED_object_active_context(C);
RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, &ptr);
uiLayoutSetContextPointer(layout, "modifier", &ptr);
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
@@ -328,7 +316,7 @@ static void gpencil_modifier_panel_header(const bContext *C, Panel *panel)
uiLayout *row, *sub;
uiLayout *layout = panel->layout;
- Object *ob = get_gpencilmodifier_object(C);
+ Object *ob = ED_object_active_context(C);
GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, panel->runtime.list_index);
PointerRNA ptr;
RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, &ptr);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.h b/source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.h
index 9c6edb51d63..c85e939b13f 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.h
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_ui_common.h
@@ -18,8 +18,7 @@
* \ingroup modifiers
*/
-#ifndef __MOD_UI_COMMON__GPENCIL_H__
-#define __MOD_UI_COMMON__GPENCIL_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -62,5 +61,3 @@ struct PanelType *gpencil_modifier_subpanel_register(struct ARegionType *region_
#ifdef __cplusplus
}
#endif
-
-#endif /* __MOD_UI_COMMON__GPENCIL_H__ */
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h
index 5cc3750639b..e5a6d9e6a8f 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h
@@ -21,8 +21,7 @@
* \ingroup modifiers
*/
-#ifndef __MOD_GPENCIL_UTIL_H__
-#define __MOD_GPENCIL_UTIL_H__
+#pragma once
struct GHash;
struct MDeformVert;
@@ -46,5 +45,3 @@ bool is_stroke_affected_by_modifier(struct Object *ob,
const bool inv4);
float get_modifier_point_weight(struct MDeformVert *dvert, bool inverse, int def_nr);
-
-#endif /* __MOD_GPENCIL_UTIL_H__ */
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
index 54ed2ffafe1..56d94611b5d 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
@@ -119,7 +119,6 @@ static void gpf_clear_all_strokes(bGPDframe *gpf)
/* Reduce the number of points in the stroke
*
* Note: This won't be called if all points are present/removed
- * TODO: Allow blending of growing/shrinking tip (e.g. for more gradual transitions)
*/
static void reduce_stroke_points(bGPDstroke *gps,
const int num_points,
@@ -132,7 +131,6 @@ static void reduce_stroke_points(bGPDstroke *gps,
}
/* Which end should points be removed from */
- // TODO: free stroke weights
switch (transition) {
case GP_BUILD_TRANSITION_GROW: /* Show in forward order =
* Remove ungrown-points from end of stroke. */
@@ -279,7 +277,6 @@ static void build_sequential(BuildGpencilModifierData *mmd, bGPDframe *gpf, floa
}
else {
/* Some proportion of stroke is visible */
- /* XXX: Will the transition settings still be valid now? */
if ((first_visible <= cell->start_idx) && (last_visible >= cell->end_idx)) {
/* Do nothing - whole stroke is visible */
}
@@ -303,8 +300,6 @@ static void build_sequential(BuildGpencilModifierData *mmd, bGPDframe *gpf, floa
/* --------------------------------------------- */
/* Concurrent - Show multiple strokes at once */
-// TODO: Allow random offsets to start times
-// TODO: Allow varying speeds? Scaling of progress?
static void build_concurrent(BuildGpencilModifierData *mmd, bGPDframe *gpf, float fac)
{
bGPDstroke *gps, *gps_next;
@@ -342,8 +337,7 @@ static void build_concurrent(BuildGpencilModifierData *mmd, bGPDframe *gpf, floa
/* Build effect occurs over when fac = 0, to fac = relative_len */
if (fac <= relative_len) {
/* Scale fac to fit relative_len */
- /* FIXME: prevent potential div by zero (e.g. very short stroke vs one very long one) */
- const float scaled_fac = fac / relative_len;
+ const float scaled_fac = fac / MAX2(relative_len, PSEUDOINVERSE_EPSILON);
if (reverse) {
num_points = (int)roundf((1.0f - scaled_fac) * gps->totpoints);
@@ -371,8 +365,7 @@ static void build_concurrent(BuildGpencilModifierData *mmd, bGPDframe *gpf, floa
const float start_fac = 1.0f - relative_len;
if (fac >= start_fac) {
- /* FIXME: prevent potential div by zero (e.g. very short stroke vs one very long one) */
- const float scaled_fac = (fac - start_fac) / relative_len;
+ const float scaled_fac = (fac - start_fac) / MAX2(relative_len, PSEUDOINVERSE_EPSILON);
if (reverse) {
num_points = (int)roundf((1.0f - scaled_fac) * gps->totpoints);
@@ -393,8 +386,6 @@ static void build_concurrent(BuildGpencilModifierData *mmd, bGPDframe *gpf, floa
break;
}
-
- /* TODO... */
}
/* Modify the stroke geometry */
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c
index 03137a5cf23..21a8962b131 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c
@@ -69,7 +69,7 @@ static void initData(GpencilModifierData *md)
gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
index 4761dc878c0..10f775ee340 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
@@ -94,7 +94,7 @@ static void initData(GpencilModifierData *md)
gpmd->falloff_type = eGPHook_Falloff_Smooth;
gpmd->curfalloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curfalloff) {
- BKE_curvemapping_initialize(gpmd->curfalloff);
+ BKE_curvemapping_init(gpmd->curfalloff);
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
index 812bb5628e1..67c26bf2584 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
@@ -79,7 +79,7 @@ static void initData(GpencilModifierData *md)
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
BKE_curvemap_reset(curve->cm, &curve->clipr, CURVE_PRESET_BELL, CURVEMAP_SLOPE_POSITIVE);
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
@@ -327,7 +327,7 @@ static void random_panel_draw(const bContext *C, Panel *panel)
static void mask_panel_draw(const bContext *C, Panel *panel)
{
- gpencil_modifier_masking_panel_draw(C, panel, true, false);
+ gpencil_modifier_masking_panel_draw(C, panel, true, true);
}
static void panelRegister(ARegionType *region_type)
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c
index 9cc3712e8f4..75f929e979e 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c
@@ -105,19 +105,23 @@ static void deformStroke(GpencilModifierData *md,
bGPDspoint *pt = &gps->points[i];
MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL;
- /* verify vertex group */
+ /* Verify vertex group. */
const float weight = get_modifier_point_weight(
dvert, (mmd->flag & GP_OFFSET_INVERT_VGROUP) != 0, def_nr);
if (weight < 0.0f) {
continue;
}
- /* calculate matrix */
+ /* Calculate matrix. */
mul_v3_v3fl(loc, mmd->loc, weight);
mul_v3_v3fl(rot, mmd->rot, weight);
mul_v3_v3fl(scale, mmd->scale, weight);
add_v3_fl(scale, 1.0);
loc_eul_size_to_mat4(mat, loc, rot, scale);
+ /* Apply scale to thickness. */
+ float unit_scale = (scale[0] + scale[1] + scale[2]) / 3.0f;
+ pt->pressure *= unit_scale;
+
mul_m4_v3(mat, &pt->x);
}
/* Calc geometry data. */
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c
index 34142709c18..efa58cc4ae0 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c
@@ -70,7 +70,7 @@ static void initData(GpencilModifierData *md)
gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c
index 8d4556421eb..1e75c5926cd 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c
@@ -83,7 +83,7 @@ static void deformStroke(GpencilModifierData *md,
mmd->material,
mmd->pass_index,
mmd->layer_pass,
- mmd->mode == GP_SIMPLIFY_SAMPLE ? 3 : 4,
+ mmd->mode == GP_SIMPLIFY_SAMPLE ? 2 : 4,
gpl,
gps,
mmd->flag & GP_SIMPLIFY_INVERT_LAYER,
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
index 175a6d81b1b..e3511d9645e 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
@@ -66,7 +66,7 @@ static void initData(GpencilModifierData *md)
gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
@@ -195,7 +195,7 @@ static void panel_draw(const bContext *C, Panel *panel)
row = uiLayoutRow(layout, true);
uiItemR(row, &ptr, "use_edit_position", UI_ITEM_R_TOGGLE, IFACE_("Position"), ICON_NONE);
- uiItemR(row, &ptr, "use_edit_strength", UI_ITEM_R_TOGGLE, IFACE_("Stength"), ICON_NONE);
+ uiItemR(row, &ptr, "use_edit_strength", UI_ITEM_R_TOGGLE, IFACE_("Strength"), ICON_NONE);
uiItemR(row, &ptr, "use_edit_thickness", UI_ITEM_R_TOGGLE, IFACE_("Thickness"), ICON_NONE);
uiItemR(row, &ptr, "use_edit_uv", UI_ITEM_R_TOGGLE, IFACE_("UV"), ICON_NONE);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c
index 4fa47a592ba..68547614776 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c
@@ -65,7 +65,7 @@ static void initData(GpencilModifierData *md)
gpmd->material = NULL;
gpmd->curve_thickness = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_thickness) {
- BKE_curvemapping_initialize(gpmd->curve_thickness);
+ BKE_curvemapping_init(gpmd->curve_thickness);
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
index 49396f56d26..389f3ca1bd2 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
@@ -22,6 +22,7 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "BLI_utildefines.h"
@@ -168,7 +169,7 @@ static int remapTime(struct GpencilModifierData *md,
const int delta = abs(sfra - nfra);
return efra - delta + 1;
}
- else if (cfra + offset > efra) {
+ if (cfra + offset > efra) {
return nfra - efra + sfra - 1;
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
index da7d33839f1..9d10fcbe49b 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
@@ -96,7 +96,7 @@ static void initData(GpencilModifierData *md)
gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 0f7e804de9e..3ea18f72166 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -52,38 +52,37 @@ set(INC_SYS
)
set(SRC
- intern/gpu_attr_binding.c
- intern/gpu_batch.c
+ intern/gpu_attr_binding.cc
+ intern/gpu_batch.cc
intern/gpu_batch_presets.c
intern/gpu_batch_utils.c
intern/gpu_buffers.c
intern/gpu_codegen.c
- intern/gpu_context.cpp
- intern/gpu_debug.c
- intern/gpu_draw.c
- intern/gpu_draw_smoke.c
- intern/gpu_element.c
- intern/gpu_extensions.c
- intern/gpu_framebuffer.c
- intern/gpu_immediate.c
+ intern/gpu_context.cc
+ intern/gpu_debug.cc
+ intern/gpu_element.cc
+ intern/gpu_extensions.cc
+ intern/gpu_framebuffer.cc
+ intern/gpu_immediate.cc
intern/gpu_immediate_util.c
intern/gpu_init_exit.c
intern/gpu_material.c
intern/gpu_material_library.c
- intern/gpu_matrix.c
+ intern/gpu_matrix.cc
intern/gpu_node_graph.c
- intern/gpu_platform.c
+ intern/gpu_platform.cc
intern/gpu_primitive.c
intern/gpu_select.c
intern/gpu_select_pick.c
intern/gpu_select_sample_query.c
- intern/gpu_shader.c
- intern/gpu_shader_interface.c
- intern/gpu_state.c
- intern/gpu_texture.c
- intern/gpu_uniformbuffer.c
- intern/gpu_vertex_buffer.c
- intern/gpu_vertex_format.c
+ intern/gpu_shader.cc
+ intern/gpu_shader_builtin.c
+ intern/gpu_shader_interface.cc
+ intern/gpu_state.cc
+ intern/gpu_texture.cc
+ intern/gpu_uniformbuffer.cc
+ intern/gpu_vertex_buffer.cc
+ intern/gpu_vertex_format.cc
intern/gpu_viewport.c
GPU_attr_binding.h
@@ -94,7 +93,6 @@ set(SRC
GPU_common.h
GPU_context.h
GPU_debug.h
- GPU_draw.h
GPU_element.h
GPU_extensions.h
GPU_framebuffer.h
@@ -171,9 +169,6 @@ data_to_c_simple(shaders/gpu_shader_image_desaturate_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_overlays_merge_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_overlays_stereo_merge_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_image_alpha_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_image_varying_color_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_image_vert.glsl SRC)
@@ -219,6 +214,8 @@ data_to_c_simple(shaders/gpu_shader_text_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_keyframe_diamond_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_keyframe_diamond_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_codegen_lib.glsl SRC)
+
data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC)
data_to_c_simple(shaders/material/gpu_shader_material_add_shader.glsl SRC)
diff --git a/source/blender/gpu/GPU_attr_binding.h b/source/blender/gpu/GPU_attr_binding.h
index 8093e02cab6..e7c3dcbce05 100644
--- a/source/blender/gpu/GPU_attr_binding.h
+++ b/source/blender/gpu/GPU_attr_binding.h
@@ -23,8 +23,7 @@
* GPU vertex attribute binding
*/
-#ifndef __GPU_ATTR_BINDING_H__
-#define __GPU_ATTR_BINDING_H__
+#pragma once
#include "GPU_common.h"
@@ -42,5 +41,3 @@ typedef struct GPUAttrBinding {
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_ATTR_BINDING_H__ */
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 5f55b512695..71a29d0b178 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -24,8 +24,7 @@
* Contains VAOs + VBOs + Shader representing a drawable entity.
*/
-#ifndef __GPU_BATCH_H__
-#define __GPU_BATCH_H__
+#pragma once
#include "GPU_element.h"
#include "GPU_shader.h"
@@ -127,9 +126,8 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
#define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false)
-void GPU_batch_program_set_no_use(GPUBatch *, uint32_t program, const GPUShaderInterface *);
-void GPU_batch_program_set(GPUBatch *, uint32_t program, const GPUShaderInterface *);
-void GPU_batch_program_set_shader(GPUBatch *, GPUShader *shader);
+void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader);
+void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader);
void GPU_batch_program_set_imm_shader(GPUBatch *batch);
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id);
void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
@@ -248,5 +246,3 @@ void gpu_batch_exit(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_BATCH_H__ */
diff --git a/source/blender/gpu/GPU_batch_presets.h b/source/blender/gpu/GPU_batch_presets.h
index eb803333d98..1674cf776db 100644
--- a/source/blender/gpu/GPU_batch_presets.h
+++ b/source/blender/gpu/GPU_batch_presets.h
@@ -24,8 +24,7 @@
* This file contains any additions or modifications specific to Blender.
*/
-#ifndef __GPU_BATCH_PRESETS_H__
-#define __GPU_BATCH_PRESETS_H__
+#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_sys_types.h"
@@ -50,8 +49,8 @@ bool gpu_batch_presets_unregister(struct GPUBatch *preset_batch);
void gpu_batch_presets_reset(void);
void gpu_batch_presets_exit(void);
+void GPU_batch_presets_reset(void);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_BATCH_PRESETS_H__ */
diff --git a/source/blender/gpu/GPU_batch_utils.h b/source/blender/gpu/GPU_batch_utils.h
index 8f85ac59aa5..37dccc4621c 100644
--- a/source/blender/gpu/GPU_batch_utils.h
+++ b/source/blender/gpu/GPU_batch_utils.h
@@ -18,8 +18,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_BATCH_UTILS_H__
-#define __GPU_BATCH_UTILS_H__
+#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_sys_types.h"
@@ -44,5 +43,3 @@ struct GPUBatch *gpu_batch_sphere(int lat_res, int lon_res) ATTR_WARN_UNUSED_RES
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_BATCH_UTILS_H__ */
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 41a29a4d45d..23349728f25 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_BUFFERS_H__
-#define __GPU_BUFFERS_H__
+#pragma once
#include <stddef.h>
@@ -67,7 +66,7 @@ GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading);
void GPU_pbvh_bmesh_buffers_update_free(GPU_PBVH_Buffers *buffers);
void GPU_pbvh_grid_buffers_update_free(GPU_PBVH_Buffers *buffers,
const struct DMFlagMat *grid_flag_mats,
- int *grid_indices);
+ const int *grid_indices);
/* Update mesh buffers without topology changes. Threaded. */
enum {
@@ -121,5 +120,3 @@ bool GPU_pbvh_buffers_has_overlays(GPU_PBVH_Buffers *buffers);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/gpu/GPU_common.h b/source/blender/gpu/GPU_common.h
index dd580ebbdac..8fd1baba2f7 100644
--- a/source/blender/gpu/GPU_common.h
+++ b/source/blender/gpu/GPU_common.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_COMMON_H__
-#define __GPU_COMMON_H__
+#pragma once
#define PROGRAM_NO_OPTI 0
@@ -51,5 +50,3 @@
#else
# define GPU_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__))
#endif
-
-#endif /* __GPU_COMMON_H__ */
diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h
index 9876aa6998c..4f0edaf3ac8 100644
--- a/source/blender/gpu/GPU_context.h
+++ b/source/blender/gpu/GPU_context.h
@@ -23,8 +23,7 @@
* This interface allow GPU to manage VAOs for multiple context and threads.
*/
-#ifndef __GPU_CONTEXT_H__
-#define __GPU_CONTEXT_H__
+#pragma once
#include "GPU_batch.h"
#include "GPU_common.h"
@@ -42,8 +41,14 @@ void GPU_context_discard(GPUContext *);
void GPU_context_active_set(GPUContext *);
GPUContext *GPU_context_active_get(void);
+/* Legacy GPU (Intel HD4000 series) do not support sharing GPU objects between GPU
+ * contexts. EEVEE/Workbench can create different contexts for image/preview rendering, baking or
+ * compiling. When a legacy GPU is detected (`GPU_use_main_context_workaround()`) any worker
+ * threads should use the draw manager opengl context and make sure that they are the only one
+ * using it by locking the main context using these two functions. */
+void GPU_context_main_lock(void);
+void GPU_context_main_unlock(void);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_CONTEXT_H__ */
diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h
index 8928581ee08..be822056678 100644
--- a/source/blender/gpu/GPU_debug.h
+++ b/source/blender/gpu/GPU_debug.h
@@ -21,10 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_DEBUG_H__
-#define __GPU_DEBUG_H__
-
-#include "GPU_glew.h"
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -39,5 +36,3 @@ void GPU_string_marker(const char *str);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_DEBUG_H__ */
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
deleted file mode 100644
index b364bd0ef95..00000000000
--- a/source/blender/gpu/GPU_draw.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup gpu
- */
-
-#ifndef __GPU_DRAW_H__
-#define __GPU_DRAW_H__
-
-#include "BLI_utildefines.h"
-#include "DNA_object_enums.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct FluidModifierData;
-struct ImBuf;
-struct Image;
-struct ImageUser;
-struct Main;
-
-/* OpenGL drawing functions related to shading. */
-
-/* Mipmap settings
- * - these will free textures on changes */
-
-void GPU_set_mipmap(struct Main *bmain, bool mipmap);
-bool GPU_get_mipmap(void);
-void GPU_set_linear_mipmap(bool linear);
-bool GPU_get_linear_mipmap(void);
-void GPU_paint_set_mipmap(struct Main *bmain, bool mipmap);
-
-/* Anisotropic filtering settings
- * - these will free textures on changes */
-void GPU_set_anisotropic(float value);
-float GPU_get_anisotropic(void);
-
-/* Image updates and free
- * - these deal with images bound as opengl textures */
-
-void GPU_paint_update_image(
- struct Image *ima, struct ImageUser *iuser, int x, int y, int w, int h);
-void GPU_create_gl_tex(unsigned int *bind,
- unsigned int *rect,
- float *frect,
- int rectw,
- int recth,
- int textarget,
- bool mipmap,
- bool half_float,
- bool use_srgb,
- struct Image *ima);
-void GPU_create_gl_tex_compressed(unsigned int *bind,
- int textarget,
- struct Image *ima,
- struct ImBuf *ibuf);
-bool GPU_upload_dxt_texture(struct ImBuf *ibuf, bool use_srgb);
-void GPU_free_image(struct Image *ima);
-void GPU_free_images(struct Main *bmain);
-void GPU_free_images_anim(struct Main *bmain);
-void GPU_free_images_old(struct Main *bmain);
-
-/* gpu_draw_smoke.c */
-void GPU_free_smoke(struct FluidModifierData *fmd);
-void GPU_free_smoke_velocity(struct FluidModifierData *fmd);
-void GPU_create_smoke(struct FluidModifierData *fmd, int highres);
-void GPU_create_smoke_coba_field(struct FluidModifierData *fmd);
-void GPU_create_smoke_velocity(struct FluidModifierData *fmd);
-
-/* Delayed free of OpenGL buffers by main thread */
-void GPU_free_unused_buffers(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/source/blender/gpu/GPU_element.h b/source/blender/gpu/GPU_element.h
index 9aef8d6ed73..3d5195b12fc 100644
--- a/source/blender/gpu/GPU_element.h
+++ b/source/blender/gpu/GPU_element.h
@@ -23,8 +23,7 @@
* GPU element list (AKA index buffer)
*/
-#ifndef __GPU_ELEMENT_H__
-#define __GPU_ELEMENT_H__
+#pragma once
#include "GPU_primitive.h"
@@ -116,5 +115,3 @@ int GPU_indexbuf_primitive_len(GPUPrimType prim_type);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_ELEMENT_H__ */
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index ab54148a2ff..2ce6e458378 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_EXTENSIONS_H__
-#define __GPU_EXTENSIONS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -48,17 +47,19 @@ bool GPU_arb_texture_cube_map_array_is_supported(void);
bool GPU_mip_render_workaround(void);
bool GPU_depth_blitting_workaround(void);
bool GPU_unused_fb_slot_workaround(void);
-bool GPU_context_local_shaders_workaround(void);
+bool GPU_use_main_context_workaround(void);
bool GPU_texture_copy_workaround(void);
bool GPU_crappy_amd_driver(void);
+int GPU_texture_size_with_limit(int res);
+
bool GPU_mem_stats_supported(void);
void GPU_mem_stats_get(int *totalmem, int *freemem);
void GPU_code_generate_glsl_lib(void);
+bool GPU_stereo_quadbuffer_support(void);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_EXTENSIONS_H__ */
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index fcbe3ef2a78..9dc07fefd4e 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -21,18 +21,17 @@
* \ingroup gpu
*/
-#ifndef __GPU_FRAMEBUFFER_H__
-#define __GPU_FRAMEBUFFER_H__
+#pragma once
+
+#include "GPU_texture.h"
#ifdef __cplusplus
extern "C" {
#endif
-struct GPUTexture;
-
typedef struct GPUAttachment {
struct GPUTexture *tex;
- int mip, layer;
+ int layer, mip;
} GPUAttachment;
typedef enum eGPUFrameBufferBits {
@@ -41,6 +40,12 @@ typedef enum eGPUFrameBufferBits {
GPU_STENCIL_BIT = (1 << 2),
} eGPUFrameBufferBits;
+typedef enum eGPUBackBuffer {
+ GPU_BACKBUFFER = 0,
+ GPU_BACKBUFFER_RIGHT,
+ GPU_BACKBUFFER_LEFT,
+} eGPUBackBuffer;
+
typedef struct GPUFrameBuffer GPUFrameBuffer;
typedef struct GPUOffScreen GPUOffScreen;
@@ -114,35 +119,35 @@ void GPU_framebuffer_config_array(GPUFrameBuffer *fb, const GPUAttachment *confi
#define GPU_ATTACHMENT_NONE \
{ \
- .tex = NULL, .layer = -1, .mip = 0, \
+ NULL, -1, 0, \
}
#define GPU_ATTACHMENT_LEAVE \
{ \
- .tex = NULL, .layer = -1, .mip = -1, \
+ NULL, -1, -1, \
}
#define GPU_ATTACHMENT_TEXTURE(_tex) \
{ \
- .tex = _tex, .layer = -1, .mip = 0, \
+ _tex, -1, 0, \
}
#define GPU_ATTACHMENT_TEXTURE_MIP(_tex, _mip) \
{ \
- .tex = _tex, .layer = -1, .mip = _mip, \
+ _tex, -1, _mip, \
}
#define GPU_ATTACHMENT_TEXTURE_LAYER(_tex, _layer) \
{ \
- .tex = _tex, .layer = _layer, .mip = 0, \
+ _tex, _layer, 0, \
}
#define GPU_ATTACHMENT_TEXTURE_LAYER_MIP(_tex, _layer, _mip) \
{ \
- .tex = _tex, .layer = _layer, .mip = _mip, \
+ _tex, _layer, _mip, \
}
#define GPU_ATTACHMENT_TEXTURE_CUBEFACE(_tex, _face) \
{ \
- .tex = _tex, .layer = _face, .mip = 0, \
+ _tex, _face, 0, \
}
#define GPU_ATTACHMENT_TEXTURE_CUBEFACE_MIP(_tex, _face, _mip) \
{ \
- .tex = _tex, .layer = _face, .mip = _mip, \
+ _tex, _face, _mip, \
}
/* Framebuffer operations */
@@ -176,8 +181,15 @@ void GPU_framebuffer_clear(GPUFrameBuffer *fb,
void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float (*clear_cols)[4]);
void GPU_framebuffer_read_depth(GPUFrameBuffer *fb, int x, int y, int w, int h, float *data);
-void GPU_framebuffer_read_color(
- GPUFrameBuffer *fb, int x, int y, int w, int h, int channels, int slot, float *data);
+void GPU_framebuffer_read_color(GPUFrameBuffer *fb,
+ int x,
+ int y,
+ int w,
+ int h,
+ int channels,
+ int slot,
+ eGPUDataFormat format,
+ void *data);
void GPU_framebuffer_blit(GPUFrameBuffer *fb_read,
int read_slot,
@@ -199,7 +211,7 @@ GPUOffScreen *GPU_offscreen_create(
void GPU_offscreen_free(GPUOffScreen *ofs);
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save);
void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore);
-void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels);
+void GPU_offscreen_read_pixels(GPUOffScreen *ofs, eGPUDataFormat type, void *pixels);
void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y);
int GPU_offscreen_width(const GPUOffScreen *ofs);
int GPU_offscreen_height(const GPUOffScreen *ofs);
@@ -214,8 +226,11 @@ void GPU_clear_color(float red, float green, float blue, float alpha);
void GPU_clear_depth(float depth);
void GPU_clear(eGPUFrameBufferBits flags);
+void GPU_frontbuffer_read_pixels(
+ int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data);
+
+void GPU_backbuffer_bind(eGPUBackBuffer buffer);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_FRAMEBUFFER_H__ */
diff --git a/source/blender/gpu/GPU_glew.h b/source/blender/gpu/GPU_glew.h
index 744bce9713a..e87a7054e5f 100644
--- a/source/blender/gpu/GPU_glew.h
+++ b/source/blender/gpu/GPU_glew.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_GLEW_H__
-#define __GPU_GLEW_H__
+#pragma once
#if defined(WITH_OPENGL)
# include "glew-mx.h"
@@ -30,5 +29,3 @@
# include "GPU_legacy_stubs.h"
# endif
#endif
-
-#endif /* __GPU_GLEW_H__ */
diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h
index d1db1d5f3e7..41d4f5d28d3 100644
--- a/source/blender/gpu/GPU_immediate.h
+++ b/source/blender/gpu/GPU_immediate.h
@@ -23,14 +23,14 @@
* GPU immediate mode work-alike
*/
-#ifndef __GPU_IMMEDIATE_H__
-#define __GPU_IMMEDIATE_H__
+#pragma once
#include "GPU_batch.h"
#include "GPU_immediate_util.h"
#include "GPU_primitive.h"
#include "GPU_shader.h"
#include "GPU_shader_interface.h"
+#include "GPU_texture.h"
#include "GPU_vertex_format.h"
#ifdef __cplusplus
@@ -41,7 +41,7 @@ extern "C" {
GPUVertFormat *immVertexFormat(void);
/** Every immBegin must have a program bound first. */
-void immBindProgram(uint32_t program, const GPUShaderInterface *);
+void immBindShader(GPUShader *shader);
/** Call after your last immEnd, or before binding another program. */
void immUnbindProgram(void);
@@ -115,6 +115,9 @@ void immUniform4fv(const char *name, const float data[4]);
void immUniformArray4fv(const char *bare_name, const float *data, int count);
void immUniformMatrix4fv(const char *name, const float data[4][4]);
+void immBindTexture(const char *name, GPUTexture *tex);
+void immBindTextureSampler(const char *name, GPUTexture *tex, eGPUSamplerState state);
+
/* Convenience functions for setting "uniform vec4 color". */
/* The rgb functions have implicit alpha = 1.0. */
void immUniformColor4f(float r, float g, float b, float a);
@@ -130,13 +133,14 @@ void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a);
void immUniformColor4ubv(const unsigned char rgba[4]);
/**
- * Extend #immBindProgram to use Blender’s library of built-in shader programs.
+ * Extend #immBindShader to use Blender’s library of built-in shader programs.
* Use #immUnbindProgram() when done.
*/
void immBindBuiltinProgram(eGPUBuiltinShader shader_id);
/* Extend immUniformColor to take Blender's themes */
void immUniformThemeColor(int color_id);
+void immUniformThemeColorAlpha(int color_id, float a);
void immUniformThemeColor3(int color_id);
void immUniformThemeColorShade(int color_id, int offset);
void immUniformThemeColorShadeAlpha(int color_id, int color_offset, int alpha_offset);
@@ -153,5 +157,3 @@ void immDestroy(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_IMMEDIATE_H__ */
diff --git a/source/blender/gpu/GPU_immediate_util.h b/source/blender/gpu/GPU_immediate_util.h
index 47b44b59461..7786bcd2d06 100644
--- a/source/blender/gpu/GPU_immediate_util.h
+++ b/source/blender/gpu/GPU_immediate_util.h
@@ -20,8 +20,7 @@
* Utility drawing functions (rough equivalent to OpenGL's GLU)
*/
-#ifndef __GPU_IMMEDIATE_UTIL_H__
-#define __GPU_IMMEDIATE_UTIL_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -92,5 +91,3 @@ void imm_draw_cylinder_fill_3d(
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_IMMEDIATE_UTIL_H__ */
diff --git a/source/blender/gpu/GPU_init_exit.h b/source/blender/gpu/GPU_init_exit.h
index 3e30a1ddcf5..42c56940c4c 100644
--- a/source/blender/gpu/GPU_init_exit.h
+++ b/source/blender/gpu/GPU_init_exit.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_INIT_EXIT_H__
-#define __GPU_INIT_EXIT_H__
+#pragma once
#include "BLI_utildefines.h"
@@ -32,10 +31,8 @@ extern "C" {
void GPU_init(void);
void GPU_exit(void);
-bool GPU_is_initialized(void);
+bool GPU_is_init(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_INIT_EXIT_H__ */
diff --git a/source/blender/gpu/GPU_legacy_stubs.h b/source/blender/gpu/GPU_legacy_stubs.h
index c666ff73bc6..2e21b879907 100644
--- a/source/blender/gpu/GPU_legacy_stubs.h
+++ b/source/blender/gpu/GPU_legacy_stubs.h
@@ -26,8 +26,7 @@
* This file should be removed in the future
*/
-#ifndef __GPU_LEGACY_STUBS_H__
-#define __GPU_LEGACY_STUBS_H__
+#pragma once
#if defined(__GNUC__)
# pragma GCC diagnostic push
@@ -512,5 +511,3 @@ _GL_VOID DO_NOT_USE_glClientActiveTexture(GLenum texture) _GL_VOID_RET
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
-
-#endif /* __GPU_LEGACY_STUBS_H__ */
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index eeb2d2caef2..b8957ff1819 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_MATERIAL_H__
-#define __GPU_MATERIAL_H__
+#pragma once
#include "DNA_customdata_types.h" /* for CustomDataType */
#include "DNA_listBase.h"
@@ -110,6 +109,7 @@ typedef enum eGPUMatFlag {
GPU_MATFLAG_GLOSSY = (1 << 1),
GPU_MATFLAG_REFRACT = (1 << 2),
GPU_MATFLAG_SSS = (1 << 3),
+ GPU_MATFLAG_BARYCENTRIC = (1 << 4),
} eGPUMatFlag;
typedef enum eGPUBlendMode {
@@ -137,6 +137,13 @@ typedef enum eGPUMaterialStatus {
GPU_MAT_SUCCESS,
} eGPUMaterialStatus;
+typedef void (*GPUMaterialEvalCallbackFn)(GPUMaterial *mat,
+ int options,
+ const char **vert_code,
+ const char **geom_code,
+ const char **frag_lib,
+ const char **defines);
+
GPUNodeLink *GPU_constant(const float *num);
GPUNodeLink *GPU_uniform(const float *num);
GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name);
@@ -169,8 +176,8 @@ void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
void GPU_material_sss_profile_create(GPUMaterial *material,
float radii[3],
- short *falloff_type,
- float *sharpness);
+ const short *falloff_type,
+ const float *sharpness);
struct GPUUniformBuffer *GPU_material_sss_profile_get(GPUMaterial *material,
int sample_len,
struct GPUTexture **tex_profile);
@@ -190,7 +197,8 @@ GPUMaterial *GPU_material_from_nodetree(struct Scene *scene,
const char *geom_code,
const char *frag_lib,
const char *defines,
- const char *name);
+ const char *name,
+ GPUMaterialEvalCallbackFn callback);
void GPU_material_compile(GPUMaterial *mat);
void GPU_material_free(struct ListBase *gpumaterial);
@@ -255,5 +263,3 @@ ListBase GPU_material_volume_grids(GPUMaterial *material);
#ifdef __cplusplus
}
#endif
-
-#endif /*__GPU_MATERIAL_H__*/
diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h
index 2899fba46e4..7b94a535a30 100644
--- a/source/blender/gpu/GPU_matrix.h
+++ b/source/blender/gpu/GPU_matrix.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_MATRIX_H__
-#define __GPU_MATRIX_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -102,11 +101,15 @@ struct GPUMatrixUnproject_Precalc {
float model_inverted[4][4];
float view[4];
bool is_persp;
- /** Result of 'projmat_dimensions'. */
+ /**
+ * Result of #projmat_dimensions_db.
+ * Using double precision here is important as far clipping ranges
+ * can cause divide-by-zero when using float, see: T66937.
+ */
struct {
- float xmin, xmax;
- float ymin, ymax;
- float zmin, zmax;
+ double xmin, xmax;
+ double ymin, ymax;
+ double zmin, zmax;
} dims;
};
@@ -147,6 +150,10 @@ const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3];
void GPU_matrix_bind(const struct GPUShaderInterface *);
bool GPU_matrix_dirty_get(void); /* since last bind */
+/* own working polygon offset */
+float GPU_polygon_offset_calc(const float (*winmat)[4], float viewdist, float dist);
+void GPU_polygon_offset(float viewdist, float dist);
+
/* Python API needs to be able to inspect the stack so errors raise exceptions
* instead of crashing. */
#ifdef USE_GPU_PY_MATRIX_API
@@ -228,5 +235,3 @@ int GPU_matrix_stack_level_get_projection(void);
* however we need to check these limits in code that calls into these API's. */
#define GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT (-100)
#define GPU_MATRIX_ORTHO_CLIP_FAR_DEFAULT (100)
-
-#endif /* __GPU_MATRIX_H__ */
diff --git a/source/blender/gpu/GPU_platform.h b/source/blender/gpu/GPU_platform.h
index f199a748cb5..a89298c0d01 100644
--- a/source/blender/gpu/GPU_platform.h
+++ b/source/blender/gpu/GPU_platform.h
@@ -21,14 +21,10 @@
* \ingroup gpu
*/
-#ifndef __GPU_PLATFORM_H__
-#define __GPU_PLATFORM_H__
+#pragma once
#include "BLI_sys_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "BLI_utildefines.h"
/* GPU platform support */
@@ -43,6 +39,8 @@ typedef enum eGPUDeviceType {
GPU_DEVICE_ANY = (0xff),
} eGPUDeviceType;
+ENUM_OPERATORS(eGPUDeviceType)
+
typedef enum eGPUOSType {
GPU_OS_WIN = (1 << 8),
GPU_OS_MAC = (1 << 9),
@@ -63,6 +61,10 @@ typedef enum eGPUSupportLevel {
GPU_SUPPORT_LEVEL_UNSUPPORTED,
} eGPUSupportLevel;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver);
eGPUSupportLevel GPU_platform_support_level(void);
const char *GPU_platform_support_level_key(void);
@@ -71,5 +73,3 @@ const char *GPU_platform_gpu_name(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_PLATFORM_H__ */
diff --git a/source/blender/gpu/GPU_primitive.h b/source/blender/gpu/GPU_primitive.h
index 4cd6205c0d1..e910e81fac1 100644
--- a/source/blender/gpu/GPU_primitive.h
+++ b/source/blender/gpu/GPU_primitive.h
@@ -23,8 +23,7 @@
* GPU geometric primitives
*/
-#ifndef __GPU_PRIMITIVE_H__
-#define __GPU_PRIMITIVE_H__
+#pragma once
#include "GPU_common.h"
@@ -63,5 +62,3 @@ bool GPU_primtype_belongs_to_class(GPUPrimType, GPUPrimClass);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_PRIMITIVE_H__ */
diff --git a/source/blender/gpu/GPU_select.h b/source/blender/gpu/GPU_select.h
index d9a8e964a3d..d28363253b1 100644
--- a/source/blender/gpu/GPU_select.h
+++ b/source/blender/gpu/GPU_select.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_SELECT_H__
-#define __GPU_SELECT_H__
+#pragma once
#include "BLI_sys_types.h"
@@ -63,5 +62,3 @@ void GPU_select_buffer_stride_realign(const struct rcti *src, const struct rcti
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 0ad472113c9..f782742ae53 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_SHADER_H__
-#define __GPU_SHADER_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -87,8 +86,6 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader);
int GPU_shader_get_program(GPUShader *shader);
-void *GPU_shader_get_interface(GPUShader *shader);
-
void GPU_shader_set_srgb_uniform(const struct GPUShaderInterface *interface);
int GPU_shader_get_uniform(GPUShader *shader, const char *name);
@@ -144,8 +141,6 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_2D_IMAGE,
GPU_SHADER_2D_IMAGE_COLOR,
GPU_SHADER_2D_IMAGE_DESATURATE_COLOR,
- GPU_SHADER_2D_IMAGE_ALPHA_COLOR,
- GPU_SHADER_2D_IMAGE_ALPHA,
GPU_SHADER_2D_IMAGE_RECT_COLOR,
GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR,
GPU_SHADER_2D_CHECKER,
@@ -209,16 +204,6 @@ typedef enum eGPUBuiltinShader {
GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE,
GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE,
GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
- GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,
- /**
- * Draw texture with alpha. Take a 3D position and a 2D texture coordinate for each vertex.
- *
- * \param alpha: uniform float
- * \param image: uniform sampler2D
- * \param texCoord: in vec2
- * \param pos: in vec3
- */
- GPU_SHADER_3D_IMAGE_MODULATE_ALPHA,
/* points */
/**
* Draw round points with a hardcoded size.
@@ -384,5 +369,3 @@ void GPU_shader_free_builtin_shaders(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_SHADER_H__ */
diff --git a/source/blender/gpu/GPU_shader_interface.h b/source/blender/gpu/GPU_shader_interface.h
index 28ee162bdbd..8aba1236b65 100644
--- a/source/blender/gpu/GPU_shader_interface.h
+++ b/source/blender/gpu/GPU_shader_interface.h
@@ -23,8 +23,7 @@
* GPU shader interface (C --> GLSL)
*/
-#ifndef __GPU_SHADER_INTERFACE_H__
-#define __GPU_SHADER_INTERFACE_H__
+#pragma once
#include "GPU_common.h"
@@ -116,5 +115,3 @@ void GPU_shaderinterface_remove_batch_ref(GPUShaderInterface *, struct GPUBatch
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_SHADER_INTERFACE_H__ */
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 4daf3f8dba5..4a2c90e241b 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -18,8 +18,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_STATE_H__
-#define __GPU_STATE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -40,6 +39,17 @@ typedef enum eGPUFilterFunction {
GPU_LINEAR,
} eGPUFilterFunction;
+typedef enum eGPUFaceCull {
+ GPU_CULL_NONE = 0, /* Culling disabled. */
+ GPU_CULL_FRONT,
+ GPU_CULL_BACK,
+} eGPUFaceCull;
+
+typedef enum eGPUProvokingVertex {
+ GPU_VERTEX_FIRST = 0,
+ GPU_VERTEX_LAST, /* Default */
+} eGPUProvokingVertex;
+
/* Initialize
* - sets the default Blender opengl state, if in doubt, check
* the contents of this function
@@ -52,9 +62,13 @@ void GPU_blend_set_func_separate(eGPUBlendFunction src_rgb,
eGPUBlendFunction dst_rgb,
eGPUBlendFunction src_alpha,
eGPUBlendFunction dst_alpha);
+void GPU_face_culling(eGPUFaceCull culling);
+void GPU_front_facing(bool invert);
+void GPU_provoking_vertex(eGPUProvokingVertex vert);
void GPU_depth_range(float near, float far);
void GPU_depth_test(bool enable);
bool GPU_depth_test_enabled(void);
+void GPU_scissor_test(bool enable);
void GPU_line_smooth(bool enable);
void GPU_line_width(float width);
void GPU_point_size(float size);
@@ -63,13 +77,21 @@ void GPU_program_point_size(bool enable);
void GPU_scissor(int x, int y, int width, int height);
void GPU_scissor_get_f(float coords[4]);
void GPU_scissor_get_i(int coords[4]);
+void GPU_viewport(int x, int y, int width, int height);
void GPU_viewport_size_get_f(float coords[4]);
void GPU_viewport_size_get_i(int coords[4]);
+void GPU_color_mask(bool r, bool g, bool b, bool a);
+void GPU_depth_mask(bool depth);
+bool GPU_depth_mask_get(void);
+void GPU_stencil_mask(uint stencil);
+void GPU_unpack_row_length_set(uint len);
+void GPU_clip_distances(int enabled_len);
+bool GPU_mipmap_enabled(void);
void GPU_flush(void);
void GPU_finish(void);
-void GPU_logic_op_invert_set(bool enable);
+void GPU_logic_op_xor_set(bool enable);
/* Attribute push & pop. */
typedef enum eGPUAttrMask {
@@ -86,5 +108,3 @@ void gpuPopAttr(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_STATE_H__ */
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index a13f61177e6..7ee7f8fcdec 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -21,14 +21,11 @@
* \ingroup gpu
*/
-#ifndef __GPU_TEXTURE_H__
-#define __GPU_TEXTURE_H__
+#pragma once
-#include "GPU_state.h"
+#include "BLI_utildefines.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "GPU_state.h"
struct GPUVertBuf;
struct ImBuf;
@@ -46,7 +43,6 @@ typedef struct GPUTexture GPUTexture;
* - Internally used by textures.
* - All states are created at startup to avoid runtime costs.
*/
-
typedef enum eGPUSamplerState {
GPU_SAMPLER_FILTER = (1 << 0),
GPU_SAMPLER_MIPMAP = (1 << 1),
@@ -60,6 +56,12 @@ typedef enum eGPUSamplerState {
GPU_SAMPLER_MAX = (1 << 8),
} eGPUSamplerState;
+ENUM_OPERATORS(eGPUSamplerState)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define GPU_SAMPLER_DEFAULT GPU_SAMPLER_FILTER
#define GPU_SAMPLER_REPEAT (GPU_SAMPLER_REPEAT_S | GPU_SAMPLER_REPEAT_T | GPU_SAMPLER_REPEAT_R)
@@ -120,7 +122,6 @@ typedef enum eGPUTextureFormat {
#if 0
GPU_RGB10_A2,
GPU_RGB10_A2UI,
- GPU_SRGB8_A8,
#endif
GPU_R11F_G11F_B10F,
GPU_DEPTH32F_STENCIL8,
@@ -149,7 +150,13 @@ typedef enum eGPUTextureFormat {
GPU_R8_SNORM,
#endif
-/* Special formats texture only */
+ /* Special formats texture only */
+ GPU_SRGB8_A8_DXT1,
+ GPU_SRGB8_A8_DXT3,
+ GPU_SRGB8_A8_DXT5,
+ GPU_RGBA8_DXT1,
+ GPU_RGBA8_DXT3,
+ GPU_RGBA8_DXT5,
#if 0
GPU_SRGB8,
GPU_RGB9_E5,
@@ -222,17 +229,10 @@ GPUTexture *GPU_texture_create_cube_array(
GPUTexture *GPU_texture_create_from_vertbuf(struct GPUVertBuf *vert);
GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat data_type, const uint buffer);
-GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode);
-GPUTexture *GPU_texture_from_blender(struct Image *ima,
- struct ImageUser *iuser,
- struct ImBuf *ibuf,
- int textarget);
+GPUTexture *GPU_texture_create_compressed(
+ int w, int h, int miplen, eGPUTextureFormat format, const void *data);
-/* movie clip drawing */
-GPUTexture *GPU_texture_from_movieclip(struct MovieClip *clip,
- struct MovieClipUser *cuser,
- int textarget);
-void GPU_free_texture_movieclip(struct MovieClip *clip);
+GPUTexture *GPU_texture_create_error(int dimension, bool array);
void GPU_texture_add_mipmap(GPUTexture *tex,
eGPUDataFormat gpu_data_format,
@@ -268,14 +268,12 @@ void GPU_texture_unbind_all(void);
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src);
void GPU_texture_generate_mipmap(GPUTexture *tex);
+void GPU_texture_anisotropic_filter(GPUTexture *tex, bool use_aniso);
void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare);
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter);
void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter);
void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp);
-void GPU_texture_filters(GPUTexture *tex,
- eGPUFilterFunction min_filter,
- eGPUFilterFunction mag_filter);
-void GPU_texture_swizzle_channel_auto(GPUTexture *tex, int channels);
+void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4]);
void GPU_texture_attach_framebuffer(GPUTexture *tex, struct GPUFrameBuffer *fb, int attachment);
int GPU_texture_detach_framebuffer(GPUTexture *tex, struct GPUFrameBuffer *fb);
@@ -298,8 +296,8 @@ int GPU_texture_opengl_bindcode(const GPUTexture *tex);
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size);
+void GPU_sampler_icon_bind(int number);
+
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_TEXTURE_H__ */
diff --git a/source/blender/gpu/GPU_uniformbuffer.h b/source/blender/gpu/GPU_uniformbuffer.h
index b221ae035d3..e2b2a757fb9 100644
--- a/source/blender/gpu/GPU_uniformbuffer.h
+++ b/source/blender/gpu/GPU_uniformbuffer.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_UNIFORMBUFFER_H__
-#define __GPU_UNIFORMBUFFER_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -42,8 +41,7 @@ void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_);
void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number);
void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo);
-
-int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo);
+void GPU_uniformbuffer_unbind_all(void);
bool GPU_uniformbuffer_is_empty(GPUUniformBuffer *ubo);
bool GPU_uniformbuffer_is_dirty(GPUUniformBuffer *ubo);
@@ -53,5 +51,3 @@ bool GPU_uniformbuffer_is_dirty(GPUUniformBuffer *ubo);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_UNIFORMBUFFER_H__ */
diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h
index f9bdf726930..757255496e0 100644
--- a/source/blender/gpu/GPU_vertex_buffer.h
+++ b/source/blender/gpu/GPU_vertex_buffer.h
@@ -23,8 +23,7 @@
* GPU vertex buffer
*/
-#ifndef __GPU_VERTEX_BUFFER_H__
-#define __GPU_VERTEX_BUFFER_H__
+#pragma once
#include "GPU_vertex_format.h"
@@ -59,10 +58,10 @@ typedef struct GPUVertBuf {
/** 0 indicates not yet allocated. */
uint32_t vbo_id;
/** Usage hint for GL optimisation. */
- uint usage : 2;
+ GPUUsageType usage;
/** Data has been touched and need to be reuploaded to GPU. */
- uint dirty : 1;
- unsigned char *data; /* NULL indicates data in VRAM (unmapped) */
+ bool dirty;
+ uchar *data; /* NULL indicates data in VRAM (unmapped) */
} GPUVertBuf;
GPUVertBuf *GPU_vertbuf_create(GPUUsageType);
@@ -147,5 +146,3 @@ uint GPU_vertbuf_get_memory_usage(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_VERTEX_BUFFER_H__ */
diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h
index 34bfbb27823..59af912ed3d 100644
--- a/source/blender/gpu/GPU_vertex_format.h
+++ b/source/blender/gpu/GPU_vertex_format.h
@@ -23,8 +23,7 @@
* GPU vertex format
*/
-#ifndef __GPU_VERTEX_FORMAT_H__
-#define __GPU_VERTEX_FORMAT_H__
+#pragma once
#include "BLI_assert.h"
#include "BLI_compiler_compat.h"
@@ -42,7 +41,7 @@ extern "C" {
#define GPU_MAX_SAFE_ATTR_NAME 12
typedef enum {
- GPU_COMP_I8,
+ GPU_COMP_I8 = 0,
GPU_COMP_U8,
GPU_COMP_I16,
GPU_COMP_U16,
@@ -52,17 +51,21 @@ typedef enum {
GPU_COMP_F32,
GPU_COMP_I10,
+ /* Warning! adjust GPUVertAttr if changing. */
} GPUVertCompType;
typedef enum {
- GPU_FETCH_FLOAT,
+ GPU_FETCH_FLOAT = 0,
GPU_FETCH_INT,
GPU_FETCH_INT_TO_FLOAT_UNIT, /* 127 (ubyte) -> 0.5 (and so on for other int types) */
GPU_FETCH_INT_TO_FLOAT, /* 127 (any int type) -> 127.0 */
+ /* Warning! adjust GPUVertAttr if changing. */
} GPUVertFetchMode;
typedef struct GPUVertAttr {
+ /* GPUVertFetchMode */
uint fetch_mode : 2;
+ /* GPUVertCompType */
uint comp_type : 3;
/* 1 to 4 or 8 or 12 or 16 */
uint comp_len : 5;
@@ -72,8 +75,6 @@ typedef struct GPUVertAttr {
uint offset : 11;
/* up to GPU_VERT_ATTR_MAX_NAMES */
uint name_len : 3;
- uint gl_comp_type;
- /* -- 8 Bytes -- */
uchar names[GPU_VERT_ATTR_MAX_NAMES];
} GPUVertAttr;
@@ -197,5 +198,3 @@ BLI_INLINE GPUPackedNormal GPU_normal_convert_i10_s3(const short data[3])
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_VERTEX_FORMAT_H__ */
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index 50d265feaad..60b78ecd59b 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -21,8 +21,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_VIEWPORT_H__
-#define __GPU_VIEWPORT_H__
+#pragma once
#include <stdbool.h>
@@ -41,6 +40,8 @@ extern "C" {
typedef struct GPUViewport GPUViewport;
+struct GPUFrameBuffer;
+
/* Contains memory pools information */
typedef struct ViewportMemoryPool {
struct BLI_memblock *commands;
@@ -151,8 +152,9 @@ GPUTexture *GPU_viewport_texture_pool_query(
bool GPU_viewport_engines_data_validate(GPUViewport *viewport, void **engine_handle_array);
void GPU_viewport_cache_release(GPUViewport *viewport);
+struct GPUFrameBuffer *GPU_viewport_framebuffer_default_get(GPUViewport *viewport);
+struct GPUFrameBuffer *GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport);
+
#ifdef __cplusplus
}
#endif
-
-#endif // __GPU_VIEWPORT_H__
diff --git a/source/blender/gpu/intern/gpu_attr_binding.c b/source/blender/gpu/intern/gpu_attr_binding.cc
index 6cb60884620..6cb60884620 100644
--- a/source/blender/gpu/intern/gpu_attr_binding.c
+++ b/source/blender/gpu/intern/gpu_attr_binding.cc
diff --git a/source/blender/gpu/intern/gpu_attr_binding_private.h b/source/blender/gpu/intern/gpu_attr_binding_private.h
index 301ec3333dd..4d359343c38 100644
--- a/source/blender/gpu/intern/gpu_attr_binding_private.h
+++ b/source/blender/gpu/intern/gpu_attr_binding_private.h
@@ -23,12 +23,16 @@
* GPU vertex attribute binding
*/
-#ifndef __GPU_ATTR_BINDING_PRIVATE_H__
-#define __GPU_ATTR_BINDING_PRIVATE_H__
+#pragma once
#include "GPU_shader_interface.h"
#include "GPU_vertex_format.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* TODO(fclem) remove, use shaderface directly. */
void AttrBinding_clear(GPUAttrBinding *binding);
void get_attr_locations(const GPUVertFormat *format,
@@ -36,4 +40,6 @@ void get_attr_locations(const GPUVertFormat *format,
const GPUShaderInterface *shaderface);
uint read_attr_location(const GPUAttrBinding *binding, uint a_idx);
-#endif /* __GPU_ATTR_BINDING_PRIVATE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.cc
index 5f77f13c135..9f9adcacfa6 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -37,6 +37,7 @@
#include "gpu_context_private.h"
#include "gpu_primitive_private.h"
#include "gpu_shader_private.h"
+#include "gpu_vertex_format_private.h"
#include <limits.h>
#include <stdlib.h>
@@ -89,7 +90,7 @@ GPUBatch *GPU_batch_create_ex(GPUPrimType prim_type,
GPUIndexBuf *elem,
uint owns_flag)
{
- GPUBatch *batch = MEM_callocN(sizeof(GPUBatch), "GPUBatch");
+ GPUBatch *batch = (GPUBatch *)MEM_callocN(sizeof(GPUBatch), "GPUBatch");
GPU_batch_init_ex(batch, prim_type, verts, elem, owns_flag);
return batch;
}
@@ -327,10 +328,10 @@ static GLuint batch_vao_get(GPUBatch *batch)
}
/* Init dynamic arrays and let the branch below set the values. */
batch->dynamic_vaos.count = GPU_BATCH_VAO_DYN_ALLOC_COUNT;
- batch->dynamic_vaos.interfaces = MEM_callocN(
+ batch->dynamic_vaos.interfaces = (const GPUShaderInterface **)MEM_callocN(
batch->dynamic_vaos.count * sizeof(GPUShaderInterface *), "dyn vaos interfaces");
- batch->dynamic_vaos.vao_ids = MEM_callocN(batch->dynamic_vaos.count * sizeof(GLuint),
- "dyn vaos ids");
+ batch->dynamic_vaos.vao_ids = (GLuint *)MEM_callocN(
+ batch->dynamic_vaos.count * sizeof(GLuint), "dyn vaos ids");
}
}
@@ -346,11 +347,11 @@ static GLuint batch_vao_get(GPUBatch *batch)
/* Not enough place, realloc the array. */
i = batch->dynamic_vaos.count;
batch->dynamic_vaos.count += GPU_BATCH_VAO_DYN_ALLOC_COUNT;
- batch->dynamic_vaos.interfaces = MEM_recallocN((void *)batch->dynamic_vaos.interfaces,
- sizeof(GPUShaderInterface *) *
- batch->dynamic_vaos.count);
- batch->dynamic_vaos.vao_ids = MEM_recallocN(batch->dynamic_vaos.vao_ids,
- sizeof(GLuint) * batch->dynamic_vaos.count);
+ batch->dynamic_vaos.interfaces = (const GPUShaderInterface **)MEM_recallocN(
+ (void *)batch->dynamic_vaos.interfaces,
+ sizeof(GPUShaderInterface *) * batch->dynamic_vaos.count);
+ batch->dynamic_vaos.vao_ids = (GLuint *)MEM_recallocN(
+ batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count);
}
batch->dynamic_vaos.interfaces[i] = batch->interface;
batch->dynamic_vaos.vao_ids[i] = new_vao = GPU_vao_alloc();
@@ -370,22 +371,20 @@ static GLuint batch_vao_get(GPUBatch *batch)
return new_vao;
}
-void GPU_batch_program_set_no_use(GPUBatch *batch,
- uint32_t program,
- const GPUShaderInterface *shaderface)
+void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader)
{
#if TRUST_NO_ONE
- assert(glIsProgram(program));
+ assert(glIsProgram(shader->program));
assert(batch->program_in_use == 0);
#endif
- batch->interface = shaderface;
- batch->program = program;
+ batch->interface = shader->interface;
+ batch->program = shader->program;
batch->vao_id = batch_vao_get(batch);
}
-void GPU_batch_program_set(GPUBatch *batch, uint32_t program, const GPUShaderInterface *shaderface)
+void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader)
{
- GPU_batch_program_set_no_use(batch, program, shaderface);
+ GPU_batch_set_shader_no_bind(batch, shader);
GPU_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */
}
@@ -440,6 +439,7 @@ static void create_bindings(GPUVertBuf *verts,
}
const GLvoid *pointer = (const GLubyte *)0 + offset + v_first * stride;
+ const GLenum type = convert_comp_type_to_gl(static_cast<GPUVertCompType>(a->comp_type));
for (uint n_idx = 0; n_idx < a->name_len; n_idx++) {
const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
@@ -452,19 +452,13 @@ static void create_bindings(GPUVertBuf *verts,
*attr_mask &= ~(1 << input->location);
if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) {
-#if TRUST_NO_ONE
- assert(a->fetch_mode == GPU_FETCH_FLOAT);
- assert(a->gl_comp_type == GL_FLOAT);
-#endif
+ BLI_assert(a->fetch_mode == GPU_FETCH_FLOAT);
+ BLI_assert(a->comp_type == GPU_COMP_F32);
for (int i = 0; i < a->comp_len / 4; i++) {
glEnableVertexAttribArray(input->location + i);
glVertexAttribDivisor(input->location + i, (use_instancing) ? 1 : 0);
- glVertexAttribPointer(input->location + i,
- 4,
- a->gl_comp_type,
- GL_FALSE,
- stride,
- (const GLubyte *)pointer + i * 16);
+ glVertexAttribPointer(
+ input->location + i, 4, type, GL_FALSE, stride, (const GLubyte *)pointer + i * 16);
}
}
else {
@@ -474,15 +468,13 @@ static void create_bindings(GPUVertBuf *verts,
switch (a->fetch_mode) {
case GPU_FETCH_FLOAT:
case GPU_FETCH_INT_TO_FLOAT:
- glVertexAttribPointer(
- input->location, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer);
+ glVertexAttribPointer(input->location, a->comp_len, type, GL_FALSE, stride, pointer);
break;
case GPU_FETCH_INT_TO_FLOAT_UNIT:
- glVertexAttribPointer(
- input->location, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer);
+ glVertexAttribPointer(input->location, a->comp_len, type, GL_TRUE, stride, pointer);
break;
case GPU_FETCH_INT:
- glVertexAttribIPointer(input->location, a->comp_len, a->gl_comp_type, stride, pointer);
+ glVertexAttribIPointer(input->location, a->comp_len, type, stride, pointer);
break;
}
}
@@ -839,7 +831,7 @@ struct GPUDrawList {
GPUDrawList *GPU_draw_list_create(int length)
{
- GPUDrawList *list = MEM_callocN(sizeof(GPUDrawList), "GPUDrawList");
+ GPUDrawList *list = (GPUDrawList *)MEM_callocN(sizeof(GPUDrawList), "GPUDrawList");
/* Alloc the biggest possible command list which is indexed. */
list->buffer_size = sizeof(GPUDrawCommandIndexed) * length;
if (USE_MULTI_DRAW_INDIRECT) {
@@ -848,7 +840,7 @@ GPUDrawList *GPU_draw_list_create(int length)
glBufferData(GL_DRAW_INDIRECT_BUFFER, list->buffer_size, NULL, GL_DYNAMIC_DRAW);
}
else {
- list->commands = MEM_mallocN(list->buffer_size, "GPUDrawList data");
+ list->commands = (GPUDrawCommand *)MEM_mallocN(list->buffer_size, "GPUDrawList data");
}
return list;
}
@@ -880,7 +872,7 @@ void GPU_draw_list_init(GPUDrawList *list, GPUBatch *batch)
list->cmd_offset = 0;
}
GLenum flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
- list->commands = glMapBufferRange(
+ list->commands = (GPUDrawCommand *)glMapBufferRange(
GL_DRAW_INDIRECT_BUFFER, list->cmd_offset, list->buffer_size - list->cmd_offset, flags);
}
}
@@ -989,17 +981,12 @@ void GPU_draw_list_submit(GPUDrawList *list)
/** \name Utilities
* \{ */
-void GPU_batch_program_set_shader(GPUBatch *batch, GPUShader *shader)
-{
- GPU_batch_program_set(batch, shader->program, shader->interface);
-}
-
void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
eGPUBuiltinShader shader_id,
eGPUShaderConfig sh_cfg)
{
GPUShader *shader = GPU_shader_get_builtin_shader_with_config(shader_id, sh_cfg);
- GPU_batch_program_set(batch, shader->program, shader->interface);
+ GPU_batch_set_shader(batch, shader);
}
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
@@ -1012,10 +999,7 @@ void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
* DO NOT DRAW WITH THE BATCH BEFORE CALLING immUnbindProgram. */
void GPU_batch_program_set_imm_shader(GPUBatch *batch)
{
- GLuint program;
- GPUShaderInterface *interface;
- immGetProgram(&program, &interface);
- GPU_batch_program_set(batch, program, interface);
+ GPU_batch_set_shader(batch, immGetShader());
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_batch_presets.c b/source/blender/gpu/intern/gpu_batch_presets.c
index d16edab5ac9..7f842d4d508 100644
--- a/source/blender/gpu/intern/gpu_batch_presets.c
+++ b/source/blender/gpu/intern/gpu_batch_presets.c
@@ -406,4 +406,17 @@ void gpu_batch_presets_exit(void)
BLI_mutex_end(&g_presets_3d.mutex);
}
+/**
+ * This function only needs to be accessed externally because
+ * we are drawing UI batches with the DRW old context.
+ *
+ * And now we use it for drawing the entire area.
+ *
+ * XXX (Clément) - to cleanup in the upcoming 2.91 refactor.
+ **/
+void GPU_batch_presets_reset()
+{
+ gpu_batch_presets_reset();
+}
+
/** \} */
diff --git a/source/blender/gpu/intern/gpu_batch_private.h b/source/blender/gpu/intern/gpu_batch_private.h
index 58d1810ac7a..93745b9ca9b 100644
--- a/source/blender/gpu/intern/gpu_batch_private.h
+++ b/source/blender/gpu/intern/gpu_batch_private.h
@@ -24,8 +24,7 @@
* Contains VAOs + VBOs + Shader representing a drawable entity.
*/
-#ifndef __GPU_BATCH_PRIVATE_H__
-#define __GPU_BATCH_PRIVATE_H__
+#pragma once
#include "GPU_batch.h"
#include "GPU_context.h"
@@ -40,5 +39,3 @@ void gpu_batch_remove_interface_ref(GPUBatch *batch, const GPUShaderInterface *i
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_BATCH_PRIVATE_H__ */
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 9c21f9040da..10d5a860f6a 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -38,6 +38,7 @@
#include "BLI_utildefines.h"
#include "DNA_meshdata_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_DerivedMesh.h"
#include "BKE_ccg.h"
@@ -234,7 +235,8 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
const bool show_mask = vmask && (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
const bool show_face_sets = sculpt_face_sets &&
(update_flags & GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS) != 0;
- const bool show_vcol = (vcol || vtcol) && (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
+ const bool show_vcol = (vcol || (vtcol && U.experimental.use_sculpt_vertex_colors)) &&
+ (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
bool empty_mask = true;
bool default_face_set = true;
@@ -317,7 +319,7 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers,
/* Vertex Colors. */
if (show_vcol) {
ushort scol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
- if (vtcol) {
+ if (vtcol && U.experimental.use_sculpt_vertex_colors) {
scol[0] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[0]);
scol[1] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[1]);
scol[2] = unit_float_to_ushort_clamp(vtcol[vtri[j]].color[2]);
@@ -450,7 +452,7 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const MPoly *mpoly,
static void gpu_pbvh_grid_fill_index_buffers(GPU_PBVH_Buffers *buffers,
SubdivCCG *UNUSED(subdiv_ccg),
const int *UNUSED(face_sets),
- int *grid_indices,
+ const int *grid_indices,
uint visible_quad_len,
int totgrid,
int gridsize)
@@ -581,7 +583,7 @@ static void gpu_pbvh_grid_fill_index_buffers(GPU_PBVH_Buffers *buffers,
void GPU_pbvh_grid_buffers_update_free(GPU_PBVH_Buffers *buffers,
const struct DMFlagMat *grid_flag_mats,
- int *grid_indices)
+ const int *grid_indices)
{
const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index c1e7933d7ba..8947365d666 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -41,7 +41,6 @@
#include "BKE_material.h"
#include "GPU_extensions.h"
-#include "GPU_glew.h"
#include "GPU_material.h"
#include "GPU_shader.h"
#include "GPU_uniformbuffer.h"
@@ -56,8 +55,8 @@
#include <stdarg.h>
#include <string.h>
+extern char datatoc_gpu_shader_codegen_lib_glsl[];
extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
-extern char datatoc_common_view_lib_glsl[];
/* -------------------- GPUPass Cache ------------------ */
/**
@@ -282,18 +281,15 @@ static const char *gpu_builtin_name(eGPUBuiltin builtin)
static void codegen_set_unique_ids(GPUNodeGraph *graph)
{
- GPUNode *node;
- GPUInput *input;
- GPUOutput *output;
int id = 1;
- for (node = graph->nodes.first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
+ LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
/* set id for unique names of uniform variables */
input->id = id++;
}
- for (output = node->outputs.first; output; output = output->next) {
+ LISTBASE_FOREACH (GPUOutput *, output, &node->outputs) {
/* set id for unique names of tmp variables storing output */
output->id = id++;
}
@@ -307,17 +303,10 @@ static int codegen_process_uniforms_functions(GPUMaterial *material,
DynStr *ds,
GPUNodeGraph *graph)
{
- GPUNode *node;
- GPUInput *input;
const char *name;
int builtins = 0;
ListBase ubo_inputs = {NULL, NULL};
- /* Attributes */
- LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
- BLI_dynstr_appendf(ds, "in %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
- }
-
/* Textures */
LISTBASE_FOREACH (GPUMaterialTexture *, tex, &graph->textures) {
if (tex->colorband) {
@@ -339,8 +328,9 @@ static int codegen_process_uniforms_functions(GPUMaterial *material,
}
/* Print other uniforms */
- for (node = graph->nodes.first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
+
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
+ LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
if (input->source == GPU_SOURCE_BUILTIN) {
/* only define each builtin uniform/varying once */
if (!(builtins & input->builtin)) {
@@ -382,8 +372,8 @@ static int codegen_process_uniforms_functions(GPUMaterial *material,
BLI_dynstr_appendf(ds, "\nlayout (std140) uniform %s {\n", GPU_UBO_BLOCK_NAME);
LISTBASE_FOREACH (LinkData *, link, &ubo_inputs) {
- input = link->data;
- BLI_dynstr_appendf(ds, "\t%s unf%d;\n", gpu_data_type_to_string(input->type), input->id);
+ GPUInput *input = (GPUInput *)(link->data);
+ BLI_dynstr_appendf(ds, " %s unf%d;\n", gpu_data_type_to_string(input->type), input->id);
}
BLI_dynstr_append(ds, "};\n");
BLI_freelistN(&ubo_inputs);
@@ -396,34 +386,26 @@ static int codegen_process_uniforms_functions(GPUMaterial *material,
static void codegen_declare_tmps(DynStr *ds, GPUNodeGraph *graph)
{
- GPUNode *node;
- GPUOutput *output;
-
- for (node = graph->nodes.first; node; node = node->next) {
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
/* declare temporary variables for node output storage */
- for (output = node->outputs.first; output; output = output->next) {
+ LISTBASE_FOREACH (GPUOutput *, output, &node->outputs) {
if (output->type == GPU_CLOSURE) {
- BLI_dynstr_appendf(ds, "\tClosure tmp%d;\n", output->id);
+ BLI_dynstr_appendf(ds, " Closure tmp%d;\n", output->id);
}
else {
- BLI_dynstr_appendf(ds, "\t%s tmp%d;\n", gpu_data_type_to_string(output->type), output->id);
+ BLI_dynstr_appendf(ds, " %s tmp%d;\n", gpu_data_type_to_string(output->type), output->id);
}
}
}
-
BLI_dynstr_append(ds, "\n");
}
static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *finaloutput)
{
- GPUNode *node;
- GPUInput *input;
- GPUOutput *output;
-
- for (node = graph->nodes.first; node; node = node->next) {
- BLI_dynstr_appendf(ds, "\t%s(", node->name);
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
+ BLI_dynstr_appendf(ds, " %s(", node->name);
- for (input = node->inputs.first; input; input = input->next) {
+ LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
if (input->source == GPU_SOURCE_TEX) {
BLI_dynstr_append(ds, input->texture->sampler_name);
}
@@ -504,7 +486,7 @@ static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *f
BLI_dynstr_append(ds, ", ");
}
- for (output = node->outputs.first; output; output = output->next) {
+ LISTBASE_FOREACH (GPUOutput *, output, &node->outputs) {
BLI_dynstr_appendf(ds, "tmp%d", output->id);
if (output->next) {
BLI_dynstr_append(ds, ", ");
@@ -514,21 +496,24 @@ static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *f
BLI_dynstr_append(ds, ");\n");
}
- BLI_dynstr_appendf(ds, "\n\treturn tmp%d", finaloutput->id);
- BLI_dynstr_append(ds, ";\n");
+ BLI_dynstr_appendf(ds, "\n return tmp%d;\n", finaloutput->id);
}
-static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph)
+static char *code_generate_fragment(GPUMaterial *material,
+ GPUNodeGraph *graph,
+ const char *interface_str)
{
DynStr *ds = BLI_dynstr_new();
char *code;
int builtins;
-#if 0
- BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
-#endif
-
codegen_set_unique_ids(graph);
+
+ /* Attributes, Shader stage interface. */
+ if (interface_str) {
+ BLI_dynstr_appendf(ds, "in codegenInterface {%s};\n\n", interface_str);
+ }
+
builtins = codegen_process_uniforms_functions(material, ds, graph);
if (builtins & (GPU_OBJECT_INFO | GPU_OBJECT_COLOR)) {
@@ -536,73 +521,61 @@ static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph)
}
if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "in vec2 barycentricTexCo;\n");
- }
-
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "flat in vec3 barycentricDist;\n");
+ BLI_dynstr_append(ds, datatoc_gpu_shader_codegen_lib_glsl);
}
BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n");
if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds,
- "\tvec2 barytexco = vec2((fract(barycentricTexCo.y) != 0.0)\n"
- "\t ? barycentricTexCo.x\n"
- "\t : 1.0 - barycentricTexCo.x,\n"
- "\t 0.0);\n");
- BLI_dynstr_append(ds, "#else\n");
- BLI_dynstr_append(ds, "\tvec2 barytexco = barycentricTexCo;\n");
- BLI_dynstr_append(ds, "#endif\n");
+ BLI_dynstr_append(ds, " vec2 barytexco = barycentric_resolve(barycentricTexCo);\n");
}
/* TODO(fclem) get rid of that. */
if (builtins & GPU_VIEW_MATRIX) {
- BLI_dynstr_append(ds, "\t#define viewmat ViewMatrix\n");
+ BLI_dynstr_append(ds, " #define viewmat ViewMatrix\n");
}
if (builtins & GPU_CAMERA_TEXCO_FACTORS) {
- BLI_dynstr_append(ds, "\t#define camtexfac CameraTexCoFactors\n");
+ BLI_dynstr_append(ds, " #define camtexfac CameraTexCoFactors\n");
}
if (builtins & GPU_OBJECT_MATRIX) {
- BLI_dynstr_append(ds, "\t#define objmat ModelMatrix\n");
+ BLI_dynstr_append(ds, " #define objmat ModelMatrix\n");
}
if (builtins & GPU_INVERSE_OBJECT_MATRIX) {
- BLI_dynstr_append(ds, "\t#define objinv ModelMatrixInverse\n");
+ BLI_dynstr_append(ds, " #define objinv ModelMatrixInverse\n");
}
if (builtins & GPU_INVERSE_VIEW_MATRIX) {
- BLI_dynstr_append(ds, "\t#define viewinv ViewMatrixInverse\n");
+ BLI_dynstr_append(ds, " #define viewinv ViewMatrixInverse\n");
}
if (builtins & GPU_LOC_TO_VIEW_MATRIX) {
- BLI_dynstr_append(ds, "\t#define localtoviewmat (ViewMatrix * ModelMatrix)\n");
+ BLI_dynstr_append(ds, " #define localtoviewmat (ViewMatrix * ModelMatrix)\n");
}
if (builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) {
BLI_dynstr_append(ds,
- "\t#define invlocaltoviewmat (ModelMatrixInverse * ViewMatrixInverse)\n");
+ " #define invlocaltoviewmat (ModelMatrixInverse * ViewMatrixInverse)\n");
}
if (builtins & GPU_VIEW_NORMAL) {
BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds, "\tvec3 n;\n");
- BLI_dynstr_append(ds, "\tworld_normals_get(n);\n");
- BLI_dynstr_append(ds, "\tvec3 facingnormal = transform_direction(ViewMatrix, n);\n");
+ BLI_dynstr_append(ds, " vec3 n;\n");
+ BLI_dynstr_append(ds, " world_normals_get(n);\n");
+ BLI_dynstr_append(ds, " vec3 facingnormal = transform_direction(ViewMatrix, n);\n");
BLI_dynstr_append(ds, "#else\n");
- BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing ? viewNormal: -viewNormal;\n");
+ BLI_dynstr_append(ds, " vec3 facingnormal = gl_FrontFacing ? viewNormal: -viewNormal;\n");
BLI_dynstr_append(ds, "#endif\n");
}
if (builtins & GPU_WORLD_NORMAL) {
- BLI_dynstr_append(ds, "\tvec3 facingwnormal;\n");
+ BLI_dynstr_append(ds, " vec3 facingwnormal;\n");
if (builtins & GPU_VIEW_NORMAL) {
BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds, "\tfacingwnormal = n;\n");
+ BLI_dynstr_append(ds, " facingwnormal = n;\n");
BLI_dynstr_append(ds, "#else\n");
- BLI_dynstr_append(ds, "\tworld_normals_get(facingwnormal);\n");
+ BLI_dynstr_append(ds, " world_normals_get(facingwnormal);\n");
BLI_dynstr_append(ds, "#endif\n");
}
else {
- BLI_dynstr_append(ds, "\tworld_normals_get(facingwnormal);\n");
+ BLI_dynstr_append(ds, " world_normals_get(facingwnormal);\n");
}
}
if (builtins & GPU_VIEW_POSITION) {
- BLI_dynstr_append(ds, "\t#define viewposition viewPosition\n");
+ BLI_dynstr_append(ds, " #define viewposition viewPosition\n");
}
codegen_declare_tmps(ds, graph);
@@ -610,21 +583,6 @@ static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph)
BLI_dynstr_append(ds, "}\n");
- /* XXX This cannot go into gpu_shader_material.glsl because main()
- * would be parsed and generate error */
- /* Old glsl mode compat. */
- /* TODO(fclem) This is only used by world shader now. get rid of it? */
- BLI_dynstr_append(ds, "#ifndef NODETREE_EXEC\n");
- BLI_dynstr_append(ds, "out vec4 fragColor;\n");
- BLI_dynstr_append(ds, "void main()\n");
- BLI_dynstr_append(ds, "{\n");
- BLI_dynstr_append(ds, "\tClosure cl = nodetree_exec();\n");
- BLI_dynstr_append(ds,
- "\tfragColor = vec4(cl.radiance, "
- "saturate(1.0 - avg(cl.transmittance)));\n");
- BLI_dynstr_append(ds, "}\n");
- BLI_dynstr_append(ds, "#endif\n\n");
-
/* create shader */
code = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
@@ -649,6 +607,8 @@ static const char *attr_prefix_get(CustomDataType type)
return "t";
case CD_MCOL:
return "c";
+ case CD_PROP_COLOR:
+ return "c";
case CD_AUTO_FROM_NAME:
return "a";
default:
@@ -657,23 +617,48 @@ static const char *attr_prefix_get(CustomDataType type)
}
}
-static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bool use_geom)
+/* We talk about shader stage interface, not to be mistaken with GPUShaderInterface. */
+static char *code_generate_interface(GPUNodeGraph *graph, int builtins)
{
+ if (BLI_listbase_is_empty(&graph->attributes) &&
+ (builtins & (GPU_BARYCENTRIC_DIST | GPU_BARYCENTRIC_TEXCO)) == 0) {
+ return NULL;
+ }
+
DynStr *ds = BLI_dynstr_new();
- GPUNode *node;
- GPUInput *input;
- char *code;
- int builtins = 0;
- /* Hairs uv and col attributes are passed by bufferTextures. */
- BLI_dynstr_append(ds,
- "#ifdef HAIR_SHADER\n"
- "#define DEFINE_ATTR(type, attr) uniform samplerBuffer attr\n"
- "#else\n"
- "#define DEFINE_ATTR(type, attr) in type attr\n"
- "#endif\n");
+ BLI_dynstr_append(ds, "\n");
LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
+ BLI_dynstr_appendf(ds, "%s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ }
+ if (builtins & GPU_BARYCENTRIC_TEXCO) {
+ BLI_dynstr_append(ds, "vec2 barycentricTexCo;\n");
+ }
+ if (builtins & GPU_BARYCENTRIC_DIST) {
+ BLI_dynstr_append(ds, "vec3 barycentricDist;\n");
+ }
+
+ char *code = BLI_dynstr_get_cstring(ds);
+
+ BLI_dynstr_free(ds);
+
+ return code;
+}
+
+static char *code_generate_vertex(GPUNodeGraph *graph,
+ const char *interface_str,
+ const char *vert_code,
+ int builtins)
+{
+ DynStr *ds = BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, datatoc_gpu_shader_codegen_lib_glsl);
+
+ /* Inputs */
+ LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
+ const char *type_str = gpu_data_type_to_string(attr->gputype);
+ const char *prefix = attr_prefix_get(attr->type);
/* XXX FIXME : see notes in mesh_render_data_create() */
/* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
if (attr->type == CD_ORCO) {
@@ -682,188 +667,58 @@ static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bo
BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n");
}
else if (attr->name[0] == '\0') {
- BLI_dynstr_appendf(ds,
- "DEFINE_ATTR(%s, %s);\n",
- gpu_data_type_to_string(attr->gputype),
- attr_prefix_get(attr->type));
- BLI_dynstr_appendf(ds, "#define att%d %s\n", attr->id, attr_prefix_get(attr->type));
+ BLI_dynstr_appendf(ds, "DEFINE_ATTR(%s, %s);\n", type_str, prefix);
+ BLI_dynstr_appendf(ds, "#define att%d %s\n", attr->id, prefix);
}
else {
char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
GPU_vertformat_safe_attr_name(attr->name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
- BLI_dynstr_appendf(ds,
- "DEFINE_ATTR(%s, %s%s);\n",
- gpu_data_type_to_string(attr->gputype),
- attr_prefix_get(attr->type),
- attr_safe_name);
- BLI_dynstr_appendf(
- ds, "#define att%d %s%s\n", attr->id, attr_prefix_get(attr->type), attr_safe_name);
+ BLI_dynstr_appendf(ds, "DEFINE_ATTR(%s, %s%s);\n", type_str, prefix, attr_safe_name);
+ BLI_dynstr_appendf(ds, "#define att%d %s%s\n", attr->id, prefix, attr_safe_name);
}
- BLI_dynstr_appendf(ds,
- "out %s var%d%s;\n",
- gpu_data_type_to_string(attr->gputype),
- attr->id,
- use_geom ? "g" : "");
}
- for (node = graph->nodes.first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_BUILTIN) {
- builtins |= input->builtin;
- }
- }
+ /* Outputs interface */
+ if (interface_str) {
+ BLI_dynstr_appendf(ds, "out codegenInterface {%s};\n\n", interface_str);
}
- if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_appendf(ds, "out vec2 barycentricTexCo%s;\n", use_geom ? "g" : "");
- BLI_dynstr_append(ds, "#endif\n");
- }
-
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "out vec3 barycentricPosg;\n");
- }
-
- BLI_dynstr_append(ds, "\n#define USE_ATTR\n");
-
- /* Prototype, defined later (this is because of matrices definition). */
- BLI_dynstr_append(ds, "void pass_attr(in vec3 position);\n");
-
- BLI_dynstr_append(ds, "\n");
-
- if (use_geom) {
- /* XXX HACK: Eevee specific. */
- char *vert_new, *vert_new2;
- vert_new = BLI_str_replaceN(vert_code, "worldPosition", "worldPositiong");
- vert_new2 = vert_new;
- vert_new = BLI_str_replaceN(vert_new2, "viewPosition", "viewPositiong");
- MEM_freeN(vert_new2);
- vert_new2 = vert_new;
- vert_new = BLI_str_replaceN(vert_new2, "worldNormal", "worldNormalg");
- MEM_freeN(vert_new2);
- vert_new2 = vert_new;
- vert_new = BLI_str_replaceN(vert_new2, "viewNormal", "viewNormalg");
- MEM_freeN(vert_new2);
-
- BLI_dynstr_append(ds, vert_new);
-
- MEM_freeN(vert_new);
- }
- else {
- BLI_dynstr_append(ds, vert_code);
- }
+ /* Prototype. Needed for hair functions. */
+ BLI_dynstr_append(ds, "void pass_attr(vec3 position, mat3 normalmat, mat4 modelmatinv);\n");
+ BLI_dynstr_append(ds, "#define USE_ATTR\n\n");
+ BLI_dynstr_append(ds, vert_code);
BLI_dynstr_append(ds, "\n");
- BLI_dynstr_append(ds, use_geom ? "RESOURCE_ID_VARYING_GEOM\n" : "RESOURCE_ID_VARYING\n");
-
- /* Prototype because defined later. */
- BLI_dynstr_append(ds,
- "vec2 hair_get_customdata_vec2(const samplerBuffer);\n"
- "vec3 hair_get_customdata_vec3(const samplerBuffer);\n"
- "vec4 hair_get_customdata_vec4(const samplerBuffer);\n"
- "vec3 hair_get_strand_pos(void);\n"
- "int hair_get_base_id(void);\n"
- "\n");
-
- BLI_dynstr_append(ds, "void pass_attr(in vec3 position) {\n");
-
- BLI_dynstr_append(ds, use_geom ? "\tPASS_RESOURCE_ID_GEOM\n" : "\tPASS_RESOURCE_ID\n");
-
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
-
- if (builtins & GPU_BARYCENTRIC_TEXCO) {
- /* To match cycles without breaking into individual segment we encode if we need to invert
- * the first component into the second component. We invert if the barycentricTexCo.y
- * is NOT 0.0 or 1.0. */
- BLI_dynstr_append(ds, "\tint _base_id = hair_get_base_id();\n");
- BLI_dynstr_appendf(
- ds, "\tbarycentricTexCo%s.x = float((_base_id %% 2) == 1);\n", use_geom ? "g" : "");
- BLI_dynstr_appendf(
- ds, "\tbarycentricTexCo%s.y = float(((_base_id %% 4) %% 3) > 0);\n", use_geom ? "g" : "");
- }
-
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "\tbarycentricPosg = position;\n");
- }
-
- LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
- if (attr->type == CD_TANGENT) {
- /* Not supported by hairs */
- BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", attr->id, use_geom ? "g" : "");
- }
- else if (attr->type == CD_ORCO) {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * "
- "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n",
- attr->id,
- use_geom ? "g" : "");
- /* TODO: fix ORCO with modifiers. */
- }
- else {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = hair_get_customdata_%s(att%d);\n",
- attr->id,
- use_geom ? "g" : "",
- gpu_data_type_to_string(attr->gputype),
- attr->id);
- }
- }
-
- BLI_dynstr_append(ds, "#else /* MESH_SHADER */\n");
+ BLI_dynstr_append(ds, "void pass_attr(vec3 position, mat3 normalmat, mat4 modelmatinv) {\n");
/* GPU_BARYCENTRIC_TEXCO cannot be computed based on gl_VertexID
* for MESH_SHADER because of indexed drawing. In this case a
* geometry shader is needed. */
-
+ if (builtins & GPU_BARYCENTRIC_TEXCO) {
+ BLI_dynstr_appendf(ds, " barycentricTexCo = barycentric_get();\n");
+ }
if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "\tbarycentricPosg = (ModelMatrix * vec4(position, 1.0)).xyz;\n");
+ BLI_dynstr_appendf(ds, " barycentricDist = vec3(0);\n");
}
LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
if (attr->type == CD_TANGENT) { /* silly exception */
- BLI_dynstr_appendf(ds,
- "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n",
- attr->id,
- use_geom ? "g" : "",
- attr->id);
- BLI_dynstr_appendf(ds, "\tvar%d%s.w = att%d.w;\n", attr->id, use_geom ? "g" : "", attr->id);
- /* Normalize only if vector is not null. */
- BLI_dynstr_appendf(ds,
- "\tfloat lvar%d = dot(var%d%s.xyz, var%d%s.xyz);\n",
- attr->id,
- attr->id,
- use_geom ? "g" : "",
- attr->id,
- use_geom ? "g" : "");
- BLI_dynstr_appendf(ds,
- "\tvar%d%s.xyz *= (lvar%d > 0.0) ? inversesqrt(lvar%d) : 1.0;\n",
- attr->id,
- use_geom ? "g" : "",
- attr->id,
- attr->id);
+ BLI_dynstr_appendf(ds, " var%d = tangent_get(att%d, normalmat);\n", attr->id, attr->id);
}
else if (attr->type == CD_ORCO) {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = OrcoTexCoFactors[0].xyz + position *"
- " OrcoTexCoFactors[1].xyz;\n",
- attr->id,
- use_geom ? "g" : "");
- /* See mesh_create_loop_orco() for explanation. */
- BLI_dynstr_appendf(ds,
- "\tif (orco.w == 0.0) { var%d%s = orco.xyz * 0.5 + 0.5; }\n",
- attr->id,
- use_geom ? "g" : "");
+ BLI_dynstr_appendf(
+ ds, " var%d = orco_get(position, modelmatinv, OrcoTexCoFactors, orco);\n", attr->id);
}
else {
- BLI_dynstr_appendf(ds, "\tvar%d%s = att%d;\n", attr->id, use_geom ? "g" : "", attr->id);
+ const char *type_str = gpu_data_type_to_string(attr->gputype);
+ BLI_dynstr_appendf(ds, " var%d = GET_ATTR(%s, att%d);\n", attr->id, type_str, attr->id);
}
}
- BLI_dynstr_append(ds, "#endif /* HAIR_SHADER */\n");
BLI_dynstr_append(ds, "}\n");
- code = BLI_dynstr_get_cstring(ds);
+ char *code = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
@@ -877,146 +732,46 @@ static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bo
}
static char *code_generate_geometry(GPUNodeGraph *graph,
+ const char *interface_str,
const char *geom_code,
- const char *defines)
+ int builtins)
{
- DynStr *ds = BLI_dynstr_new();
- GPUNode *node;
- GPUInput *input;
- char *code;
- int builtins = 0;
-
- /* XXX we should not make specific eevee cases here. */
- bool is_hair_shader = (strstr(defines, "HAIR_SHADER") != NULL);
-
- /* Create prototype because attributes cannot be declared before layout. */
- BLI_dynstr_append(ds, "void pass_attr(in int vert);\n");
- BLI_dynstr_append(ds, "void calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2);\n");
- BLI_dynstr_append(ds, "#define USE_ATTR\n");
-
- /* Generate varying declarations. */
- for (node = graph->nodes.first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_BUILTIN) {
- builtins |= input->builtin;
- }
- }
- }
-
- LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
- BLI_dynstr_appendf(ds, "in %s var%dg[];\n", gpu_data_type_to_string(attr->gputype), attr->id);
- BLI_dynstr_appendf(ds, "out %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ if (!geom_code) {
+ return NULL;
}
- if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds, "in vec2 barycentricTexCog[];\n");
- BLI_dynstr_append(ds, "#endif\n");
-
- BLI_dynstr_append(ds, "out vec2 barycentricTexCo;\n");
- }
+ DynStr *ds = BLI_dynstr_new();
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "in vec3 barycentricPosg[];\n");
- BLI_dynstr_append(ds, "flat out vec3 barycentricDist;\n");
+ /* Attributes, Shader interface; */
+ if (interface_str) {
+ BLI_dynstr_appendf(ds, "in codegenInterface {%s} dataAttrIn[];\n\n", interface_str);
+ BLI_dynstr_appendf(ds, "out codegenInterface {%s} dataAttrOut;\n\n", interface_str);
}
- if (geom_code == NULL) {
- /* Force geometry usage if GPU_BARYCENTRIC_DIST or GPU_BARYCENTRIC_TEXCO are used.
- * Note: GPU_BARYCENTRIC_TEXCO only requires it if the shader is not drawing hairs. */
- if ((builtins & (GPU_BARYCENTRIC_DIST | GPU_BARYCENTRIC_TEXCO)) == 0 || is_hair_shader) {
- /* Early out */
- BLI_dynstr_free(ds);
- return NULL;
- }
- else {
- /* Force geom shader usage */
- /* TODO put in external file. */
- BLI_dynstr_append(ds, "layout(triangles) in;\n");
- BLI_dynstr_append(ds, "layout(triangle_strip, max_vertices=3) out;\n");
-
- BLI_dynstr_append(ds, "in vec3 worldPositiong[];\n");
- BLI_dynstr_append(ds, "in vec3 viewPositiong[];\n");
- BLI_dynstr_append(ds, "in vec3 worldNormalg[];\n");
- BLI_dynstr_append(ds, "in vec3 viewNormalg[];\n");
-
- BLI_dynstr_append(ds, "out vec3 worldPosition;\n");
- BLI_dynstr_append(ds, "out vec3 viewPosition;\n");
- BLI_dynstr_append(ds, "out vec3 worldNormal;\n");
- BLI_dynstr_append(ds, "out vec3 viewNormal;\n");
-
- BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
-
- BLI_dynstr_append(ds, "void main(){\n");
-
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds,
- "\tcalc_barycentric_distances(barycentricPosg[0], barycentricPosg[1], "
- "barycentricPosg[2]);\n");
- }
-
- for (int i = 0; i < 3; i++) {
- BLI_dynstr_appendf(ds, "\tgl_Position = gl_in[%d].gl_Position;\n", i);
- BLI_dynstr_appendf(ds, "\tgl_ClipDistance[0] = gl_in[%d].gl_ClipDistance[0];\n", i);
- BLI_dynstr_appendf(ds, "\tpass_attr(%d);\n", i);
- BLI_dynstr_append(ds, "\tEmitVertex();\n");
- }
- BLI_dynstr_append(ds, "}\n");
- }
- }
- else {
- BLI_dynstr_append(ds, geom_code);
- }
+ BLI_dynstr_append(ds, datatoc_gpu_shader_codegen_lib_glsl);
if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "void calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2) {\n");
- BLI_dynstr_append(ds, "\tvec3 edge21 = pos2 - pos1;\n");
- BLI_dynstr_append(ds, "\tvec3 edge10 = pos1 - pos0;\n");
- BLI_dynstr_append(ds, "\tvec3 edge02 = pos0 - pos2;\n");
- BLI_dynstr_append(ds, "\tvec3 d21 = normalize(edge21);\n");
- BLI_dynstr_append(ds, "\tvec3 d10 = normalize(edge10);\n");
- BLI_dynstr_append(ds, "\tvec3 d02 = normalize(edge02);\n");
-
- BLI_dynstr_append(ds, "\tfloat d = dot(d21, edge02);\n");
- BLI_dynstr_append(ds, "\tbarycentricDist.x = sqrt(dot(edge02, edge02) - d * d);\n");
- BLI_dynstr_append(ds, "\td = dot(d02, edge10);\n");
- BLI_dynstr_append(ds, "\tbarycentricDist.y = sqrt(dot(edge10, edge10) - d * d);\n");
- BLI_dynstr_append(ds, "\td = dot(d10, edge21);\n");
- BLI_dynstr_append(ds, "\tbarycentricDist.z = sqrt(dot(edge21, edge21) - d * d);\n");
- BLI_dynstr_append(ds, "}\n");
+ /* geom_code should do something with this, but may not. */
+ BLI_dynstr_append(ds, "#define DO_BARYCENTRIC_DISTANCES\n");
}
- BLI_dynstr_append(ds, "RESOURCE_ID_VARYING\n");
-
/* Generate varying assignments. */
- BLI_dynstr_append(ds, "void pass_attr(in int vert) {\n");
-
- BLI_dynstr_append(ds, "\tPASS_RESOURCE_ID(vert)\n");
-
- /* XXX HACK: Eevee specific. */
- if (geom_code == NULL) {
- BLI_dynstr_append(ds, "\tworldPosition = worldPositiong[vert];\n");
- BLI_dynstr_append(ds, "\tviewPosition = viewPositiong[vert];\n");
- BLI_dynstr_append(ds, "\tworldNormal = worldNormalg[vert];\n");
- BLI_dynstr_append(ds, "\tviewNormal = viewNormalg[vert];\n");
- }
+ BLI_dynstr_append(ds, "#define USE_ATTR\n");
+ BLI_dynstr_append(ds, "void pass_attr(const int vert) {\n");
if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds, "\tbarycentricTexCo = barycentricTexCog[vert];\n");
- BLI_dynstr_append(ds, "#else\n");
- BLI_dynstr_append(ds, "\tbarycentricTexCo.x = float((vert % 3) == 0);\n");
- BLI_dynstr_append(ds, "\tbarycentricTexCo.y = float((vert % 3) == 1);\n");
- BLI_dynstr_append(ds, "#endif\n");
+ BLI_dynstr_append(ds, " dataAttrOut.barycentricTexCo = calc_barycentric_co(vert);\n");
}
LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
/* TODO let shader choose what to do depending on what the attribute is. */
- BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", attr->id, attr->id);
+ BLI_dynstr_appendf(ds, " dataAttrOut.var%d = dataAttrIn[vert].var%d;\n", attr->id, attr->id);
}
- BLI_dynstr_append(ds, "}\n");
+ BLI_dynstr_append(ds, "}\n\n");
- code = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_append(ds, geom_code);
+
+ char *code = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
return code;
@@ -1046,8 +801,17 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
* generated VBOs are ready to accept the future shader. */
gpu_node_graph_prune_unused(graph);
+ int builtins = 0;
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
+ LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
+ if (input->source == GPU_SOURCE_BUILTIN) {
+ builtins |= input->builtin;
+ }
+ }
+ }
/* generate code */
- char *fragmentgen = code_generate_fragment(material, graph);
+ char *interface_str = code_generate_interface(graph, builtins);
+ char *fragmentgen = code_generate_fragment(material, graph, interface_str);
/* Cache lookup: Reuse shaders already compiled */
uint32_t hash = gpu_pass_hash(fragmentgen, defines, &graph->attributes);
@@ -1055,6 +819,7 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
if (pass_hash && (pass_hash->next == NULL || pass_hash->next->hash != hash)) {
/* No collision, just return the pass. */
+ MEM_SAFE_FREE(interface_str);
MEM_freeN(fragmentgen);
if (!gpu_pass_is_valid(pass_hash)) {
/* Shader has already been created but failed to compile. */
@@ -1069,10 +834,11 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
GSet *used_libraries = gpu_material_used_libraries(material);
char *tmp = gpu_material_library_generate_code(used_libraries, frag_lib);
- char *geometrycode = code_generate_geometry(graph, geom_code, defines);
- char *vertexcode = code_generate_vertex(graph, vert_code, (geometrycode != NULL));
+ char *geometrycode = code_generate_geometry(graph, interface_str, geom_code, builtins);
+ char *vertexcode = code_generate_vertex(graph, interface_str, vert_code, builtins);
char *fragmentcode = BLI_strdupcat(tmp, fragmentgen);
+ MEM_SAFE_FREE(interface_str);
MEM_freeN(fragmentgen);
MEM_freeN(tmp);
@@ -1226,21 +992,9 @@ bool GPU_pass_compile(GPUPass *pass, const char *shname)
shader = NULL;
}
}
- else if (!BLI_thread_is_main() && GPU_context_local_shaders_workaround()) {
- pass->binary.content = GPU_shader_get_binary(
- shader, &pass->binary.format, &pass->binary.len);
- GPU_shader_free(shader);
- shader = NULL;
- }
-
pass->shader = shader;
pass->compiled = true;
}
- else if (pass->binary.content && BLI_thread_is_main()) {
- pass->shader = GPU_shader_load_from_binary(
- pass->binary.content, pass->binary.format, pass->binary.len, shname);
- MEM_SAFE_FREE(pass->binary.content);
- }
return success;
}
@@ -1261,9 +1015,6 @@ static void gpu_pass_free(GPUPass *pass)
MEM_SAFE_FREE(pass->geometrycode);
MEM_SAFE_FREE(pass->vertexcode);
MEM_SAFE_FREE(pass->defines);
- if (pass->binary.content) {
- MEM_freeN(pass->binary.content);
- }
MEM_freeN(pass);
}
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index ce20f495ba3..5d130d75d2c 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -23,8 +23,11 @@
* Generate shader code from the intermediate node graph.
*/
-#ifndef __GPU_CODEGEN_H__
-#define __GPU_CODEGEN_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
struct GPUMaterial;
struct GPUNodeGraph;
@@ -43,11 +46,6 @@ typedef struct GPUPass {
char *defines;
uint refcount; /* Orphaned GPUPasses gets freed by the garbage collector. */
uint32_t hash; /* Identity hash generated from all GLSL code. */
- struct {
- char *content;
- uint format;
- int len;
- } binary;
bool compiled; /* Did we already tried to compile the attached GPUShader. */
} GPUPass;
@@ -68,4 +66,6 @@ void GPU_pass_release(GPUPass *pass);
void gpu_codegen_init(void);
void gpu_codegen_exit(void);
-#endif /* __GPU_CODEGEN_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cc
index 0b9104e5349..e6356580ea3 100644
--- a/source/blender/gpu/intern/gpu_context.cpp
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -62,6 +62,7 @@ static std::vector<GLuint> orphaned_buffer_ids;
static std::vector<GLuint> orphaned_texture_ids;
static std::mutex orphans_mutex;
+static std::mutex main_context_mutex;
struct GPUContext {
GLuint default_vao;
@@ -345,3 +346,13 @@ struct GPUMatrixState *gpu_context_active_matrix_state_get()
BLI_assert(active_ctx);
return active_ctx->matrix_state;
}
+
+void GPU_context_main_lock(void)
+{
+ main_context_mutex.lock();
+}
+
+void GPU_context_main_unlock(void)
+{
+ main_context_mutex.unlock();
+}
diff --git a/source/blender/gpu/intern/gpu_context_private.h b/source/blender/gpu/intern/gpu_context_private.h
index f64cdf439a1..08fbefe3b3f 100644
--- a/source/blender/gpu/intern/gpu_context_private.h
+++ b/source/blender/gpu/intern/gpu_context_private.h
@@ -23,8 +23,7 @@
* This interface allow GPU to manage GL objects for multiple context and threads.
*/
-#ifndef __GPU_CONTEXT_PRIVATE_H__
-#define __GPU_CONTEXT_PRIVATE_H__
+#pragma once
#include "GPU_context.h"
@@ -64,5 +63,3 @@ struct GPUMatrixState *gpu_context_active_matrix_state_get(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_CONTEXT_PRIVATE_H__ */
diff --git a/source/blender/gpu/intern/gpu_debug.c b/source/blender/gpu/intern/gpu_debug.cc
index f7d6236071d..f7d6236071d 100644
--- a/source/blender/gpu/intern/gpu_debug.c
+++ b/source/blender/gpu/intern/gpu_debug.cc
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
deleted file mode 100644
index f07e3ed70d7..00000000000
--- a/source/blender/gpu/intern/gpu_draw.c
+++ /dev/null
@@ -1,1464 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup gpu
- *
- * Utility functions for dealing with OpenGL texture & material context,
- * mipmap generation and light objects.
- *
- * These are some obscure rendering functions shared between the game engine (not anymore)
- * and the blender, in this module to avoid duplication
- * and abstract them away from the rest a bit.
- */
-
-#include <string.h>
-
-#include "BLI_blenlib.h"
-#include "BLI_boxpack_2d.h"
-#include "BLI_linklist.h"
-#include "BLI_math.h"
-#include "BLI_threads.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_image_types.h"
-#include "DNA_movieclip_types.h"
-#include "DNA_userdef_types.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "IMB_colormanagement.h"
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
-
-#include "BKE_global.h"
-#include "BKE_image.h"
-#include "BKE_main.h"
-#include "BKE_movieclip.h"
-
-#include "GPU_draw.h"
-#include "GPU_extensions.h"
-#include "GPU_glew.h"
-#include "GPU_platform.h"
-#include "GPU_texture.h"
-
-#include "PIL_time.h"
-
-static void gpu_free_image(Image *ima, const bool immediate);
-static void gpu_free_unused_buffers(void);
-
-//* Checking powers of two for images since OpenGL ES requires it */
-#ifdef WITH_DDS
-static bool is_power_of_2_resolution(int w, int h)
-{
- return is_power_of_2_i(w) && is_power_of_2_i(h);
-}
-#endif
-
-static bool is_over_resolution_limit(GLenum textarget, int w, int h)
-{
- int size = (textarget == GL_TEXTURE_CUBE_MAP) ? GPU_max_cube_map_size() : GPU_max_texture_size();
- int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size;
-
- return (w > reslimit || h > reslimit);
-}
-
-static int smaller_power_of_2_limit(int num)
-{
- int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, GPU_max_texture_size()) :
- GPU_max_texture_size();
- /* take texture clamping into account */
- if (num > reslimit) {
- return reslimit;
- }
-
- return power_of_2_min_i(num);
-}
-
-/* Current OpenGL state caching for GPU_set_tpage */
-
-static struct GPUTextureState {
- /* also controls min/mag filtering */
- bool domipmap;
- /* only use when 'domipmap' is set */
- bool linearmipmap;
- /* store this so that new images created while texture painting won't be set to mipmapped */
- bool texpaint;
-
- float anisotropic;
-} GTS = {1, 0, 0, 1.0f};
-
-/* Mipmap settings */
-
-void GPU_set_mipmap(Main *bmain, bool mipmap)
-{
- if (GTS.domipmap != mipmap) {
- GPU_free_images(bmain);
- GTS.domipmap = mipmap;
- }
-}
-
-void GPU_set_linear_mipmap(bool linear)
-{
- if (GTS.linearmipmap != linear) {
- GTS.linearmipmap = linear;
- }
-}
-
-bool GPU_get_mipmap(void)
-{
- return GTS.domipmap && !GTS.texpaint;
-}
-
-bool GPU_get_linear_mipmap(void)
-{
- return GTS.linearmipmap;
-}
-
-static GLenum gpu_get_mipmap_filter(bool mag)
-{
- /* linearmipmap is off by default *when mipmapping is off,
- * use unfiltered display */
- if (mag) {
- if (GTS.domipmap) {
- return GL_LINEAR;
- }
- else {
- return GL_NEAREST;
- }
- }
- else {
- if (GTS.domipmap) {
- if (GTS.linearmipmap) {
- return GL_LINEAR_MIPMAP_LINEAR;
- }
- else {
- return GL_LINEAR_MIPMAP_NEAREST;
- }
- }
- else {
- return GL_NEAREST;
- }
- }
-}
-
-/* Anisotropic filtering settings */
-void GPU_set_anisotropic(float value)
-{
- if (GTS.anisotropic != value) {
- GPU_samplers_free();
-
- /* Clamp value to the maximum value the graphics card supports */
- const float max = GPU_max_texture_anisotropy();
- if (value > max) {
- value = max;
- }
-
- GTS.anisotropic = value;
-
- GPU_samplers_init();
- }
-}
-
-float GPU_get_anisotropic(void)
-{
- return GTS.anisotropic;
-}
-
-/* Set OpenGL state for an MTFace */
-
-static GPUTexture **gpu_get_image_gputexture(Image *ima, GLenum textarget, const int multiview_eye)
-{
- if (textarget == GL_TEXTURE_2D) {
- return &(ima->gputexture[TEXTARGET_TEXTURE_2D][multiview_eye]);
- }
- else if (textarget == GL_TEXTURE_CUBE_MAP) {
- return &(ima->gputexture[TEXTARGET_TEXTURE_CUBE_MAP][multiview_eye]);
- }
- else if (textarget == GL_TEXTURE_2D_ARRAY) {
- return &(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][multiview_eye]);
- }
- else if (textarget == GL_TEXTURE_1D_ARRAY) {
- return &(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][multiview_eye]);
- }
-
- return NULL;
-}
-
-static uint gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye)
-{
- GPUTexture *tilearray = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][multiview_eye];
-
- if (tilearray == NULL) {
- return 0;
- }
-
- float array_w = GPU_texture_width(tilearray);
- float array_h = GPU_texture_height(tilearray);
-
- ImageTile *last_tile = ima->tiles.last;
- /* Tiles are sorted by number. */
- int max_tile = last_tile->tile_number - 1001;
-
- /* create image */
- int bindcode;
- glGenTextures(1, (GLuint *)&bindcode);
- glBindTexture(GL_TEXTURE_1D_ARRAY, bindcode);
-
- int width = max_tile + 1;
- float *data = MEM_callocN(width * 8 * sizeof(float), __func__);
- for (int i = 0; i < width; i++) {
- data[4 * i] = -1.0f;
- }
- LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
- int i = tile->tile_number - 1001;
- data[4 * i] = tile->runtime.tilearray_layer;
-
- float *tile_info = &data[4 * width + 4 * i];
- tile_info[0] = tile->runtime.tilearray_offset[0] / array_w;
- tile_info[1] = tile->runtime.tilearray_offset[1] / array_h;
- tile_info[2] = tile->runtime.tilearray_size[0] / array_w;
- tile_info[3] = tile->runtime.tilearray_size[1] / array_h;
- }
-
- glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA32F, width, 2, 0, GL_RGBA, GL_FLOAT, data);
- MEM_freeN(data);
-
- glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glBindTexture(GL_TEXTURE_1D_ARRAY, 0);
-
- return bindcode;
-}
-
-typedef struct PackTile {
- FixedSizeBoxPack boxpack;
- ImageTile *tile;
- float pack_score;
-} PackTile;
-
-static int compare_packtile(const void *a, const void *b)
-{
- const PackTile *tile_a = a;
- const PackTile *tile_b = b;
-
- return tile_a->pack_score < tile_b->pack_score;
-}
-
-static uint gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
-{
- int arraywidth = 0, arrayheight = 0;
-
- ListBase boxes = {NULL};
-
- LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
- ImageUser iuser;
- BKE_imageuser_default(&iuser);
- iuser.tile = tile->tile_number;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
-
- if (ibuf) {
- PackTile *packtile = MEM_callocN(sizeof(PackTile), __func__);
- packtile->tile = tile;
- packtile->boxpack.w = ibuf->x;
- packtile->boxpack.h = ibuf->y;
-
- if (is_over_resolution_limit(
- GL_TEXTURE_2D_ARRAY, packtile->boxpack.w, packtile->boxpack.h)) {
- packtile->boxpack.w = smaller_power_of_2_limit(packtile->boxpack.w);
- packtile->boxpack.h = smaller_power_of_2_limit(packtile->boxpack.h);
- }
- arraywidth = max_ii(arraywidth, packtile->boxpack.w);
- arrayheight = max_ii(arrayheight, packtile->boxpack.h);
-
- /* We sort the tiles by decreasing size, with an additional penalty term
- * for high aspect ratios. This improves packing efficiency. */
- float w = packtile->boxpack.w, h = packtile->boxpack.h;
- packtile->pack_score = max_ff(w, h) / min_ff(w, h) * w * h;
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- BLI_addtail(&boxes, packtile);
- }
- }
-
- BLI_assert(arraywidth > 0 && arrayheight > 0);
-
- BLI_listbase_sort(&boxes, compare_packtile);
- int arraylayers = 0;
- /* Keep adding layers until all tiles are packed. */
- while (boxes.first != NULL) {
- ListBase packed = {NULL};
- BLI_box_pack_2d_fixedarea(&boxes, arraywidth, arrayheight, &packed);
- BLI_assert(packed.first != NULL);
-
- LISTBASE_FOREACH (PackTile *, packtile, &packed) {
- ImageTile *tile = packtile->tile;
- int *tileoffset = tile->runtime.tilearray_offset;
- int *tilesize = tile->runtime.tilearray_size;
-
- tileoffset[0] = packtile->boxpack.x;
- tileoffset[1] = packtile->boxpack.y;
- tilesize[0] = packtile->boxpack.w;
- tilesize[1] = packtile->boxpack.h;
- tile->runtime.tilearray_layer = arraylayers;
- }
-
- BLI_freelistN(&packed);
- arraylayers++;
- }
-
- /* create image */
- int bindcode;
- glGenTextures(1, (GLuint *)&bindcode);
- glBindTexture(GL_TEXTURE_2D_ARRAY, bindcode);
-
- GLenum data_type, internal_format;
- if (main_ibuf->rect_float) {
- data_type = GL_FLOAT;
- internal_format = (!(main_ibuf->flags & IB_halffloat) && (ima->flag & IMA_HIGH_BITDEPTH)) ?
- GL_RGBA32F :
- GL_RGBA16F;
- }
- else {
- data_type = GL_UNSIGNED_BYTE;
- internal_format = GL_RGBA8;
- if (!IMB_colormanagement_space_is_data(main_ibuf->rect_colorspace) &&
- !IMB_colormanagement_space_is_scene_linear(main_ibuf->rect_colorspace)) {
- internal_format = GL_SRGB8_ALPHA8;
- }
- }
-
- glTexImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- internal_format,
- arraywidth,
- arrayheight,
- arraylayers,
- 0,
- GL_RGBA,
- data_type,
- NULL);
-
- LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
- int tilelayer = tile->runtime.tilearray_layer;
- int *tileoffset = tile->runtime.tilearray_offset;
- int *tilesize = tile->runtime.tilearray_size;
-
- if (tilesize[0] == 0 || tilesize[1] == 0) {
- continue;
- }
-
- ImageUser iuser;
- BKE_imageuser_default(&iuser);
- iuser.tile = tile->tile_number;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
-
- if (ibuf) {
- bool needs_scale = (ibuf->x != tilesize[0] || ibuf->y != tilesize[1]);
-
- ImBuf *scale_ibuf = NULL;
- if (ibuf->rect_float) {
- float *rect_float = ibuf->rect_float;
-
- const bool store_premultiplied = ima->alpha_mode != IMA_ALPHA_STRAIGHT;
- if (ibuf->channels != 4 || !store_premultiplied) {
- rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__);
- IMB_colormanagement_imbuf_to_float_texture(
- rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied);
- }
-
- float *pixeldata = rect_float;
- if (needs_scale) {
- scale_ibuf = IMB_allocFromBuffer(NULL, rect_float, ibuf->x, ibuf->y, 4);
- IMB_scaleImBuf(scale_ibuf, tilesize[0], tilesize[1]);
- pixeldata = scale_ibuf->rect_float;
- }
-
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- tileoffset[0],
- tileoffset[1],
- tilelayer,
- tilesize[0],
- tilesize[1],
- 1,
- GL_RGBA,
- GL_FLOAT,
- pixeldata);
-
- if (rect_float != ibuf->rect_float) {
- MEM_freeN(rect_float);
- }
- }
- else {
- unsigned int *rect = ibuf->rect;
-
- if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
- rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__);
- IMB_colormanagement_imbuf_to_byte_texture((uchar *)rect,
- 0,
- 0,
- ibuf->x,
- ibuf->y,
- ibuf,
- internal_format == GL_SRGB8_ALPHA8,
- ima->alpha_mode == IMA_ALPHA_PREMUL);
- }
-
- unsigned int *pixeldata = rect;
- if (needs_scale) {
- scale_ibuf = IMB_allocFromBuffer(rect, NULL, ibuf->x, ibuf->y, 4);
- IMB_scaleImBuf(scale_ibuf, tilesize[0], tilesize[1]);
- pixeldata = scale_ibuf->rect;
- }
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- tileoffset[0],
- tileoffset[1],
- tilelayer,
- tilesize[0],
- tilesize[1],
- 1,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- pixeldata);
-
- if (rect != ibuf->rect) {
- MEM_freeN(rect);
- }
- }
- if (scale_ibuf != NULL) {
- IMB_freeImBuf(scale_ibuf);
- }
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
-
- if (GPU_get_mipmap()) {
- glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
- if (ima) {
- ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
- }
- }
-
- glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
-
- return bindcode;
-}
-
-static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget)
-{
- uint bindcode = 0;
- const bool mipmap = GPU_get_mipmap();
- const bool half_float = (ibuf->flags & IB_halffloat) != 0;
-
-#ifdef WITH_DDS
- if (ibuf->ftype == IMB_FTYPE_DDS) {
- /* DDS is loaded directly in compressed form. */
- GPU_create_gl_tex_compressed(&bindcode, textarget, ima, ibuf);
- return bindcode;
- }
-#endif
-
- /* Regular uncompressed texture. */
- float *rect_float = ibuf->rect_float;
- uchar *rect = (uchar *)ibuf->rect;
- bool compress_as_srgb = false;
-
- if (rect_float == NULL) {
- /* Byte image is in original colorspace from the file. If the file is sRGB
- * scene linear, or non-color data no conversion is needed. Otherwise we
- * compress as scene linear + sRGB transfer function to avoid precision loss
- * in common cases.
- *
- * We must also convert to premultiplied for correct texture interpolation
- * and consistency with float images. */
- if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
- compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace);
-
- rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__);
- if (rect == NULL) {
- return bindcode;
- }
-
- /* Texture storage of images is defined by the alpha mode of the image. The
- * downside of this is that there can be artifacts near alpha edges. However,
- * this allows us to use sRGB texture formats and preserves color values in
- * zero alpha areas, and appears generally closer to what game engines that we
- * want to be compatible with do. */
- const bool store_premultiplied = ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true;
- IMB_colormanagement_imbuf_to_byte_texture(
- rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied);
- }
- }
- else {
- /* Float image is already in scene linear colorspace or non-color data by
- * convention, no colorspace conversion needed. But we do require 4 channels
- * currently. */
- const bool store_premultiplied = ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false;
-
- if (ibuf->channels != 4 || !store_premultiplied) {
- rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__);
- if (rect_float == NULL) {
- return bindcode;
- }
- IMB_colormanagement_imbuf_to_float_texture(
- rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied);
- }
- }
-
- /* Create OpenGL texture. */
- GPU_create_gl_tex(&bindcode,
- (uint *)rect,
- rect_float,
- ibuf->x,
- ibuf->y,
- textarget,
- mipmap,
- half_float,
- compress_as_srgb,
- ima);
-
- /* Free buffers if needed. */
- if (rect && rect != (uchar *)ibuf->rect) {
- MEM_freeN(rect);
- }
- if (rect_float && rect_float != ibuf->rect_float) {
- MEM_freeN(rect_float);
- }
-
- return bindcode;
-}
-
-static GPUTexture **gpu_get_movieclip_gputexture(MovieClip *clip,
- MovieClipUser *cuser,
- GLenum textarget)
-{
- MovieClip_RuntimeGPUTexture *tex;
- for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) {
- if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) {
- break;
- }
- }
-
- if (tex == NULL) {
- tex = MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture), __func__);
-
- for (int i = 0; i < TEXTARGET_COUNT; i++) {
- tex->gputexture[i] = NULL;
- }
-
- memcpy(&tex->user, cuser, sizeof(MovieClipUser));
- BLI_addtail(&clip->runtime.gputextures, tex);
- }
-
- if (textarget == GL_TEXTURE_2D) {
- return &tex->gputexture[TEXTARGET_TEXTURE_2D];
- }
- else if (textarget == GL_TEXTURE_CUBE_MAP) {
- return &tex->gputexture[TEXTARGET_TEXTURE_CUBE_MAP];
- }
-
- return NULL;
-}
-
-static ImBuf *update_do_scale(uchar *rect,
- float *rect_float,
- int *x,
- int *y,
- int *w,
- int *h,
- int limit_w,
- int limit_h,
- int full_w,
- int full_h)
-{
- /* Partial update with scaling. */
- float xratio = limit_w / (float)full_w;
- float yratio = limit_h / (float)full_h;
-
- int part_w = *w, part_h = *h;
-
- /* Find sub coordinates in scaled image. Take ceiling because we will be
- * losing 1 pixel due to rounding errors in x,y. */
- *x *= xratio;
- *y *= yratio;
- *w = (int)ceil(xratio * (*w));
- *h = (int)ceil(yratio * (*h));
-
- /* ...but take back if we are over the limit! */
- if (*x + *w > limit_w) {
- (*w)--;
- }
- if (*y + *h > limit_h) {
- (*h)--;
- }
-
- /* Scale pixels. */
- ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, part_w, part_h, 4);
- IMB_scaleImBuf(ibuf, *w, *h);
-
- return ibuf;
-}
-
-static void gpu_texture_update_scaled_array(uchar *rect,
- float *rect_float,
- int full_w,
- int full_h,
- int x,
- int y,
- int layer,
- const int *tile_offset,
- const int *tile_size,
- int w,
- int h)
-{
- ImBuf *ibuf = update_do_scale(
- rect, rect_float, &x, &y, &w, &h, tile_size[0], tile_size[1], full_w, full_h);
-
- /* Shift to account for tile packing. */
- x += tile_offset[0];
- y += tile_offset[1];
-
- if (ibuf->rect_float) {
- glTexSubImage3D(
- GL_TEXTURE_2D_ARRAY, 0, x, y, layer, w, h, 1, GL_RGBA, GL_FLOAT, ibuf->rect_float);
- }
- else {
- glTexSubImage3D(
- GL_TEXTURE_2D_ARRAY, 0, x, y, layer, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
- }
-
- IMB_freeImBuf(ibuf);
-}
-
-static void gpu_texture_update_scaled(
- uchar *rect, float *rect_float, int full_w, int full_h, int x, int y, int w, int h)
-{
- /* Partial update with scaling. */
- int limit_w = smaller_power_of_2_limit(full_w);
- int limit_h = smaller_power_of_2_limit(full_h);
-
- ImBuf *ibuf = update_do_scale(
- rect, rect_float, &x, &y, &w, &h, limit_w, limit_h, full_w, full_h);
-
- if (ibuf->rect_float) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, ibuf->rect_float);
- }
- else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
- }
-
- IMB_freeImBuf(ibuf);
-}
-
-static void gpu_texture_update_unscaled(uchar *rect,
- float *rect_float,
- int x,
- int y,
- int layer,
- int w,
- int h,
- GLint tex_stride,
- GLint tex_offset)
-{
- /* Partial update without scaling. Stride and offset are used to copy only a
- * subset of a possible larger buffer than what we are updating. */
- GLint row_length;
- glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, tex_stride);
-
- if (layer >= 0) {
- if (rect_float == NULL) {
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- x,
- y,
- layer,
- w,
- h,
- 1,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- rect + tex_offset);
- }
- else {
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- x,
- y,
- layer,
- w,
- h,
- 1,
- GL_RGBA,
- GL_FLOAT,
- rect_float + tex_offset);
- }
- }
- else {
- if (rect_float == NULL) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect + tex_offset);
- }
- else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, rect_float + tex_offset);
- }
- }
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
-}
-
-static void gpu_texture_update_from_ibuf(
- GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h)
-{
- /* Partial update of texture for texture painting. This is often much
- * quicker than fully updating the texture for high resolution images. */
- GPU_texture_bind(tex, 0);
-
- bool scaled;
- if (tile != NULL) {
- int *tilesize = tile->runtime.tilearray_size;
- scaled = (ibuf->x != tilesize[0]) || (ibuf->y != tilesize[1]);
- }
- else {
- scaled = is_over_resolution_limit(GL_TEXTURE_2D, ibuf->x, ibuf->y);
- }
-
- if (scaled) {
- /* Extra padding to account for bleed from neighboring pixels. */
- const int padding = 4;
- const int xmax = min_ii(x + w + padding, ibuf->x);
- const int ymax = min_ii(y + h + padding, ibuf->y);
- x = max_ii(x - padding, 0);
- y = max_ii(y - padding, 0);
- w = xmax - x;
- h = ymax - y;
- }
-
- /* Get texture data pointers. */
- float *rect_float = ibuf->rect_float;
- uchar *rect = (uchar *)ibuf->rect;
- GLint tex_stride = ibuf->x;
- GLint tex_offset = ibuf->channels * (y * ibuf->x + x);
-
- if (rect_float == NULL) {
- /* Byte pixels. */
- if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
- const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(
- ibuf->rect_colorspace);
-
- rect = MEM_mallocN(sizeof(uchar) * 4 * w * h, __func__);
- if (rect == NULL) {
- return;
- }
-
- tex_stride = w;
- tex_offset = 0;
-
- /* Convert to scene linear with sRGB compression, and premultiplied for
- * correct texture interpolation. */
- const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL);
- IMB_colormanagement_imbuf_to_byte_texture(
- rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied);
- }
- }
- else {
- /* Float pixels. */
- const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT);
-
- if (ibuf->channels != 4 || scaled || !store_premultiplied) {
- rect_float = MEM_mallocN(sizeof(float) * 4 * w * h, __func__);
- if (rect_float == NULL) {
- return;
- }
-
- tex_stride = w;
- tex_offset = 0;
-
- IMB_colormanagement_imbuf_to_float_texture(
- rect_float, x, y, w, h, ibuf, store_premultiplied);
- }
- }
-
- if (scaled) {
- /* Slower update where we first have to scale the input pixels. */
- if (tile != NULL) {
- int *tileoffset = tile->runtime.tilearray_offset;
- int *tilesize = tile->runtime.tilearray_size;
- int tilelayer = tile->runtime.tilearray_layer;
- gpu_texture_update_scaled_array(
- rect, rect_float, ibuf->x, ibuf->y, x, y, tilelayer, tileoffset, tilesize, w, h);
- }
- else {
- gpu_texture_update_scaled(rect, rect_float, ibuf->x, ibuf->y, x, y, w, h);
- }
- }
- else {
- /* Fast update at same resolution. */
- if (tile != NULL) {
- int *tileoffset = tile->runtime.tilearray_offset;
- int tilelayer = tile->runtime.tilearray_layer;
- gpu_texture_update_unscaled(rect,
- rect_float,
- x + tileoffset[0],
- y + tileoffset[1],
- tilelayer,
- w,
- h,
- tex_stride,
- tex_offset);
- }
- else {
- gpu_texture_update_unscaled(rect, rect_float, x, y, -1, w, h, tex_stride, tex_offset);
- }
- }
-
- /* Free buffers if needed. */
- if (rect && rect != (uchar *)ibuf->rect) {
- MEM_freeN(rect);
- }
- if (rect_float && rect_float != ibuf->rect_float) {
- MEM_freeN(rect_float);
- }
-
- if (GPU_get_mipmap()) {
- glGenerateMipmap((tile != NULL) ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D);
- }
- else {
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
- }
-
- GPU_texture_unbind(tex);
-}
-
-/* Get the GPUTexture for a given `Image`.
- *
- * `iuser` and `ibuf` are mutual exclusive parameters. The caller can pass the `ibuf` when already
- * available. It is also required when requesting the GPUTexture for a render result. */
-GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf, int textarget)
-{
-#ifndef GPU_STANDALONE
- if (ima == NULL) {
- return NULL;
- }
-
- /* Free any unused GPU textures, since we know we are in a thread with OpenGL
- * context and might as well ensure we have as much space free as possible. */
- gpu_free_unused_buffers();
-
- /* currently, gpu refresh tagging is used by ima sequences */
- if (ima->gpuflag & IMA_GPU_REFRESH) {
- gpu_free_image(ima, true);
- ima->gpuflag &= ~IMA_GPU_REFRESH;
- }
-
- /* Tag as in active use for garbage collector. */
- BKE_image_tag_time(ima);
-
- /* Test if we already have a texture. */
- GPUTexture **tex = gpu_get_image_gputexture(ima, textarget, iuser ? iuser->multiview_eye : 0);
- if (*tex) {
- return *tex;
- }
-
- /* Check if we have a valid image. If not, we return a dummy
- * texture with zero bindcode so we don't keep trying. */
- uint bindcode = 0;
- ImageTile *tile = BKE_image_get_tile(ima, 0);
- if (tile == NULL || tile->ok == 0) {
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
- return *tex;
- }
-
- /* check if we have a valid image buffer */
- ImBuf *ibuf_intern = ibuf;
- if (ibuf_intern == NULL) {
- ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if (ibuf_intern == NULL) {
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
- return *tex;
- }
- }
-
- if (textarget == GL_TEXTURE_2D_ARRAY) {
- bindcode = gpu_texture_create_tile_array(ima, ibuf_intern);
- }
- else if (textarget == GL_TEXTURE_1D_ARRAY) {
- bindcode = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0);
- }
- else {
- bindcode = gpu_texture_create_from_ibuf(ima, ibuf_intern, textarget);
- }
-
- /* if `ibuf` was given, we don't own the `ibuf_intern` */
- if (ibuf == NULL) {
- BKE_image_release_ibuf(ima, ibuf_intern, NULL);
- }
-
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
-
- GPU_texture_orig_size_set(*tex, ibuf_intern->x, ibuf_intern->y);
-
- if (textarget == GL_TEXTURE_1D_ARRAY) {
- /* Special for tile mapping. */
- GPU_texture_mipmap_mode(*tex, false, false);
- }
-
- return *tex;
-#endif
- return NULL;
-}
-
-GPUTexture *GPU_texture_from_movieclip(MovieClip *clip, MovieClipUser *cuser, int textarget)
-{
-#ifndef GPU_STANDALONE
- if (clip == NULL) {
- return NULL;
- }
-
- GPUTexture **tex = gpu_get_movieclip_gputexture(clip, cuser, textarget);
- if (*tex) {
- return *tex;
- }
-
- /* check if we have a valid image buffer */
- uint bindcode = 0;
- ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser);
- if (ibuf == NULL) {
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
- return *tex;
- }
-
- bindcode = gpu_texture_create_from_ibuf(NULL, ibuf, textarget);
- IMB_freeImBuf(ibuf);
-
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
- return *tex;
-#else
- return NULL;
-#endif
-}
-
-void GPU_free_texture_movieclip(struct MovieClip *clip)
-{
- /* number of gpu textures to keep around as cache
- * We don't want to keep too many GPU textures for
- * movie clips around, as they can be large.*/
- const int MOVIECLIP_NUM_GPUTEXTURES = 1;
-
- while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) {
- MovieClip_RuntimeGPUTexture *tex = BLI_pophead(&clip->runtime.gputextures);
- for (int i = 0; i < TEXTARGET_COUNT; i++) {
- /* free glsl image binding */
- if (tex->gputexture[i]) {
- GPU_texture_free(tex->gputexture[i]);
- tex->gputexture[i] = NULL;
- }
- }
- MEM_freeN(tex);
- }
-}
-
-static void **gpu_gen_cube_map(uint *rect, float *frect, int rectw, int recth)
-{
- size_t block_size = frect ? sizeof(float[4]) : sizeof(uchar[4]);
- void **sides = NULL;
- int h = recth / 2;
- int w = rectw / 3;
-
- if (w != h) {
- return sides;
- }
-
- /* PosX, NegX, PosY, NegY, PosZ, NegZ */
- sides = MEM_mallocN(sizeof(void *) * 6, "");
- for (int i = 0; i < 6; i++) {
- sides[i] = MEM_mallocN(block_size * w * h, "");
- }
-
- /* divide image into six parts */
- /* ______________________
- * | | | |
- * | NegX | NegY | PosX |
- * |______|______|______|
- * | | | |
- * | NegZ | PosZ | PosY |
- * |______|______|______|
- */
- if (frect) {
- float(*frectb)[4] = (float(*)[4])frect;
- float(**fsides)[4] = (float(**)[4])sides;
-
- for (int y = 0; y < h; y++) {
- for (int x = 0; x < w; x++) {
- memcpy(&fsides[0][x * h + y], &frectb[(recth - y - 1) * rectw + 2 * w + x], block_size);
- memcpy(&fsides[1][x * h + y], &frectb[(y + h) * rectw + w - 1 - x], block_size);
- memcpy(
- &fsides[3][y * w + x], &frectb[(recth - y - 1) * rectw + 2 * w - 1 - x], block_size);
- memcpy(&fsides[5][y * w + x], &frectb[(h - y - 1) * rectw + w - 1 - x], block_size);
- }
- memcpy(&fsides[2][y * w], frectb[y * rectw + 2 * w], block_size * w);
- memcpy(&fsides[4][y * w], frectb[y * rectw + w], block_size * w);
- }
- }
- else {
- uint **isides = (uint **)sides;
-
- for (int y = 0; y < h; y++) {
- for (int x = 0; x < w; x++) {
- isides[0][x * h + y] = rect[(recth - y - 1) * rectw + 2 * w + x];
- isides[1][x * h + y] = rect[(y + h) * rectw + w - 1 - x];
- isides[3][y * w + x] = rect[(recth - y - 1) * rectw + 2 * w - 1 - x];
- isides[5][y * w + x] = rect[(h - y - 1) * rectw + w - 1 - x];
- }
- memcpy(&isides[2][y * w], &rect[y * rectw + 2 * w], block_size * w);
- memcpy(&isides[4][y * w], &rect[y * rectw + w], block_size * w);
- }
- }
-
- return sides;
-}
-
-static void gpu_del_cube_map(void **cube_map)
-{
- int i;
- if (cube_map == NULL) {
- return;
- }
- for (i = 0; i < 6; i++) {
- MEM_freeN(cube_map[i]);
- }
- MEM_freeN(cube_map);
-}
-
-/* Image *ima can be NULL */
-void GPU_create_gl_tex(uint *bind,
- uint *rect,
- float *frect,
- int rectw,
- int recth,
- int textarget,
- bool mipmap,
- bool half_float,
- bool use_srgb,
- Image *ima)
-{
- ImBuf *ibuf = NULL;
-
- if (textarget == GL_TEXTURE_2D && is_over_resolution_limit(textarget, rectw, recth)) {
- int tpx = rectw;
- int tpy = recth;
- rectw = smaller_power_of_2_limit(rectw);
- recth = smaller_power_of_2_limit(recth);
-
- if (frect) {
- ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy, 4);
- IMB_scaleImBuf(ibuf, rectw, recth);
-
- frect = ibuf->rect_float;
- }
- else {
- ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy, 4);
- IMB_scaleImBuf(ibuf, rectw, recth);
-
- rect = ibuf->rect;
- }
- }
-
- /* create image */
- glGenTextures(1, (GLuint *)bind);
- glBindTexture(textarget, *bind);
-
- GLenum float_format = (!half_float && (ima && (ima->flag & IMA_HIGH_BITDEPTH))) ? GL_RGBA32F :
- GL_RGBA16F;
- GLenum internal_format = (frect) ? float_format : (use_srgb) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
-
- if (textarget == GL_TEXTURE_2D) {
- if (frect) {
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
- }
- else {
- glTexImage2D(
- GL_TEXTURE_2D, 0, internal_format, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
- }
-
- if (GPU_get_mipmap() && mipmap) {
- glGenerateMipmap(GL_TEXTURE_2D);
- if (ima) {
- ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
- }
- }
- }
- else if (textarget == GL_TEXTURE_CUBE_MAP) {
- int w = rectw / 3, h = recth / 2;
-
- if (h == w && is_power_of_2_i(h) && !is_over_resolution_limit(textarget, h, w)) {
- void **cube_map = gpu_gen_cube_map(rect, frect, rectw, recth);
- GLenum type = frect ? GL_FLOAT : GL_UNSIGNED_BYTE;
-
- if (cube_map) {
- for (int i = 0; i < 6; i++) {
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
- 0,
- internal_format,
- w,
- h,
- 0,
- GL_RGBA,
- type,
- cube_map[i]);
- }
- }
-
- if (GPU_get_mipmap() && mipmap) {
- glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
-
- if (ima) {
- ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
- }
- }
-
- gpu_del_cube_map(cube_map);
- }
- else {
- printf("Incorrect envmap size\n");
- }
- }
-
- glBindTexture(textarget, 0);
-
- if (ibuf) {
- IMB_freeImBuf(ibuf);
- }
-}
-
-/**
- * GPU_upload_dxt_texture() assumes that the texture is already bound and ready to go.
- * This is so the viewport and the BGE can share some code.
- * Returns false if the provided ImBuf doesn't have a supported DXT compression format
- */
-bool GPU_upload_dxt_texture(ImBuf *ibuf, bool use_srgb)
-{
-#ifdef WITH_DDS
- GLint format = 0;
- int blocksize, height, width, i, size, offset = 0;
-
- width = ibuf->x;
- height = ibuf->y;
-
- if (GLEW_EXT_texture_compression_s3tc) {
- if (ibuf->dds_data.fourcc == FOURCC_DXT1) {
- format = (use_srgb) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT :
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
- }
- else if (ibuf->dds_data.fourcc == FOURCC_DXT3) {
- format = (use_srgb) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT :
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
- }
- else if (ibuf->dds_data.fourcc == FOURCC_DXT5) {
- format = (use_srgb) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT :
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
- }
- }
-
- if (format == 0) {
- fprintf(stderr, "Unable to find a suitable DXT compression, falling back to uncompressed\n");
- return false;
- }
-
- if (!is_power_of_2_resolution(width, height)) {
- fprintf(
- stderr,
- "Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n");
- return false;
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
-
- blocksize = (ibuf->dds_data.fourcc == FOURCC_DXT1) ? 8 : 16;
- for (i = 0; i < ibuf->dds_data.nummipmaps && (width || height); i++) {
- if (width == 0) {
- width = 1;
- }
- if (height == 0) {
- height = 1;
- }
-
- size = ((width + 3) / 4) * ((height + 3) / 4) * blocksize;
-
- glCompressedTexImage2D(
- GL_TEXTURE_2D, i, format, width, height, 0, size, ibuf->dds_data.data + offset);
-
- offset += size;
- width >>= 1;
- height >>= 1;
- }
-
- /* set number of mipmap levels we have, needed in case they don't go down to 1x1 */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i - 1);
-
- return true;
-#else
- UNUSED_VARS(ibuf, use_srgb);
- return false;
-#endif
-}
-
-void GPU_create_gl_tex_compressed(unsigned int *bind, int textarget, Image *ima, ImBuf *ibuf)
-{
- /* For DDS we only support data, scene linear and sRGB. Converting to
- * different colorspace would break the compression. */
- const bool use_srgb = !(IMB_colormanagement_space_is_data(ibuf->rect_colorspace) ||
- IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace));
- const bool mipmap = GPU_get_mipmap();
- const bool half_float = (ibuf->flags & IB_halffloat) != 0;
-
-#ifndef WITH_DDS
- (void)ibuf;
- /* Fall back to uncompressed if DDS isn't enabled */
- GPU_create_gl_tex(
- bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima);
-#else
- glGenTextures(1, (GLuint *)bind);
- glBindTexture(textarget, *bind);
-
- if (textarget == GL_TEXTURE_2D && GPU_upload_dxt_texture(ibuf, use_srgb) == 0) {
- glDeleteTextures(1, (GLuint *)bind);
- GPU_create_gl_tex(
- bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima);
- }
-
- glBindTexture(textarget, 0);
-#endif
-}
-
-/* these two functions are called on entering and exiting texture paint mode,
- * temporary disabling/enabling mipmapping on all images for quick texture
- * updates with glTexSubImage2D. images that didn't change don't have to be
- * re-uploaded to OpenGL */
-void GPU_paint_set_mipmap(Main *bmain, bool mipmap)
-{
-#ifndef GPU_STANDALONE
- if (!GTS.domipmap) {
- return;
- }
-
- GTS.texpaint = !mipmap;
-
- if (mipmap) {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
- if (BKE_image_has_opengl_texture(ima)) {
- if (ima->gpuflag & IMA_GPU_MIPMAP_COMPLETE) {
- for (int eye = 0; eye < 2; eye++) {
- for (int a = 0; a < TEXTARGET_COUNT; a++) {
- if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) {
- GPUTexture *tex = ima->gputexture[a][eye];
- if (tex != NULL) {
- GPU_texture_bind(tex, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
- GPU_texture_unbind(tex);
- }
- }
- }
- }
- }
- else {
- GPU_free_image(ima);
- }
- }
- else {
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
- }
- }
- }
- else {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
- if (BKE_image_has_opengl_texture(ima)) {
- for (int eye = 0; eye < 2; eye++) {
- for (int a = 0; a < TEXTARGET_COUNT; a++) {
- if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) {
- GPUTexture *tex = ima->gputexture[a][eye];
- if (tex != NULL) {
- GPU_texture_bind(tex, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
- GPU_texture_unbind(tex);
- }
- }
- }
- }
- }
- else {
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
- }
- }
- }
-#endif /* GPU_STANDALONE */
-}
-
-void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, int h)
-{
-#ifndef GPU_STANDALONE
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- ImageTile *tile = BKE_image_get_tile_from_iuser(ima, iuser);
-
- if ((ibuf == NULL) || (w == 0) || (h == 0)) {
- /* Full reload of texture. */
- GPU_free_image(ima);
- }
-
- GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D][0];
- /* Check if we need to update the main gputexture. */
- if (tex != NULL && tile == ima->tiles.first) {
- gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h);
- }
-
- /* Check if we need to update the array gputexture. */
- tex = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][0];
- if (tex != NULL) {
- gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h);
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-#endif
-}
-
-/* Delayed GPU texture free. Image datablocks can be deleted by any thread,
- * but there may not be any active OpenGL context. In that case we push them
- * into a queue and free the buffers later. */
-static LinkNode *gpu_texture_free_queue = NULL;
-static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER;
-
-static void gpu_free_unused_buffers()
-{
- if (gpu_texture_free_queue == NULL) {
- return;
- }
-
- BLI_mutex_lock(&gpu_texture_queue_mutex);
-
- if (gpu_texture_free_queue != NULL) {
- for (LinkNode *node = gpu_texture_free_queue; node; node = node->next) {
- GPUTexture *tex = node->link;
- GPU_texture_free(tex);
- }
-
- BLI_linklist_free(gpu_texture_free_queue, NULL);
- gpu_texture_free_queue = NULL;
- }
-
- BLI_mutex_unlock(&gpu_texture_queue_mutex);
-}
-
-static void gpu_free_image(Image *ima, const bool immediate)
-{
- for (int eye = 0; eye < 2; eye++) {
- for (int i = 0; i < TEXTARGET_COUNT; i++) {
- if (ima->gputexture[i][eye] != NULL) {
- if (immediate) {
- GPU_texture_free(ima->gputexture[i][eye]);
- }
- else {
- BLI_mutex_lock(&gpu_texture_queue_mutex);
- BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]);
- BLI_mutex_unlock(&gpu_texture_queue_mutex);
- }
-
- ima->gputexture[i][eye] = NULL;
- }
- }
- }
-
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
-}
-
-void GPU_free_unused_buffers()
-{
- if (BLI_thread_is_main()) {
- gpu_free_unused_buffers();
- }
-}
-
-void GPU_free_image(Image *ima)
-{
- gpu_free_image(ima, BLI_thread_is_main());
-}
-
-void GPU_free_images(Main *bmain)
-{
- if (bmain) {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
- GPU_free_image(ima);
- }
- }
-}
-
-/* same as above but only free animated images */
-void GPU_free_images_anim(Main *bmain)
-{
- if (bmain) {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
- if (BKE_image_is_animated(ima)) {
- GPU_free_image(ima);
- }
- }
- }
-}
-
-void GPU_free_images_old(Main *bmain)
-{
- static int lasttime = 0;
- int ctime = (int)PIL_check_seconds_timer();
-
- /*
- * Run garbage collector once for every collecting period of time
- * if textimeout is 0, that's the option to NOT run the collector
- */
- if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime) {
- return;
- }
-
- /* of course not! */
- if (G.is_rendering) {
- return;
- }
-
- lasttime = ctime;
-
- Image *ima = bmain->images.first;
- while (ima) {
- if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
- /* If it's in GL memory, deallocate and set time tag to current time
- * This gives textures a "second chance" to be used before dying. */
- if (BKE_image_has_opengl_texture(ima)) {
- GPU_free_image(ima);
- ima->lastused = ctime;
- }
- /* Otherwise, just kill the buffers */
- else {
- BKE_image_free_buffers(ima);
- }
- }
- ima = ima->id.next;
- }
-}
diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.cc
index 036588b4a48..9f104ab3fec 100644
--- a/source/blender/gpu/intern/gpu_element.c
+++ b/source/blender/gpu/intern/gpu_element.cc
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "GPU_element.h"
+#include "GPU_glew.h"
#include "gpu_context_private.h"
@@ -37,21 +38,18 @@
static GLenum convert_index_type_to_gl(GPUIndexBufType type)
{
- static const GLenum table[] = {
- [GPU_INDEX_U16] = GL_UNSIGNED_SHORT,
- [GPU_INDEX_U32] = GL_UNSIGNED_INT,
- };
- return table[type];
+#if GPU_TRACK_INDEX_RANGE
+ return (type == GPU_INDEX_U32) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+#else
+ return GL_UNSIGNED_INT;
+#endif
}
uint GPU_indexbuf_size_get(const GPUIndexBuf *elem)
{
#if GPU_TRACK_INDEX_RANGE
- static const uint table[] = {
- [GPU_INDEX_U16] = sizeof(GLushort),
- [GPU_INDEX_U32] = sizeof(GLuint),
- };
- return elem->index_len * table[elem->index_type];
+ return elem->index_len *
+ ((elem->index_type == GPU_INDEX_U32) ? sizeof(GLuint) : sizeof(GLshort));
#else
return elem->index_len * sizeof(GLuint);
#endif
@@ -86,7 +84,7 @@ void GPU_indexbuf_init_ex(GPUIndexBufBuilder *builder,
builder->max_index_len = index_len;
builder->index_len = 0; // start empty
builder->prim_type = prim_type;
- builder->data = MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data");
+ builder->data = (uint *)MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data");
}
void GPU_indexbuf_init(GPUIndexBufBuilder *builder,
@@ -241,7 +239,7 @@ void GPU_indexbuf_set_tri_restart(GPUIndexBufBuilder *builder, uint elem)
GPUIndexBuf *GPU_indexbuf_create_subrange(GPUIndexBuf *elem_src, uint start, uint length)
{
- GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
+ GPUIndexBuf *elem = (GPUIndexBuf *)MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
GPU_indexbuf_create_subrange_in_place(elem, elem_src, start, length);
return elem;
}
@@ -331,7 +329,7 @@ static void squeeze_indices_short(GPUIndexBufBuilder *builder,
GPUIndexBuf *GPU_indexbuf_build(GPUIndexBufBuilder *builder)
{
- GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
+ GPUIndexBuf *elem = (GPUIndexBuf *)MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
GPU_indexbuf_build_in_place(builder, elem);
return elem;
}
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.cc
index fbeb2edc266..35b70a18363 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.cc
@@ -31,6 +31,8 @@
#include "BKE_global.h"
#include "MEM_guardedalloc.h"
+#include "DNA_userdef_types.h"
+
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
#include "GPU_glew.h"
@@ -95,7 +97,7 @@ static struct GPUGlobal {
bool broken_amd_driver;
/* Some crappy Intel drivers don't work well with shaders created in different
* rendering contexts. */
- bool context_local_shaders_workaround;
+ bool use_main_context_workaround;
/* Intel drivers exhibit artifacts when using #glCopyImageSubData & workbench anti-aliasing.
* (see T76273) */
bool texture_copy_workaround;
@@ -104,7 +106,8 @@ static struct GPUGlobal {
static void gpu_detect_mip_render_workaround(void)
{
int cube_size = 2;
- float *source_pix = MEM_callocN(sizeof(float) * 4 * 6 * cube_size * cube_size, __func__);
+ float *source_pix = (float *)MEM_callocN(sizeof(float) * 4 * 6 * cube_size * cube_size,
+ __func__);
float clear_color[4] = {1.0f, 0.5f, 0.0f, 0.0f};
GPUTexture *tex = GPU_texture_create_cube(cube_size, GPU_RGBA16F, source_pix, NULL);
@@ -123,7 +126,7 @@ static void gpu_detect_mip_render_workaround(void)
GPU_framebuffer_restore();
GPU_framebuffer_free(fb);
- float *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 1);
+ float *data = (float *)GPU_texture_read(tex, GPU_DATA_FLOAT, 1);
GG.mip_render_workaround = !equals_v4v4(clear_color, data);
MEM_freeN(data);
@@ -222,9 +225,9 @@ bool GPU_unused_fb_slot_workaround(void)
return GG.unused_fb_slot_workaround;
}
-bool GPU_context_local_shaders_workaround(void)
+bool GPU_use_main_context_workaround(void)
{
- return GG.context_local_shaders_workaround;
+ return GG.use_main_context_workaround;
}
bool GPU_texture_copy_workaround(void)
@@ -238,6 +241,13 @@ bool GPU_crappy_amd_driver(void)
return GG.broken_amd_driver;
}
+int GPU_texture_size_with_limit(int res)
+{
+ int size = GPU_max_texture_size();
+ int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size;
+ return min_ii(reslimit, res);
+}
+
void gpu_extensions_init(void)
{
/* during 2.8 development each platform has its own OpenGL minimum requirements
@@ -311,7 +321,7 @@ void gpu_extensions_init(void)
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL)) {
/* Limit this fix to older hardware with GL < 4.5. This means Broadwell GPUs are
* covered since they only support GL 4.4 on windows.
- * This fixes some issues with workbench antialiasing on Win + Intel GPU. (see T76273) */
+ * This fixes some issues with workbench anti-aliasing on Win + Intel GPU. (see T76273) */
if (!GLEW_VERSION_4_5) {
GG.texture_copy_workaround = true;
}
@@ -339,7 +349,6 @@ void gpu_extensions_init(void)
GG.depth_blitting_workaround = true;
GG.unused_fb_slot_workaround = true;
GG.texture_copy_workaround = true;
- GG.context_local_shaders_workaround = GLEW_ARB_get_program_binary;
}
/* Special fix for theses specific GPUs.
@@ -347,7 +356,13 @@ void gpu_extensions_init(void)
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) &&
(strstr(renderer, "HD Graphics 620") || strstr(renderer, "HD Graphics 630"))) {
GG.mip_render_workaround = true;
- GG.context_local_shaders_workaround = GLEW_ARB_get_program_binary;
+ }
+
+ /* Intel Ivy Bridge GPU's seems to have buggy cube-map array support. (see T75943) */
+ if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) &&
+ (strstr(renderer, "HD Graphics 4000") || strstr(renderer, "HD Graphics 4400") ||
+ strstr(renderer, "HD Graphics 2500"))) {
+ GG.glew_arb_texture_cube_map_array_is_supported = false;
}
/* df/dy calculation factors, those are dependent on driver */
@@ -376,12 +391,12 @@ void gpu_extensions_init(void)
/* Maybe not all of these drivers have problems with `GLEW_ARB_base_instance`.
* But it's hard to test each case. */
GG.glew_arb_base_instance_is_supported = false;
- GG.context_local_shaders_workaround = true;
+ GG.use_main_context_workaround = true;
}
if (strstr(version, "Build 20.19.15.4285")) {
/* Somehow fixes armature display issues (see T69743). */
- GG.context_local_shaders_workaround = true;
+ GG.use_main_context_workaround = true;
}
}
else if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) &&
@@ -405,7 +420,7 @@ void gpu_extensions_exit(void)
bool GPU_mem_stats_supported(void)
{
#ifndef GPU_STANDALONE
- return (GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo) && (G.debug & G_DEBUG_GPU_MEM);
+ return (GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo);
#else
return false;
#endif
@@ -433,3 +448,11 @@ void GPU_mem_stats_get(int *totalmem, int *freemem)
*freemem = 0;
}
}
+
+/* Return support for the active context + window. */
+bool GPU_stereo_quadbuffer_support(void)
+{
+ GLboolean stereo = GL_FALSE;
+ glGetBooleanv(GL_STEREO, &stereo);
+ return stereo == GL_TRUE;
+}
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.cc
index 3e806e1a982..056a449ac6d 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -28,7 +28,6 @@
#include "BLI_utildefines.h"
#include "GPU_batch.h"
-#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
#include "GPU_shader.h"
@@ -53,6 +52,10 @@ typedef enum {
GPU_FB_MAX_ATTACHEMENT,
} GPUAttachmentType;
+#define FOREACH_ATTACHMENT_RANGE(att, _start, _end) \
+ for (GPUAttachmentType att = static_cast<GPUAttachmentType>(_start); att < _end; \
+ att = static_cast<GPUAttachmentType>(att + 1))
+
#define GPU_FB_MAX_COLOR_ATTACHMENT (GPU_FB_MAX_ATTACHEMENT - GPU_FB_COLOR_ATTACHMENT0)
#define GPU_FB_DIRTY_DRAWBUFFER (1 << 15)
@@ -74,17 +77,25 @@ struct GPUFrameBuffer {
static GLenum convert_attachment_type_to_gl(GPUAttachmentType type)
{
- static const GLenum table[] = {
- [GPU_FB_DEPTH_ATTACHMENT] = GL_DEPTH_ATTACHMENT,
- [GPU_FB_DEPTH_STENCIL_ATTACHMENT] = GL_DEPTH_STENCIL_ATTACHMENT,
- [GPU_FB_COLOR_ATTACHMENT0] = GL_COLOR_ATTACHMENT0,
- [GPU_FB_COLOR_ATTACHMENT1] = GL_COLOR_ATTACHMENT1,
- [GPU_FB_COLOR_ATTACHMENT2] = GL_COLOR_ATTACHMENT2,
- [GPU_FB_COLOR_ATTACHMENT3] = GL_COLOR_ATTACHMENT3,
- [GPU_FB_COLOR_ATTACHMENT4] = GL_COLOR_ATTACHMENT4,
- [GPU_FB_COLOR_ATTACHMENT5] = GL_COLOR_ATTACHMENT5,
- };
- return table[type];
+#define ATTACHMENT(type) \
+ case GPU_FB_##type: { \
+ return GL_##type; \
+ } \
+ ((void)0)
+
+ switch (type) {
+ ATTACHMENT(DEPTH_ATTACHMENT);
+ ATTACHMENT(DEPTH_STENCIL_ATTACHMENT);
+ ATTACHMENT(COLOR_ATTACHMENT0);
+ ATTACHMENT(COLOR_ATTACHMENT1);
+ ATTACHMENT(COLOR_ATTACHMENT2);
+ ATTACHMENT(COLOR_ATTACHMENT3);
+ ATTACHMENT(COLOR_ATTACHMENT4);
+ ATTACHMENT(COLOR_ATTACHMENT5);
+ default:
+ BLI_assert(0);
+ return GL_COLOR_ATTACHMENT0;
+ }
}
static GPUAttachmentType attachment_type_from_tex(GPUTexture *tex, int slot)
@@ -98,7 +109,7 @@ static GPUAttachmentType attachment_type_from_tex(GPUTexture *tex, int slot)
case GPU_DEPTH32F_STENCIL8:
return GPU_FB_DEPTH_STENCIL_ATTACHMENT;
default:
- return GPU_FB_COLOR_ATTACHMENT0 + slot;
+ return static_cast<GPUAttachmentType>(GPU_FB_COLOR_ATTACHMENT0 + slot);
}
}
@@ -198,7 +209,7 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
{
/* We generate the FB object later at first use in order to
* create the framebuffer in the right opengl context. */
- return MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
+ return (GPUFrameBuffer *)MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
}
static void gpu_framebuffer_init(GPUFrameBuffer *fb)
@@ -210,7 +221,8 @@ static void gpu_framebuffer_init(GPUFrameBuffer *fb)
void GPU_framebuffer_free(GPUFrameBuffer *fb)
{
- for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) {
+ for (int i_type = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i_type++) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
if (fb->attachments[type].tex != NULL) {
GPU_framebuffer_texture_detach(fb, fb->attachments[type].tex);
}
@@ -304,7 +316,7 @@ void GPU_framebuffer_texture_detach_slot(GPUFrameBuffer *fb, GPUTexture *tex, in
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
{
- GPUAttachmentType type = GPU_texture_detach_framebuffer(tex, fb);
+ GPUAttachmentType type = (GPUAttachmentType)GPU_texture_detach_framebuffer(tex, fb);
GPU_framebuffer_texture_detach_slot(fb, tex, type);
}
@@ -387,8 +399,8 @@ static void gpu_framebuffer_update_attachments(GPUFrameBuffer *fb)
BLI_assert(GPU_framebuffer_active_get() == fb);
/* Update attachments */
- for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) {
-
+ FOREACH_ATTACHMENT_RANGE(type, 0, GPU_FB_MAX_ATTACHEMENT)
+ {
if (type >= GPU_FB_COLOR_ATTACHMENT0) {
if (fb->attachments[type].tex) {
gl_attachments[numslots] = convert_attachment_type_to_gl(type);
@@ -438,7 +450,8 @@ static void gpu_framebuffer_update_attachments_and_fill_empty_slots(GPUFrameBuff
BLI_assert(GPU_framebuffer_active_get() == fb);
/* Update attachments */
- for (GPUAttachmentType type = GPU_FB_MAX_ATTACHEMENT; type--;) {
+ for (int i_type = GPU_FB_MAX_ATTACHEMENT - 1; i_type >= 0; --i_type) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
GPUTexture *tex = fb->attachments[type].tex;
if (type >= GPU_FB_COLOR_ATTACHMENT0) {
@@ -623,8 +636,9 @@ void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float (*clear_cols)[4
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- GPUAttachmentType type = GPU_FB_COLOR_ATTACHMENT0;
- for (int i = 0; type < GPU_FB_MAX_ATTACHEMENT; i++, type++) {
+ int i_type = GPU_FB_COLOR_ATTACHMENT0;
+ for (int i = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i++, i_type++) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
if (fb->attachments[type].tex != NULL) {
glClearBufferfv(GL_COLOR, i, clear_cols[i]);
}
@@ -640,31 +654,70 @@ void GPU_framebuffer_read_depth(GPUFrameBuffer *fb, int x, int y, int w, int h,
glReadPixels(x, y, w, h, type, GL_FLOAT, data);
}
-void GPU_framebuffer_read_color(
- GPUFrameBuffer *fb, int x, int y, int w, int h, int channels, int slot, float *data)
+static GLenum gpu_get_gl_datatype(eGPUDataFormat format)
{
- CHECK_FRAMEBUFFER_IS_BOUND(fb);
+ switch (format) {
+ case GPU_DATA_FLOAT:
+ return GL_FLOAT;
+ case GPU_DATA_INT:
+ return GL_INT;
+ case GPU_DATA_UNSIGNED_INT:
+ return GL_UNSIGNED_INT;
+ case GPU_DATA_UNSIGNED_BYTE:
+ return GL_UNSIGNED_BYTE;
+ case GPU_DATA_UNSIGNED_INT_24_8:
+ return GL_UNSIGNED_INT_24_8;
+ case GPU_DATA_10_11_11_REV:
+ return GL_UNSIGNED_INT_10F_11F_11F_REV;
+ default:
+ BLI_assert(!"Unhandled data format");
+ return GL_FLOAT;
+ }
+}
- GLenum type;
+static GLenum gpu_get_gl_channel_type(int channels)
+{
switch (channels) {
case 1:
- type = GL_RED;
- break;
+ return GL_RED;
case 2:
- type = GL_RG;
- break;
+ return GL_RG;
case 3:
- type = GL_RGB;
- break;
+ return GL_RGB;
case 4:
- type = GL_RGBA;
- break;
+ return GL_RGBA;
default:
- BLI_assert(false && "wrong number of read channels");
- return;
+ BLI_assert(!"Wrong number of read channels");
+ return GL_RED;
}
- glReadBuffer(GL_COLOR_ATTACHMENT0 + slot);
- glReadPixels(x, y, w, h, type, GL_FLOAT, data);
+}
+
+static void gpu_framebuffer_read_color_ex(
+ int x, int y, int w, int h, int channels, GLenum readfb, eGPUDataFormat format, float *data)
+{
+ GLenum type = gpu_get_gl_channel_type(channels);
+ GLenum gl_format = gpu_get_gl_datatype(format);
+ /* TODO: needed for selection buffers to work properly, this should be handled better. */
+ if (type == GL_RED && gl_format == GL_UNSIGNED_INT) {
+ type = GL_RED_INTEGER;
+ }
+ glReadBuffer(readfb);
+ glReadPixels(x, y, w, h, type, gl_format, data);
+}
+
+void GPU_framebuffer_read_color(GPUFrameBuffer *fb,
+ int x,
+ int y,
+ int w,
+ int h,
+ int channels,
+ int slot,
+ eGPUDataFormat format,
+ void *data)
+{
+ CHECK_FRAMEBUFFER_IS_BOUND(fb);
+ gpu_framebuffer_read_color_ex(
+ x, y, w, h, channels, GL_COLOR_ATTACHMENT0 + slot, format, (float *)data);
}
/* read_slot and write_slot are only used for color buffers. */
@@ -749,9 +802,9 @@ void GPU_framebuffer_blit(GPUFrameBuffer *fb_read,
}
/**
- * Use this if you need to custom down-sample your texture and use the previous mip level as input.
- * This function only takes care of the correct texture handling.
- * It execute the callback for each texture level.
+ * Use this if you need to custom down-sample your texture and use the previous mip level as
+ * input. This function only takes care of the correct texture handling. It execute the callback
+ * for each texture level.
*/
void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb,
int max_lvl,
@@ -777,7 +830,8 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb,
current_dim[0] = max_ii(current_dim[0] / 2, 1);
current_dim[1] = max_ii(current_dim[1] / 2, 1);
- for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) {
+ for (int i_type = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i_type++) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
if (fb->attachments[type].tex != NULL) {
/* Some Intel HDXXX have issue with rendering to a mipmap that is below
* the texture GL_TEXTURE_MAX_LEVEL. So even if it not correct, in this case
@@ -806,7 +860,8 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb,
}
}
- for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) {
+ for (int i_type = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i_type++) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
if (fb->attachments[type].tex != NULL) {
/* reset mipmap level range */
GPUTexture *tex = fb->attachments[type].tex;
@@ -847,9 +902,11 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs)
for (int i = 0; i < MAX_CTX_FB_LEN; i++) {
if (ofs->framebuffers[i].fb == NULL) {
ofs->framebuffers[i].ctx = ctx;
- GPU_framebuffer_ensure_config(
- &ofs->framebuffers[i].fb,
- {GPU_ATTACHMENT_TEXTURE(ofs->depth), GPU_ATTACHMENT_TEXTURE(ofs->color)});
+ GPU_framebuffer_ensure_config(&ofs->framebuffers[i].fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(ofs->depth),
+ GPU_ATTACHMENT_TEXTURE(ofs->color),
+ });
}
if (ofs->framebuffers[i].ctx == ctx) {
@@ -878,9 +935,7 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs)
GPUOffScreen *GPU_offscreen_create(
int width, int height, bool depth, bool high_bitdepth, char err_out[256])
{
- GPUOffScreen *ofs;
-
- ofs = MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen");
+ GPUOffScreen *ofs = (GPUOffScreen *)MEM_callocN(sizeof(GPUOffScreen), __func__);
/* Sometimes areas can have 0 height or width and this will
* create a 1D texture which we don't want. */
@@ -937,14 +992,14 @@ void GPU_offscreen_free(GPUOffScreen *ofs)
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
{
if (save) {
- gpuPushAttr(GPU_SCISSOR_BIT | GPU_VIEWPORT_BIT);
+ gpuPushAttr((eGPUAttrMask)(GPU_SCISSOR_BIT | GPU_VIEWPORT_BIT));
GPUFrameBuffer *fb = GPU_framebuffer_active_get();
gpuPushFrameBuffer(fb);
}
- glDisable(GL_SCISSOR_TEST);
GPUFrameBuffer *ofs_fb = gpu_offscreen_fb_get(ofs);
GPU_framebuffer_bind(ofs_fb);
glDisable(GL_FRAMEBUFFER_SRGB);
+ GPU_scissor_test(false);
GPU_shader_set_framebuffer_srgb_target(false);
}
@@ -985,14 +1040,15 @@ void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y)
glBindFramebuffer(GL_READ_FRAMEBUFFER, GPU_framebuffer_default());
}
-void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
+void GPU_offscreen_read_pixels(GPUOffScreen *ofs, eGPUDataFormat type, void *pixels)
{
const int w = GPU_texture_width(ofs->color);
const int h = GPU_texture_height(ofs->color);
- BLI_assert(type == GL_UNSIGNED_BYTE || type == GL_FLOAT);
+ BLI_assert(ELEM(type, GPU_DATA_UNSIGNED_BYTE, GPU_DATA_FLOAT));
+ GLenum gl_type = (type == GPU_DATA_FLOAT) ? GL_FLOAT : GL_UNSIGNED_BYTE;
- glReadPixels(0, 0, w, h, GL_RGBA, type, pixels);
+ glReadPixels(0, 0, w, h, GL_RGBA, gl_type, pixels);
}
int GPU_offscreen_width(const GPUOffScreen *ofs)
@@ -1035,3 +1091,23 @@ void GPU_clear(eGPUFrameBufferBits flags)
{
glClear(convert_buffer_bits_to_gl(flags));
}
+
+void GPU_frontbuffer_read_pixels(
+ int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data)
+{
+ gpu_framebuffer_read_color_ex(x, y, w, h, channels, GL_FRONT, format, (float *)data);
+}
+
+/* For stereo rendering. */
+void GPU_backbuffer_bind(eGPUBackBuffer buffer)
+{
+ if (buffer == GPU_BACKBUFFER) {
+ glDrawBuffer(GL_BACK);
+ }
+ else if (buffer == GPU_BACKBUFFER_LEFT) {
+ glDrawBuffer(GL_BACK_LEFT);
+ }
+ else if (buffer == GPU_BACKBUFFER_RIGHT) {
+ glDrawBuffer(GL_BACK_RIGHT);
+ }
+}
diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.cc
index 9ea273f33cf..7283f7c12aa 100644
--- a/source/blender/gpu/intern/gpu_immediate.c
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -29,6 +29,8 @@
#include "GPU_attr_binding.h"
#include "GPU_immediate.h"
+#include "GPU_matrix.h"
+#include "GPU_texture.h"
#include "gpu_attr_binding_private.h"
#include "gpu_context_private.h"
@@ -39,10 +41,6 @@
#include <stdlib.h>
#include <string.h>
-/* necessary functions from matrix API */
-extern void GPU_matrix_bind(const GPUShaderInterface *);
-extern bool GPU_matrix_dirty_get(void);
-
typedef struct ImmediateDrawBuffer {
GLuint vbo_id;
GLubyte *buffer_data;
@@ -74,7 +72,7 @@ typedef struct {
GLuint vao_id;
- GLuint bound_program;
+ GPUShader *bound_program;
const GPUShaderInterface *shader_interface;
GPUAttrBinding attr_binding;
uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */
@@ -145,48 +143,47 @@ GPUVertFormat *immVertexFormat(void)
return &imm.vertex_format;
}
-void immBindProgram(GLuint program, const GPUShaderInterface *shaderface)
+void immBindShader(GPUShader *shader)
{
#if TRUST_NO_ONE
- assert(imm.bound_program == 0);
- assert(glIsProgram(program));
+ assert(imm.bound_program == NULL);
+ assert(glIsProgram(shader->program));
#endif
- imm.bound_program = program;
- imm.shader_interface = shaderface;
+ imm.bound_program = shader;
+ imm.shader_interface = shader->interface;
if (!imm.vertex_format.packed) {
VertexFormat_pack(&imm.vertex_format);
}
- glUseProgram(program);
- get_attr_locations(&imm.vertex_format, &imm.attr_binding, shaderface);
- GPU_matrix_bind(shaderface);
- GPU_shader_set_srgb_uniform(shaderface);
+ GPU_shader_bind(shader);
+ get_attr_locations(&imm.vertex_format, &imm.attr_binding, imm.shader_interface);
+ GPU_matrix_bind(imm.shader_interface);
+ GPU_shader_set_srgb_uniform(imm.shader_interface);
}
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
{
GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
- immBindProgram(shader->program, shader->interface);
+ immBindShader(shader);
}
void immUnbindProgram(void)
{
#if TRUST_NO_ONE
- assert(imm.bound_program != 0);
+ assert(imm.bound_program != NULL);
#endif
#if PROGRAM_NO_OPTI
glUseProgram(0);
#endif
- imm.bound_program = 0;
+ imm.bound_program = NULL;
}
/* XXX do not use it. Special hack to use OCIO with batch API. */
-void immGetProgram(GLuint *program, GPUShaderInterface **shaderface)
+GPUShader *immGetShader(void)
{
- *program = imm.bound_program;
- *shaderface = (GPUShaderInterface *)imm.shader_interface;
+ return imm.bound_program;
}
#if TRUST_NO_ONE
@@ -280,7 +277,7 @@ void immBegin(GPUPrimType prim_type, uint vertex_len)
}
#endif
- active_buffer->buffer_data = glMapBufferRange(
+ active_buffer->buffer_data = (GLubyte *)glMapBufferRange(
GL_ARRAY_BUFFER,
active_buffer->buffer_offset,
bytes_needed,
@@ -366,17 +363,18 @@ static void immDrawSetup(void)
const GLvoid *pointer = (const GLubyte *)0 + offset;
const uint loc = read_attr_location(&imm.attr_binding, a_idx);
+ const GLenum type = convert_comp_type_to_gl(static_cast<GPUVertCompType>(a->comp_type));
switch (a->fetch_mode) {
case GPU_FETCH_FLOAT:
case GPU_FETCH_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer);
+ glVertexAttribPointer(loc, a->comp_len, type, GL_FALSE, stride, pointer);
break;
case GPU_FETCH_INT_TO_FLOAT_UNIT:
- glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer);
+ glVertexAttribPointer(loc, a->comp_len, type, GL_TRUE, stride, pointer);
break;
case GPU_FETCH_INT:
- glVertexAttribIPointer(loc, a->comp_len, a->gl_comp_type, stride, pointer);
+ glVertexAttribIPointer(loc, a->comp_len, type, stride, pointer);
}
}
@@ -424,7 +422,7 @@ void immEnd(void)
GPU_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len);
/* TODO: resize only if vertex count is much smaller */
}
- GPU_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface);
+ GPU_batch_set_shader(imm.batch, imm.bound_program);
imm.batch->phase = GPU_BATCH_READY_TO_DRAW;
imm.batch = NULL; /* don't free, batch belongs to caller */
}
@@ -853,6 +851,18 @@ void immUniform4iv(const char *name, const int data[4])
glUniform4iv(uniform->location, 1, data);
}
+void immBindTexture(const char *name, GPUTexture *tex)
+{
+ GET_UNIFORM
+ GPU_texture_bind(tex, uniform->binding);
+}
+
+void immBindTextureSampler(const char *name, GPUTexture *tex, eGPUSamplerState state)
+{
+ GET_UNIFORM
+ GPU_texture_bind_ex(tex, state, uniform->binding, true);
+}
+
/* --- convenience functions for setting "uniform vec4 color" --- */
void immUniformColor4f(float r, float g, float b, float a)
@@ -921,6 +931,14 @@ void immUniformThemeColor(int color_id)
immUniformColor4fv(color);
}
+void immUniformThemeColorAlpha(int color_id, float a)
+{
+ float color[4];
+ UI_GetThemeColor3fv(color_id, color);
+ color[3] = a;
+ immUniformColor4fv(color);
+}
+
void immUniformThemeColor3(int color_id)
{
float color[3];
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 54ddb9351b9..c5061ec9ba3 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -95,7 +95,7 @@ void GPU_exit(void)
initialized = false;
}
-bool GPU_is_initialized(void)
+bool GPU_is_init(void)
{
return initialized;
}
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index d2384b9c065..f3477b6f3a4 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -85,7 +85,7 @@ struct GPUMaterial {
bool has_surface_output;
/* Only used by Eevee to know which bsdf are used. */
- int flag;
+ eGPUMatFlag flag;
/* Used by 2.8 pipeline */
GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */
@@ -497,8 +497,8 @@ static void compute_sss_translucence_kernel(const GPUSssKernelData *kd,
void GPU_material_sss_profile_create(GPUMaterial *material,
float radii[3],
- short *falloff_type,
- float *sharpness)
+ const short *falloff_type,
+ const float *sharpness)
{
copy_v3_v3(material->sss_radii, radii);
material->sss_falloff = (falloff_type) ? *falloff_type : 0.0;
@@ -659,7 +659,8 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
const char *geom_code,
const char *frag_lib,
const char *defines,
- const char *name)
+ const char *name,
+ GPUMaterialEvalCallbackFn callback)
{
LinkData *link;
bool has_volume_output, has_surface_output;
@@ -696,6 +697,9 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
mat->has_volume_output = has_volume_output;
if (mat->graph.outlink) {
+ if (callback) {
+ callback(mat, options, &vert_code, &geom_code, &frag_lib, &defines);
+ }
/* HACK: this is only for eevee. We add the define here after the nodetree evaluation. */
if (GPU_material_flag_get(mat, GPU_MATFLAG_SSS)) {
defines = BLI_string_joinN(defines,
diff --git a/source/blender/gpu/intern/gpu_material_library.h b/source/blender/gpu/intern/gpu_material_library.h
index f69c25b9490..da7b1636fa3 100644
--- a/source/blender/gpu/intern/gpu_material_library.h
+++ b/source/blender/gpu/intern/gpu_material_library.h
@@ -22,8 +22,7 @@
*
* Parsing of and code generation using GLSL shaders in gpu/shaders/material. */
-#ifndef __GPU_MATERIAL_LIBRARY_H__
-#define __GPU_MATERIAL_LIBRARY_H__
+#pragma once
#include "GPU_material.h"
@@ -65,5 +64,3 @@ char *gpu_material_library_generate_code(struct GSet *used_libraries, const char
char *gpu_str_skip_token(char *str, char *token, int max);
const char *gpu_data_type_to_string(const eGPUType type);
-
-#endif /* __ __GPU_MATERIAL_LIBRARY_H__ */
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.cc
index 2687f56ad27..c15bb1fba19 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.cc
@@ -37,8 +37,6 @@
#include "MEM_guardedalloc.h"
-#define DEBUG_MATRIX_BIND 0
-
#define MATRIX_STACK_DEPTH 32
typedef float Mat4[4][4];
@@ -79,7 +77,7 @@ GPUMatrixState *GPU_matrix_state_create(void)
} \
}
- GPUMatrixState *state = MEM_mallocN(sizeof(*state), __func__);
+ GPUMatrixState *state = (GPUMatrixState *)MEM_mallocN(sizeof(*state), __func__);
const MatrixStack identity_stack = {{MATRIX_4X4_IDENTITY}, 0};
state->model_view_stack = state->projection_stack = identity_stack;
@@ -536,13 +534,13 @@ bool GPU_matrix_unproject_precalc(struct GPUMatrixUnproject_Precalc *precalc,
const int view[4])
{
precalc->is_persp = proj[3][3] == 0.0f;
- projmat_dimensions(proj,
- &precalc->dims.xmin,
- &precalc->dims.xmax,
- &precalc->dims.ymin,
- &precalc->dims.ymax,
- &precalc->dims.zmin,
- &precalc->dims.zmax);
+ projmat_dimensions_db(proj,
+ &precalc->dims.xmin,
+ &precalc->dims.xmax,
+ &precalc->dims.ymin,
+ &precalc->dims.ymax,
+ &precalc->dims.zmin,
+ &precalc->dims.zmax);
if (isinf(precalc->dims.zmax)) {
/* We cannot retrieve the actual value of the clip_end.
* Use `FLT_MAX` to avoid nans. */
@@ -662,51 +660,32 @@ void GPU_matrix_bind(const GPUShaderInterface *shaderface)
int32_t MV_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW_INV);
int32_t P_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION_INV);
+ /* XXX(fclem) this works but this assumes shader is unused inside GPU_shader_uniform_vector. */
+ GPUShader *sh = NULL;
if (MV != -1) {
-#if DEBUG_MATRIX_BIND
- puts("setting MV matrix");
-#endif
-
- glUniformMatrix4fv(MV, 1, GL_FALSE, (const float *)GPU_matrix_model_view_get(NULL));
+ GPU_shader_uniform_vector(sh, MV, 16, 1, (const float *)GPU_matrix_model_view_get(NULL));
}
-
if (P != -1) {
-#if DEBUG_MATRIX_BIND
- puts("setting P matrix");
-#endif
-
- glUniformMatrix4fv(P, 1, GL_FALSE, (const float *)GPU_matrix_projection_get(NULL));
+ GPU_shader_uniform_vector(sh, P, 16, 1, (const float *)GPU_matrix_projection_get(NULL));
}
-
if (MVP != -1) {
-#if DEBUG_MATRIX_BIND
- puts("setting MVP matrix");
-#endif
-
- glUniformMatrix4fv(
- MVP, 1, GL_FALSE, (const float *)GPU_matrix_model_view_projection_get(NULL));
+ GPU_shader_uniform_vector(
+ sh, MVP, 16, 1, (const float *)GPU_matrix_model_view_projection_get(NULL));
}
-
if (N != -1) {
-#if DEBUG_MATRIX_BIND
- puts("setting normal matrix");
-#endif
-
- glUniformMatrix3fv(N, 1, GL_FALSE, (const float *)GPU_matrix_normal_get(NULL));
+ GPU_shader_uniform_vector(sh, N, 9, 1, (const float *)GPU_matrix_normal_get(NULL));
}
-
if (MV_inv != -1) {
Mat4 m;
GPU_matrix_model_view_get(m);
invert_m4(m);
- glUniformMatrix4fv(MV_inv, 1, GL_FALSE, (const float *)m);
+ GPU_shader_uniform_vector(sh, MV_inv, 16, 1, (const float *)m);
}
-
if (P_inv != -1) {
Mat4 m;
GPU_matrix_projection_get(m);
invert_m4(m);
- glUniformMatrix4fv(P_inv, 1, GL_FALSE, (const float *)m);
+ GPU_shader_uniform_vector(sh, P_inv, 16, 1, (const float *)m);
}
gpu_matrix_state_active_set_dirty(false);
@@ -738,3 +717,69 @@ int GPU_matrix_stack_level_get_projection(void)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Polygon Offset Hack
+ *
+ * Workaround the fact that polygon-offset is implementation dependent.
+ * We modify the projection matrix \a winmat in order to change the final depth a tiny amount.
+ * \{ */
+
+float GPU_polygon_offset_calc(const float (*winmat)[4], float viewdist, float dist)
+{
+ /* Seems like we have a factor of 2 more offset than 2.79 for some reason. Correct for this. */
+ dist *= 0.5f;
+
+ if (winmat[3][3] > 0.5f) {
+#if 1
+ return 0.00001f * dist * viewdist; // ortho tweaking
+#else
+ static float depth_fac = 0.0f;
+ if (depth_fac == 0.0f) {
+ int depthbits;
+ glGetIntegerv(GL_DEPTH_BITS, &depthbits);
+ depth_fac = 1.0f / (float)((1 << depthbits) - 1);
+ }
+ offs = (-1.0 / winmat[2][2]) * dist * depth_fac;
+
+ UNUSED_VARS(viewdist);
+#endif
+ }
+
+ /* This adjustment effectively results in reducing the Z value by 0.25%.
+ *
+ * winmat[4][3] actually evaluates to `-2 * far * near / (far - near)`,
+ * is very close to -0.2 with default clip range,
+ * and is used as the coefficient multiplied by `w / z`,
+ * thus controlling the z dependent part of the depth value.
+ */
+ return winmat[3][2] * -0.0025f * dist;
+}
+
+/**
+ * \note \a viewdist is only for ortho at the moment.
+ */
+void GPU_polygon_offset(float viewdist, float dist)
+{
+ static float winmat[4][4], offset = 0.0f;
+
+ if (dist != 0.0f) {
+ /* hack below is to mimic polygon offset */
+ GPU_matrix_projection_get(winmat);
+
+ /* dist is from camera to center point */
+
+ float offs = GPU_polygon_offset_calc(winmat, viewdist, dist);
+
+ winmat[3][2] -= offs;
+ offset += offs;
+ }
+ else {
+ winmat[3][2] += offset;
+ offset = 0.0;
+ }
+
+ GPU_matrix_projection_set(winmat);
+}
+
+/** \} */
diff --git a/source/blender/gpu/intern/gpu_matrix_private.h b/source/blender/gpu/intern/gpu_matrix_private.h
index 862ef065481..3448b0a95aa 100644
--- a/source/blender/gpu/intern/gpu_matrix_private.h
+++ b/source/blender/gpu/intern/gpu_matrix_private.h
@@ -18,8 +18,7 @@
* \ingroup gpu
*/
-#ifndef __GPU_MATRIX_PRIVATE_H__
-#define __GPU_MATRIX_PRIVATE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -31,5 +30,3 @@ void GPU_matrix_state_discard(struct GPUMatrixState *state);
#ifdef __cplusplus
}
#endif
-
-#endif /* __GPU_MATRIX_PRIVATE_H__ */
diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h
index 3067be1c485..7265abf4d65 100644
--- a/source/blender/gpu/intern/gpu_node_graph.h
+++ b/source/blender/gpu/intern/gpu_node_graph.h
@@ -23,13 +23,11 @@
* Intermediate node graph for generating GLSL shaders.
*/
-#ifndef __GPU_NODE_GRAPH_H__
-#define __GPU_NODE_GRAPH_H__
+#pragma once
#include "DNA_customdata_types.h"
#include "DNA_listBase.h"
-#include "GPU_glew.h"
#include "GPU_material.h"
#include "GPU_shader.h"
@@ -116,7 +114,7 @@ typedef struct GPUInput {
struct GPUInput *next, *prev;
GPUNode *node;
- eGPUType type; /* datatype */
+ eGPUType type; /* data-type. */
GPUNodeLink *link;
int id; /* unique id as created by code generator */
@@ -165,5 +163,3 @@ struct GPUTexture **gpu_material_ramp_texture_row_set(struct GPUMaterial *mat,
float *row);
struct GSet *gpu_material_used_libraries(struct GPUMaterial *material);
-
-#endif /* __GPU_NODE_GRAPH_H__ */
diff --git a/source/blender/gpu/intern/gpu_platform.c b/source/blender/gpu/intern/gpu_platform.cc
index 5cabde61bc3..5cabde61bc3 100644
--- a/source/blender/gpu/intern/gpu_platform.c
+++ b/source/blender/gpu/intern/gpu_platform.cc
diff --git a/source/blender/gpu/intern/gpu_primitive.c b/source/blender/gpu/intern/gpu_primitive.c
index 2285c1ab95b..3b11b38db87 100644
--- a/source/blender/gpu/intern/gpu_primitive.c
+++ b/source/blender/gpu/intern/gpu_primitive.c
@@ -26,35 +26,6 @@
#include "GPU_primitive.h"
#include "gpu_primitive_private.h"
-GPUPrimClass GPU_primtype_class(GPUPrimType prim_type)
-{
- static const GPUPrimClass classes[] = {
- [GPU_PRIM_POINTS] = GPU_PRIM_CLASS_POINT,
- [GPU_PRIM_LINES] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_LINE_STRIP] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_LINE_LOOP] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_TRIS] = GPU_PRIM_CLASS_SURFACE,
- [GPU_PRIM_TRI_STRIP] = GPU_PRIM_CLASS_SURFACE,
- [GPU_PRIM_TRI_FAN] = GPU_PRIM_CLASS_SURFACE,
-
- [GPU_PRIM_LINES_ADJ] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_LINE_STRIP_ADJ] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_TRIS_ADJ] = GPU_PRIM_CLASS_SURFACE,
-
- [GPU_PRIM_NONE] = GPU_PRIM_CLASS_NONE,
- };
-
- return classes[prim_type];
-}
-
-bool GPU_primtype_belongs_to_class(GPUPrimType prim_type, GPUPrimClass prim_class)
-{
- if (prim_class == GPU_PRIM_CLASS_NONE && prim_type == GPU_PRIM_NONE) {
- return true;
- }
- return prim_class & GPU_primtype_class(prim_type);
-}
-
GLenum convert_prim_type_to_gl(GPUPrimType prim_type)
{
#if TRUST_NO_ONE
diff --git a/source/blender/gpu/intern/gpu_primitive_private.h b/source/blender/gpu/intern/gpu_primitive_private.h
index abefa6abd20..e91eec18786 100644
--- a/source/blender/gpu/intern/gpu_primitive_private.h
+++ b/source/blender/gpu/intern/gpu_primitive_private.h
@@ -23,9 +23,15 @@
* GPU geometric primitives
*/
-#ifndef __GPU_PRIMITIVE_PRIVATE_H__
-#define __GPU_PRIMITIVE_PRIVATE_H__
+#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* TODO(fclem) move to OGL backend */
GLenum convert_prim_type_to_gl(GPUPrimType);
-#endif /* __GPU_PRIMITIVE_PRIVATE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h
index 7846bff87f4..ef96bedae4a 100644
--- a/source/blender/gpu/intern/gpu_private.h
+++ b/source/blender/gpu/intern/gpu_private.h
@@ -18,8 +18,11 @@
* \ingroup gpu
*/
-#ifndef __GPU_PRIVATE_H__
-#define __GPU_PRIVATE_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
/* call this before running any of the functions below */
void gpu_platform_init(void);
@@ -41,4 +44,6 @@ void gpu_framebuffer_module_exit(void);
void gpu_pbvh_init(void);
void gpu_pbvh_exit(void);
-#endif /* __GPU_PRIVATE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index 5766a176a96..c069cbe012f 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -26,7 +26,6 @@
#include <stdlib.h>
#include <string.h>
-#include "GPU_glew.h"
#include "GPU_select.h"
#include "MEM_guardedalloc.h"
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 4b38cd333a1..3025b5d66da 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -27,7 +27,6 @@
#include <stdlib.h>
#include <string.h>
-#include "GPU_draw.h"
#include "GPU_glew.h"
#include "GPU_immediate.h"
#include "GPU_select.h"
@@ -310,7 +309,7 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c
gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT);
/* disable writing to the framebuffer */
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ GPU_color_mask(false, false, false, false);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
@@ -320,7 +319,7 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c
glDepthFunc(GL_LEQUAL);
float viewport[4];
- glGetFloatv(GL_VIEWPORT, viewport);
+ GPU_viewport_size_get_f(viewport);
ps->src.clip_rect = *input;
ps->src.rect_len = rect_len;
@@ -330,7 +329,7 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c
ps->gl.clip_readpixels[2] = BLI_rcti_size_x(&ps->src.clip_rect);
ps->gl.clip_readpixels[3] = BLI_rcti_size_y(&ps->src.clip_rect);
- glViewport(UNPACK4(ps->gl.clip_readpixels));
+ GPU_viewport(UNPACK4(ps->gl.clip_readpixels));
/* It's possible we don't want to clear depth buffer,
* so existing elements are masked by current z-buffer. */
@@ -539,7 +538,7 @@ uint gpu_select_pick_end(void)
gpu_select_pick_load_id(ps->gl.prev_id, true);
}
gpuPopAttr();
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ GPU_color_mask(true, true, true, true);
}
/* assign but never free directly since it may be in cache */
diff --git a/source/blender/gpu/intern/gpu_select_private.h b/source/blender/gpu/intern/gpu_select_private.h
index a0619bd4293..e364b78bff2 100644
--- a/source/blender/gpu/intern/gpu_select_private.h
+++ b/source/blender/gpu/intern/gpu_select_private.h
@@ -23,8 +23,7 @@
* Selection implementations.
*/
-#ifndef __GPU_SELECT_PRIVATE_H__
-#define __GPU_SELECT_PRIVATE_H__
+#pragma once
/* gpu_select_pick */
void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, char mode);
@@ -43,5 +42,3 @@ bool gpu_select_query_load_id(uint id);
uint gpu_select_query_end(void);
#define SELECT_ID_NONE ((uint)0xffffffff)
-
-#endif /* __GPU_SELECT_PRIVATE_H__ */
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
index c82d1e17c66..70ad2f6759e 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.c
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -88,14 +88,14 @@ void gpu_select_query_begin(
gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT | GPU_SCISSOR_BIT);
/* disable writing to the framebuffer */
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ GPU_color_mask(false, false, false, false);
/* In order to save some fill rate we minimize the viewport using rect.
* We need to get the region of the viewport so that our geometry doesn't
* get rejected before the depth test. Should probably cull rect against
* the viewport but this is a rare case I think */
- glGetFloatv(GL_VIEWPORT, viewport);
- glViewport(viewport[0], viewport[1], BLI_rcti_size_x(input), BLI_rcti_size_y(input));
+ GPU_viewport_size_get_f(viewport);
+ GPU_viewport(viewport[0], viewport[1], BLI_rcti_size_x(input), BLI_rcti_size_y(input));
/* occlusion queries operates on fragments that pass tests and since we are interested on all
* objects in the view frustum independently of their order, we need to disable the depth test */
@@ -206,7 +206,7 @@ uint gpu_select_query_end(void)
MEM_freeN(g_query_state.queries);
MEM_freeN(g_query_state.id);
gpuPopAttr();
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ GPU_color_mask(true, true, true, true);
return hits;
}
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
new file mode 100644
index 00000000000..2b54e733bf5
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -0,0 +1,839 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math_base.h"
+#include "BLI_math_vector.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_appdir.h"
+#include "BKE_global.h"
+
+#include "DNA_space_types.h"
+
+#include "GPU_extensions.h"
+#include "GPU_matrix.h"
+#include "GPU_platform.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+#include "GPU_uniformbuffer.h"
+
+#include "gpu_shader_private.h"
+
+extern "C" char datatoc_gpu_shader_colorspace_lib_glsl[];
+
+/* Adjust these constants as needed. */
+#define MAX_DEFINE_LENGTH 256
+#define MAX_EXT_DEFINE_LENGTH 512
+
+#ifndef NDEBUG
+static uint g_shaderid = 0;
+#endif
+
+/* -------------------------------------------------------------------- */
+/** \name Convenience functions
+ * \{ */
+
+static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
+{
+ int line = 1;
+
+ fprintf(stderr, "GPUShader: %s error:\n", task);
+
+ for (int i = 0; i < totcode; i++) {
+ const char *c, *pos, *end = code[i] + strlen(code[i]);
+
+ if (G.debug & G_DEBUG) {
+ fprintf(stderr, "===== shader string %d ====\n", i + 1);
+
+ c = code[i];
+ while ((c < end) && (pos = strchr(c, '\n'))) {
+ fprintf(stderr, "%2d ", line);
+ fwrite(c, (pos + 1) - c, 1, stderr);
+ c = pos + 1;
+ line++;
+ }
+
+ fprintf(stderr, "%s", c);
+ }
+ }
+
+ fprintf(stderr, "%s\n", log);
+}
+
+static const char *gpu_shader_version(void)
+{
+ return "#version 330\n";
+}
+
+static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
+{
+ /* enable extensions for features that are not part of our base GLSL version
+ * don't use an extension for something already available!
+ */
+
+ if (GLEW_ARB_texture_gather) {
+ /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
+ * is reported to be supported but yield a compile error (see T55802). */
+ if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) {
+ strcat(defines, "#extension GL_ARB_texture_gather: enable\n");
+
+ /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
+ * shader so double check the preprocessor define (see T56544). */
+ if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
+ strcat(defines, "#ifdef GL_ARB_texture_gather\n");
+ strcat(defines, "# define GPU_ARB_texture_gather\n");
+ strcat(defines, "#endif\n");
+ }
+ else {
+ strcat(defines, "#define GPU_ARB_texture_gather\n");
+ }
+ }
+ }
+ if (GLEW_ARB_texture_query_lod) {
+ /* a #version 400 feature, but we use #version 330 maximum so use extension */
+ strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
+ }
+ if (GLEW_ARB_shader_draw_parameters) {
+ strcat(defines, "#extension GL_ARB_shader_draw_parameters : enable\n");
+ }
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ strcat(defines, "#extension GL_ARB_texture_cube_map_array : enable\n");
+ strcat(defines, "#define GPU_ARB_texture_cube_map_array\n");
+ }
+}
+
+static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
+{
+ /* some useful defines to detect GPU type */
+ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define GPU_ATI\n");
+ if (GPU_crappy_amd_driver()) {
+ strcat(defines, "#define GPU_DEPRECATED_AMD_DRIVER\n");
+ }
+ }
+ else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define GPU_NVIDIA\n");
+ }
+ else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define GPU_INTEL\n");
+ }
+
+ /* some useful defines to detect OS type */
+ if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_WIN, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define OS_WIN\n");
+ }
+ else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define OS_MAC\n");
+ }
+ else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_UNIX, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define OS_UNIX\n");
+ }
+
+ float derivatives_factors[2];
+ GPU_get_dfdy_factors(derivatives_factors);
+ if (derivatives_factors[0] == 1.0f) {
+ strcat(defines, "#define DFDX_SIGN 1.0\n");
+ }
+ else {
+ strcat(defines, "#define DFDX_SIGN -1.0\n");
+ }
+
+ if (derivatives_factors[1] == 1.0f) {
+ strcat(defines, "#define DFDY_SIGN 1.0\n");
+ }
+ else {
+ strcat(defines, "#define DFDY_SIGN -1.0\n");
+ }
+}
+
+#define DEBUG_SHADER_NONE ""
+#define DEBUG_SHADER_VERTEX "vert"
+#define DEBUG_SHADER_FRAGMENT "frag"
+#define DEBUG_SHADER_GEOMETRY "geom"
+
+/**
+ * Dump GLSL shaders to disk
+ *
+ * This is used for profiling shader performance externally and debug if shader code is correct.
+ * If called with no code, it simply bumps the shader index, so different shaders for the same
+ * program share the same index.
+ */
+static void gpu_dump_shaders(const char **code, const int num_shaders, const char *extension)
+{
+ if ((G.debug & G_DEBUG_GPU_SHADERS) == 0) {
+ return;
+ }
+
+ /* We use the same shader index for shaders in the same program.
+ * So we call this function once before calling for the individual shaders. */
+ static int shader_index = 0;
+ if (code == NULL) {
+ shader_index++;
+ BLI_assert(STREQ(DEBUG_SHADER_NONE, extension));
+ return;
+ }
+
+ /* Determine the full path of the new shader. */
+ char shader_path[FILE_MAX];
+
+ char file_name[512] = {'\0'};
+ sprintf(file_name, "%04d.%s", shader_index, extension);
+
+ BLI_join_dirfile(shader_path, sizeof(shader_path), BKE_tempdir_session(), file_name);
+
+ /* Write shader to disk. */
+ FILE *f = fopen(shader_path, "w");
+ if (f == NULL) {
+ printf("Error writing to file: %s\n", shader_path);
+ }
+ for (int j = 0; j < num_shaders; j++) {
+ fprintf(f, "%s", code[j]);
+ }
+ fclose(f);
+ printf("Shader file written to disk: %s\n", shader_path);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Creation / Destruction
+ * \{ */
+
+GPUShader *GPU_shader_create(const char *vertexcode,
+ const char *fragcode,
+ const char *geocode,
+ const char *libcode,
+ const char *defines,
+ const char *shname)
+{
+ return GPU_shader_create_ex(
+ vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, shname);
+}
+
+GPUShader *GPU_shader_create_from_python(const char *vertexcode,
+ const char *fragcode,
+ const char *geocode,
+ const char *libcode,
+ const char *defines)
+{
+ char *libcodecat = NULL;
+
+ if (libcode == NULL) {
+ libcode = datatoc_gpu_shader_colorspace_lib_glsl;
+ }
+ else {
+ libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl);
+ }
+
+ GPUShader *sh = GPU_shader_create_ex(
+ vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, NULL);
+
+ MEM_SAFE_FREE(libcodecat);
+ return sh;
+}
+
+GPUShader *GPU_shader_load_from_binary(const char *binary,
+ const int binary_format,
+ const int binary_len,
+ const char *shname)
+{
+ BLI_assert(GL_ARB_get_program_binary);
+ int success;
+ int program = glCreateProgram();
+
+ glProgramBinary(program, binary_format, binary, binary_len);
+ glGetProgramiv(program, GL_LINK_STATUS, &success);
+
+ if (success) {
+ glUseProgram(program);
+
+ GPUShader *shader = (GPUShader *)MEM_callocN(sizeof(*shader), __func__);
+ shader->interface = GPU_shaderinterface_create(program);
+ shader->program = program;
+
+#ifndef NDEBUG
+ BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
+#else
+ UNUSED_VARS(shname);
+#endif
+
+ return shader;
+ }
+
+ glDeleteProgram(program);
+ return NULL;
+}
+
+GPUShader *GPU_shader_create_ex(const char *vertexcode,
+ const char *fragcode,
+ const char *geocode,
+ const char *libcode,
+ const char *defines,
+ const eGPUShaderTFBType tf_type,
+ const char **tf_names,
+ const int tf_count,
+ const char *shname)
+{
+ GLint status;
+ GLchar log[5000];
+ GLsizei length = 0;
+ GPUShader *shader;
+ char standard_defines[MAX_DEFINE_LENGTH] = "";
+ char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
+
+ shader = (GPUShader *)MEM_callocN(sizeof(GPUShader), "GPUShader");
+ gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE);
+
+#ifndef NDEBUG
+ BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
+#else
+ UNUSED_VARS(shname);
+#endif
+
+ /* At least a vertex shader and a fragment shader are required. */
+ BLI_assert((fragcode != NULL) && (vertexcode != NULL));
+
+ if (vertexcode) {
+ shader->vertex = glCreateShader(GL_VERTEX_SHADER);
+ }
+ if (fragcode) {
+ shader->fragment = glCreateShader(GL_FRAGMENT_SHADER);
+ }
+ if (geocode) {
+ shader->geometry = glCreateShader(GL_GEOMETRY_SHADER);
+ }
+
+ shader->program = glCreateProgram();
+
+ if (!shader->program || (vertexcode && !shader->vertex) || (fragcode && !shader->fragment) ||
+ (geocode && !shader->geometry)) {
+ fprintf(stderr, "GPUShader, object creation failed.\n");
+ GPU_shader_free(shader);
+ return NULL;
+ }
+
+ gpu_shader_standard_defines(standard_defines);
+ gpu_shader_standard_extensions(standard_extensions);
+
+ if (vertexcode) {
+ const char *source[7];
+ /* custom limit, may be too small, beware */
+ int num_source = 0;
+
+ source[num_source++] = gpu_shader_version();
+ source[num_source++] =
+ "#define GPU_VERTEX_SHADER\n"
+ "#define IN_OUT out\n";
+ source[num_source++] = standard_extensions;
+ source[num_source++] = standard_defines;
+
+ if (geocode) {
+ source[num_source++] = "#define USE_GEOMETRY_SHADER\n";
+ }
+ if (defines) {
+ source[num_source++] = defines;
+ }
+ source[num_source++] = vertexcode;
+
+ gpu_dump_shaders(source, num_source, DEBUG_SHADER_VERTEX);
+
+ glAttachShader(shader->program, shader->vertex);
+ glShaderSource(shader->vertex, num_source, source, NULL);
+
+ glCompileShader(shader->vertex);
+ glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &status);
+
+ if (!status) {
+ glGetShaderInfoLog(shader->vertex, sizeof(log), &length, log);
+ shader_print_errors("compile", log, source, num_source);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+ }
+
+ if (fragcode) {
+ const char *source[8];
+ int num_source = 0;
+
+ source[num_source++] = gpu_shader_version();
+ source[num_source++] =
+ "#define GPU_FRAGMENT_SHADER\n"
+ "#define IN_OUT in\n";
+ source[num_source++] = standard_extensions;
+ source[num_source++] = standard_defines;
+
+ if (geocode) {
+ source[num_source++] = "#define USE_GEOMETRY_SHADER\n";
+ }
+ if (defines) {
+ source[num_source++] = defines;
+ }
+ if (libcode) {
+ source[num_source++] = libcode;
+ }
+ source[num_source++] = fragcode;
+
+ gpu_dump_shaders(source, num_source, DEBUG_SHADER_FRAGMENT);
+
+ glAttachShader(shader->program, shader->fragment);
+ glShaderSource(shader->fragment, num_source, source, NULL);
+
+ glCompileShader(shader->fragment);
+ glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &status);
+
+ if (!status) {
+ glGetShaderInfoLog(shader->fragment, sizeof(log), &length, log);
+ shader_print_errors("compile", log, source, num_source);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+ }
+
+ if (geocode) {
+ const char *source[6];
+ int num_source = 0;
+
+ source[num_source++] = gpu_shader_version();
+ source[num_source++] = "#define GPU_GEOMETRY_SHADER\n";
+ source[num_source++] = standard_extensions;
+ source[num_source++] = standard_defines;
+
+ if (defines) {
+ source[num_source++] = defines;
+ }
+ source[num_source++] = geocode;
+
+ gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY);
+
+ glAttachShader(shader->program, shader->geometry);
+ glShaderSource(shader->geometry, num_source, source, NULL);
+
+ glCompileShader(shader->geometry);
+ glGetShaderiv(shader->geometry, GL_COMPILE_STATUS, &status);
+
+ if (!status) {
+ glGetShaderInfoLog(shader->geometry, sizeof(log), &length, log);
+ shader_print_errors("compile", log, source, num_source);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+ }
+
+ if (tf_names != NULL) {
+ glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS);
+ /* Primitive type must be setup */
+ BLI_assert(tf_type != GPU_SHADER_TFB_NONE);
+ shader->feedback_transform_type = tf_type;
+ }
+
+ glLinkProgram(shader->program);
+ glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
+ if (!status) {
+ glGetProgramInfoLog(shader->program, sizeof(log), &length, log);
+ /* print attached shaders in pipeline order */
+ if (defines) {
+ shader_print_errors("linking", log, &defines, 1);
+ }
+ if (vertexcode) {
+ shader_print_errors("linking", log, &vertexcode, 1);
+ }
+ if (geocode) {
+ shader_print_errors("linking", log, &geocode, 1);
+ }
+ if (libcode) {
+ shader_print_errors("linking", log, &libcode, 1);
+ }
+ if (fragcode) {
+ shader_print_errors("linking", log, &fragcode, 1);
+ }
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+
+ glUseProgram(shader->program);
+ shader->interface = GPU_shaderinterface_create(shader->program);
+
+ return shader;
+}
+
+#undef DEBUG_SHADER_GEOMETRY
+#undef DEBUG_SHADER_FRAGMENT
+#undef DEBUG_SHADER_VERTEX
+#undef DEBUG_SHADER_NONE
+
+void GPU_shader_free(GPUShader *shader)
+{
+#if 0 /* Would be nice to have, but for now the Deferred compilation \
+ * does not have a GPUContext. */
+ BLI_assert(GPU_context_active_get() != NULL);
+#endif
+ BLI_assert(shader);
+
+ if (shader->vertex) {
+ glDeleteShader(shader->vertex);
+ }
+ if (shader->geometry) {
+ glDeleteShader(shader->geometry);
+ }
+ if (shader->fragment) {
+ glDeleteShader(shader->fragment);
+ }
+ if (shader->program) {
+ glDeleteProgram(shader->program);
+ }
+
+ if (shader->interface) {
+ GPU_shaderinterface_discard(shader->interface);
+ }
+
+ MEM_freeN(shader);
+}
+
+static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc)
+{
+ bool is_alloc = false;
+ if (str_arr == NULL) {
+ *r_is_alloc = false;
+ return NULL;
+ }
+ /* Skip empty strings (avoid alloc if we can). */
+ while (str_arr[0] && str_arr[0][0] == '\0') {
+ str_arr++;
+ }
+ int i;
+ for (i = 0; str_arr[i]; i++) {
+ if (i != 0 && str_arr[i][0] != '\0') {
+ is_alloc = true;
+ }
+ }
+ *r_is_alloc = is_alloc;
+ if (is_alloc) {
+ return BLI_string_join_arrayN(str_arr, i);
+ }
+ else {
+ return str_arr[0];
+ }
+}
+
+/**
+ * Use via #GPU_shader_create_from_arrays macro (avoids passing in param).
+ *
+ * Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader.
+ *
+ * It has the advantage that each item can be conditionally included
+ * without having to build the string inline, then free it.
+ *
+ * \param params: NULL terminated arrays of strings.
+ *
+ * Example:
+ * \code{.c}
+ * sh = GPU_shader_create_from_arrays({
+ * .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL},
+ * .geom = (const char *[]){shader_geom_glsl, NULL},
+ * .frag = (const char *[]){shader_frag_glsl, NULL},
+ * .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL},
+ * });
+ * \endcode
+ */
+struct GPUShader *GPU_shader_create_from_arrays_impl(
+ const struct GPU_ShaderCreateFromArray_Params *params)
+{
+ struct {
+ const char *str;
+ bool is_alloc;
+ } str_dst[4] = {{0}};
+ const char **str_src[4] = {params->vert, params->frag, params->geom, params->defs};
+
+ for (int i = 0; i < ARRAY_SIZE(str_src); i++) {
+ str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc);
+ }
+
+ GPUShader *sh = GPU_shader_create(
+ str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, __func__);
+
+ for (int i = 0; i < ARRAY_SIZE(str_dst); i++) {
+ if (str_dst[i].is_alloc) {
+ MEM_freeN((void *)str_dst[i].str);
+ }
+ }
+ return sh;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Binding
+ * \{ */
+
+void GPU_shader_bind(GPUShader *shader)
+{
+ BLI_assert(shader && shader->program);
+
+ glUseProgram(shader->program);
+ GPU_matrix_bind(shader->interface);
+ GPU_shader_set_srgb_uniform(shader->interface);
+}
+
+void GPU_shader_unbind(void)
+{
+ glUseProgram(0);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform feedback
+ * \{ */
+
+bool GPU_shader_transform_feedback_enable(GPUShader *shader, uint vbo_id)
+{
+ if (shader->feedback_transform_type == GPU_SHADER_TFB_NONE) {
+ return false;
+ }
+
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_id);
+
+ switch (shader->feedback_transform_type) {
+ case GPU_SHADER_TFB_POINTS:
+ glBeginTransformFeedback(GL_POINTS);
+ return true;
+ case GPU_SHADER_TFB_LINES:
+ glBeginTransformFeedback(GL_LINES);
+ return true;
+ case GPU_SHADER_TFB_TRIANGLES:
+ glBeginTransformFeedback(GL_TRIANGLES);
+ return true;
+ default:
+ return false;
+ }
+}
+
+void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader))
+{
+ glEndTransformFeedback();
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Uniforms / Resource location
+ * \{ */
+
+int GPU_shader_get_uniform(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name);
+ return uniform ? uniform->location : -1;
+}
+
+int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
+{
+ BLI_assert(shader && shader->program);
+ return GPU_shaderinterface_uniform_builtin(shader->interface,
+ static_cast<GPUUniformBuiltin>(builtin));
+}
+
+int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
+{
+ BLI_assert(shader && shader->program);
+ return GPU_shaderinterface_block_builtin(shader->interface,
+ static_cast<GPUUniformBlockBuiltin>(builtin));
+}
+
+int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
+ return ubo ? ubo->location : -1;
+}
+
+int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
+ return ubo ? ubo->binding : -1;
+}
+
+int GPU_shader_get_texture_binding(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *tex = GPU_shaderinterface_uniform(shader->interface, name);
+ return tex ? tex->binding : -1;
+}
+
+int GPU_shader_get_attribute(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *attr = GPU_shaderinterface_attr(shader->interface, name);
+ return attr ? attr->location : -1;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Getters
+ * \{ */
+
+/* Clement : Temp */
+int GPU_shader_get_program(GPUShader *shader)
+{
+ return (int)shader->program;
+}
+
+char *GPU_shader_get_binary(GPUShader *shader, uint *r_binary_format, int *r_binary_len)
+{
+ BLI_assert(GLEW_ARB_get_program_binary);
+ char *r_binary;
+ int binary_len = 0;
+
+ glGetProgramiv(shader->program, GL_PROGRAM_BINARY_LENGTH, &binary_len);
+ r_binary = (char *)MEM_mallocN(binary_len, __func__);
+ glGetProgramBinary(shader->program, binary_len, NULL, r_binary_format, r_binary);
+
+ if (r_binary_len) {
+ *r_binary_len = binary_len;
+ }
+
+ return r_binary;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Uniforms setters
+ * \{ */
+
+void GPU_shader_uniform_float(GPUShader *UNUSED(shader), int location, float value)
+{
+ if (location == -1) {
+ return;
+ }
+
+ glUniform1f(location, value);
+}
+
+void GPU_shader_uniform_vector(
+ GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
+{
+ if (location == -1 || value == NULL) {
+ return;
+ }
+
+ switch (length) {
+ case 1:
+ glUniform1fv(location, arraysize, value);
+ break;
+ case 2:
+ glUniform2fv(location, arraysize, value);
+ break;
+ case 3:
+ glUniform3fv(location, arraysize, value);
+ break;
+ case 4:
+ glUniform4fv(location, arraysize, value);
+ break;
+ case 9:
+ glUniformMatrix3fv(location, arraysize, 0, value);
+ break;
+ case 16:
+ glUniformMatrix4fv(location, arraysize, 0, value);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+}
+
+void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
+{
+ if (location == -1) {
+ return;
+ }
+
+ glUniform1i(location, value);
+}
+
+void GPU_shader_uniform_vector_int(
+ GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
+{
+ if (location == -1) {
+ return;
+ }
+
+ switch (length) {
+ case 1:
+ glUniform1iv(location, arraysize, value);
+ break;
+ case 2:
+ glUniform2iv(location, arraysize, value);
+ break;
+ case 3:
+ glUniform3iv(location, arraysize, value);
+ break;
+ case 4:
+ glUniform4iv(location, arraysize, value);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name sRGB Rendering Workaround
+ *
+ * The viewport overlay frame-buffer is sRGB and will expect shaders to output display referred
+ * Linear colors. But other frame-buffers (i.e: the area frame-buffers) are not sRGB and require
+ * the shader output color to be in sRGB space
+ * (assumed display encoded color-space as the time of writing).
+ * For this reason we have a uniform to switch the transform on and off depending on the current
+ * frame-buffer color-space.
+ * \{ */
+
+static int g_shader_builtin_srgb_transform = 0;
+
+void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface)
+{
+ int32_t loc = GPU_shaderinterface_uniform_builtin(interface, GPU_UNIFORM_SRGB_TRANSFORM);
+ if (loc != -1) {
+ glUniform1i(loc, g_shader_builtin_srgb_transform);
+ }
+}
+
+void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear)
+{
+ g_shader_builtin_srgb_transform = use_srgb_to_linear;
+}
+
+/** \} */
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader_builtin.c
index 711147a61e9..9c0692b76e2 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader_builtin.c
@@ -81,10 +81,7 @@ extern char datatoc_gpu_shader_image_overlays_stereo_merge_frag_glsl[];
extern char datatoc_gpu_shader_image_color_frag_glsl[];
extern char datatoc_gpu_shader_image_desaturate_frag_glsl[];
extern char datatoc_gpu_shader_image_varying_color_frag_glsl[];
-extern char datatoc_gpu_shader_image_alpha_color_frag_glsl[];
extern char datatoc_gpu_shader_image_shuffle_color_frag_glsl[];
-extern char datatoc_gpu_shader_image_mask_uniform_color_frag_glsl[];
-extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[];
extern char datatoc_gpu_shader_3D_vert_glsl[];
extern char datatoc_gpu_shader_3D_normal_vert_glsl[];
extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
@@ -156,11 +153,6 @@ const struct GPUShaderConfigData GPU_shader_cfg_data[GPU_SHADER_CFG_LEN] = {
/* cache of built-in shaders (each is created on first use) */
static GPUShader *builtin_shaders[GPU_SHADER_CFG_LEN][GPU_SHADER_BUILTIN_LEN] = {{NULL}};
-static int g_shader_builtin_srgb_transform = 0;
-
-#ifndef NDEBUG
-static uint g_shaderid = 0;
-#endif
typedef struct {
const char *vert;
@@ -171,725 +163,6 @@ typedef struct {
const char *defs;
} GPUShaderStages;
-static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
-{
- int line = 1;
-
- fprintf(stderr, "GPUShader: %s error:\n", task);
-
- for (int i = 0; i < totcode; i++) {
- const char *c, *pos, *end = code[i] + strlen(code[i]);
-
- if (G.debug & G_DEBUG) {
- fprintf(stderr, "===== shader string %d ====\n", i + 1);
-
- c = code[i];
- while ((c < end) && (pos = strchr(c, '\n'))) {
- fprintf(stderr, "%2d ", line);
- fwrite(c, (pos + 1) - c, 1, stderr);
- c = pos + 1;
- line++;
- }
-
- fprintf(stderr, "%s", c);
- }
- }
-
- fprintf(stderr, "%s\n", log);
-}
-
-static const char *gpu_shader_version(void)
-{
- return "#version 330\n";
-}
-
-static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
-{
- /* enable extensions for features that are not part of our base GLSL version
- * don't use an extension for something already available!
- */
-
- if (GLEW_ARB_texture_gather) {
- /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
- * is reported to be supported but yield a compile error (see T55802). */
- if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) {
- strcat(defines, "#extension GL_ARB_texture_gather: enable\n");
-
- /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
- * shader so double check the preprocessor define (see T56544). */
- if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
- strcat(defines, "#ifdef GL_ARB_texture_gather\n");
- strcat(defines, "# define GPU_ARB_texture_gather\n");
- strcat(defines, "#endif\n");
- }
- else {
- strcat(defines, "#define GPU_ARB_texture_gather\n");
- }
- }
- }
- if (GLEW_ARB_texture_query_lod) {
- /* a #version 400 feature, but we use #version 330 maximum so use extension */
- strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
- }
- if (GLEW_ARB_shader_draw_parameters) {
- strcat(defines, "#extension GL_ARB_shader_draw_parameters : enable\n");
- }
- if (GPU_arb_texture_cube_map_array_is_supported()) {
- strcat(defines, "#extension GL_ARB_texture_cube_map_array : enable\n");
- strcat(defines, "#define GPU_ARB_texture_cube_map_array\n");
- }
-}
-
-static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
-{
- /* some useful defines to detect GPU type */
- if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- strcat(defines, "#define GPU_ATI\n");
- if (GPU_crappy_amd_driver()) {
- strcat(defines, "#define GPU_DEPRECATED_AMD_DRIVER\n");
- }
- }
- else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- strcat(defines, "#define GPU_NVIDIA\n");
- }
- else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- strcat(defines, "#define GPU_INTEL\n");
- }
-
- /* some useful defines to detect OS type */
- if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_WIN, GPU_DRIVER_ANY)) {
- strcat(defines, "#define OS_WIN\n");
- }
- else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) {
- strcat(defines, "#define OS_MAC\n");
- }
- else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_UNIX, GPU_DRIVER_ANY)) {
- strcat(defines, "#define OS_UNIX\n");
- }
-
- float derivatives_factors[2];
- GPU_get_dfdy_factors(derivatives_factors);
- if (derivatives_factors[0] == 1.0f) {
- strcat(defines, "#define DFDX_SIGN 1.0\n");
- }
- else {
- strcat(defines, "#define DFDX_SIGN -1.0\n");
- }
-
- if (derivatives_factors[1] == 1.0f) {
- strcat(defines, "#define DFDY_SIGN 1.0\n");
- }
- else {
- strcat(defines, "#define DFDY_SIGN -1.0\n");
- }
-
- return;
-}
-
-GPUShader *GPU_shader_create(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines,
- const char *shname)
-{
- return GPU_shader_create_ex(
- vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, shname);
-}
-
-GPUShader *GPU_shader_create_from_python(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines)
-{
- char *libcodecat = NULL;
-
- if (libcode == NULL) {
- libcode = datatoc_gpu_shader_colorspace_lib_glsl;
- }
- else {
- libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl);
- }
-
- GPUShader *sh = GPU_shader_create_ex(
- vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, NULL);
-
- MEM_SAFE_FREE(libcodecat);
- return sh;
-}
-
-GPUShader *GPU_shader_load_from_binary(const char *binary,
- const int binary_format,
- const int binary_len,
- const char *shname)
-{
- BLI_assert(GL_ARB_get_program_binary);
- int success;
- int program = glCreateProgram();
-
- glProgramBinary(program, binary_format, binary, binary_len);
- glGetProgramiv(program, GL_LINK_STATUS, &success);
-
- if (success) {
- glUseProgram(program);
-
- GPUShader *shader = MEM_callocN(sizeof(*shader), __func__);
- shader->interface = GPU_shaderinterface_create(program);
- shader->program = program;
-
-#ifndef NDEBUG
- BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
-#else
- UNUSED_VARS(shname);
-#endif
-
- return shader;
- }
-
- glDeleteProgram(program);
- return NULL;
-}
-
-#define DEBUG_SHADER_NONE ""
-#define DEBUG_SHADER_VERTEX "vert"
-#define DEBUG_SHADER_FRAGMENT "frag"
-#define DEBUG_SHADER_GEOMETRY "geom"
-
-/**
- * Dump GLSL shaders to disk
- *
- * This is used for profiling shader performance externally and debug if shader code is correct.
- * If called with no code, it simply bumps the shader index, so different shaders for the same
- * program share the same index.
- */
-static void gpu_dump_shaders(const char **code, const int num_shaders, const char *extension)
-{
- if ((G.debug & G_DEBUG_GPU_SHADERS) == 0) {
- return;
- }
-
- /* We use the same shader index for shaders in the same program.
- * So we call this function once before calling for the individual shaders. */
- static int shader_index = 0;
- if (code == NULL) {
- shader_index++;
- BLI_assert(STREQ(DEBUG_SHADER_NONE, extension));
- return;
- }
-
- /* Determine the full path of the new shader. */
- char shader_path[FILE_MAX];
-
- char file_name[512] = {'\0'};
- sprintf(file_name, "%04d.%s", shader_index, extension);
-
- BLI_join_dirfile(shader_path, sizeof(shader_path), BKE_tempdir_session(), file_name);
-
- /* Write shader to disk. */
- FILE *f = fopen(shader_path, "w");
- if (f == NULL) {
- printf("Error writing to file: %s\n", shader_path);
- }
- for (int j = 0; j < num_shaders; j++) {
- fprintf(f, "%s", code[j]);
- }
- fclose(f);
- printf("Shader file written to disk: %s\n", shader_path);
-}
-
-GPUShader *GPU_shader_create_ex(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines,
- const eGPUShaderTFBType tf_type,
- const char **tf_names,
- const int tf_count,
- const char *shname)
-{
- GLint status;
- GLchar log[5000];
- GLsizei length = 0;
- GPUShader *shader;
- char standard_defines[MAX_DEFINE_LENGTH] = "";
- char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
-
- shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
- gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE);
-
-#ifndef NDEBUG
- BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
-#else
- UNUSED_VARS(shname);
-#endif
-
- /* At least a vertex shader and a fragment shader are required. */
- BLI_assert((fragcode != NULL) && (vertexcode != NULL));
-
- if (vertexcode) {
- shader->vertex = glCreateShader(GL_VERTEX_SHADER);
- }
- if (fragcode) {
- shader->fragment = glCreateShader(GL_FRAGMENT_SHADER);
- }
- if (geocode) {
- shader->geometry = glCreateShader(GL_GEOMETRY_SHADER);
- }
-
- shader->program = glCreateProgram();
-
- if (!shader->program || (vertexcode && !shader->vertex) || (fragcode && !shader->fragment) ||
- (geocode && !shader->geometry)) {
- fprintf(stderr, "GPUShader, object creation failed.\n");
- GPU_shader_free(shader);
- return NULL;
- }
-
- gpu_shader_standard_defines(standard_defines);
- gpu_shader_standard_extensions(standard_extensions);
-
- if (vertexcode) {
- const char *source[6];
- /* custom limit, may be too small, beware */
- int num_source = 0;
-
- source[num_source++] = gpu_shader_version();
- source[num_source++] = "#define GPU_VERTEX_SHADER\n";
- source[num_source++] = standard_extensions;
- source[num_source++] = standard_defines;
-
- if (defines) {
- source[num_source++] = defines;
- }
- source[num_source++] = vertexcode;
-
- gpu_dump_shaders(source, num_source, DEBUG_SHADER_VERTEX);
-
- glAttachShader(shader->program, shader->vertex);
- glShaderSource(shader->vertex, num_source, source, NULL);
-
- glCompileShader(shader->vertex);
- glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &status);
-
- if (!status) {
- glGetShaderInfoLog(shader->vertex, sizeof(log), &length, log);
- shader_print_errors("compile", log, source, num_source);
-
- GPU_shader_free(shader);
- return NULL;
- }
- }
-
- if (fragcode) {
- const char *source[7];
- int num_source = 0;
-
- source[num_source++] = gpu_shader_version();
- source[num_source++] = "#define GPU_FRAGMENT_SHADER\n";
- source[num_source++] = standard_extensions;
- source[num_source++] = standard_defines;
-
- if (defines) {
- source[num_source++] = defines;
- }
- if (libcode) {
- source[num_source++] = libcode;
- }
- source[num_source++] = fragcode;
-
- gpu_dump_shaders(source, num_source, DEBUG_SHADER_FRAGMENT);
-
- glAttachShader(shader->program, shader->fragment);
- glShaderSource(shader->fragment, num_source, source, NULL);
-
- glCompileShader(shader->fragment);
- glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &status);
-
- if (!status) {
- glGetShaderInfoLog(shader->fragment, sizeof(log), &length, log);
- shader_print_errors("compile", log, source, num_source);
-
- GPU_shader_free(shader);
- return NULL;
- }
- }
-
- if (geocode) {
- const char *source[6];
- int num_source = 0;
-
- source[num_source++] = gpu_shader_version();
- source[num_source++] = "#define GPU_GEOMETRY_SHADER\n";
- source[num_source++] = standard_extensions;
- source[num_source++] = standard_defines;
-
- if (defines) {
- source[num_source++] = defines;
- }
- source[num_source++] = geocode;
-
- gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY);
-
- glAttachShader(shader->program, shader->geometry);
- glShaderSource(shader->geometry, num_source, source, NULL);
-
- glCompileShader(shader->geometry);
- glGetShaderiv(shader->geometry, GL_COMPILE_STATUS, &status);
-
- if (!status) {
- glGetShaderInfoLog(shader->geometry, sizeof(log), &length, log);
- shader_print_errors("compile", log, source, num_source);
-
- GPU_shader_free(shader);
- return NULL;
- }
- }
-
- if (tf_names != NULL) {
- glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS);
- /* Primitive type must be setup */
- BLI_assert(tf_type != GPU_SHADER_TFB_NONE);
- shader->feedback_transform_type = tf_type;
- }
-
- glLinkProgram(shader->program);
- glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
- if (!status) {
- glGetProgramInfoLog(shader->program, sizeof(log), &length, log);
- /* print attached shaders in pipeline order */
- if (vertexcode) {
- shader_print_errors("linking", log, &vertexcode, 1);
- }
- if (geocode) {
- shader_print_errors("linking", log, &geocode, 1);
- }
- if (libcode) {
- shader_print_errors("linking", log, &libcode, 1);
- }
- if (fragcode) {
- shader_print_errors("linking", log, &fragcode, 1);
- }
-
- GPU_shader_free(shader);
- return NULL;
- }
-
- glUseProgram(shader->program);
- shader->interface = GPU_shaderinterface_create(shader->program);
-
- return shader;
-}
-
-#undef DEBUG_SHADER_GEOMETRY
-#undef DEBUG_SHADER_FRAGMENT
-#undef DEBUG_SHADER_VERTEX
-#undef DEBUG_SHADER_NONE
-
-static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc)
-{
- bool is_alloc = false;
- if (str_arr == NULL) {
- *r_is_alloc = false;
- return NULL;
- }
- /* Skip empty strings (avoid alloc if we can). */
- while (str_arr[0] && str_arr[0][0] == '\0') {
- str_arr++;
- }
- int i;
- for (i = 0; str_arr[i]; i++) {
- if (i != 0 && str_arr[i][0] != '\0') {
- is_alloc = true;
- }
- }
- *r_is_alloc = is_alloc;
- if (is_alloc) {
- return BLI_string_join_arrayN(str_arr, i);
- }
- else {
- return str_arr[0];
- }
-}
-
-/**
- * Use via #GPU_shader_create_from_arrays macro (avoids passing in param).
- *
- * Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader.
- *
- * It has the advantage that each item can be conditionally included
- * without having to build the string inline, then free it.
- *
- * \param params: NULL terminated arrays of strings.
- *
- * Example:
- * \code{.c}
- * sh = GPU_shader_create_from_arrays({
- * .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL},
- * .geom = (const char *[]){shader_geom_glsl, NULL},
- * .frag = (const char *[]){shader_frag_glsl, NULL},
- * .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL},
- * });
- * \endcode
- */
-struct GPUShader *GPU_shader_create_from_arrays_impl(
- const struct GPU_ShaderCreateFromArray_Params *params)
-{
- struct {
- const char *str;
- bool is_alloc;
- } str_dst[4] = {{0}};
- const char **str_src[4] = {params->vert, params->frag, params->geom, params->defs};
-
- for (int i = 0; i < ARRAY_SIZE(str_src); i++) {
- str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc);
- }
-
- GPUShader *sh = GPU_shader_create(
- str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, __func__);
-
- for (int i = 0; i < ARRAY_SIZE(str_dst); i++) {
- if (str_dst[i].is_alloc) {
- MEM_freeN((void *)str_dst[i].str);
- }
- }
- return sh;
-}
-
-void GPU_shader_bind(GPUShader *shader)
-{
- BLI_assert(shader && shader->program);
-
- glUseProgram(shader->program);
- GPU_matrix_bind(shader->interface);
- GPU_shader_set_srgb_uniform(shader->interface);
-}
-
-void GPU_shader_unbind(void)
-{
- glUseProgram(0);
-}
-
-bool GPU_shader_transform_feedback_enable(GPUShader *shader, uint vbo_id)
-{
- if (shader->feedback_transform_type == GPU_SHADER_TFB_NONE) {
- return false;
- }
-
- glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_id);
-
- switch (shader->feedback_transform_type) {
- case GPU_SHADER_TFB_POINTS:
- glBeginTransformFeedback(GL_POINTS);
- return true;
- case GPU_SHADER_TFB_LINES:
- glBeginTransformFeedback(GL_LINES);
- return true;
- case GPU_SHADER_TFB_TRIANGLES:
- glBeginTransformFeedback(GL_TRIANGLES);
- return true;
- default:
- return false;
- }
-}
-
-void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader))
-{
- glEndTransformFeedback();
-}
-
-void GPU_shader_free(GPUShader *shader)
-{
-#if 0 /* Would be nice to have, but for now the Deferred compilation \
- * does not have a GPUContext. */
- BLI_assert(GPU_context_active_get() != NULL);
-#endif
- BLI_assert(shader);
-
- if (shader->vertex) {
- glDeleteShader(shader->vertex);
- }
- if (shader->geometry) {
- glDeleteShader(shader->geometry);
- }
- if (shader->fragment) {
- glDeleteShader(shader->fragment);
- }
- if (shader->program) {
- glDeleteProgram(shader->program);
- }
-
- if (shader->interface) {
- GPU_shaderinterface_discard(shader->interface);
- }
-
- MEM_freeN(shader);
-}
-
-int GPU_shader_get_uniform(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name);
- return uniform ? uniform->location : -1;
-}
-
-int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
-{
- BLI_assert(shader && shader->program);
- return GPU_shaderinterface_uniform_builtin(shader->interface, builtin);
-}
-
-int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
-{
- BLI_assert(shader && shader->program);
- return GPU_shaderinterface_block_builtin(shader->interface, builtin);
-}
-
-int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
- return ubo ? ubo->location : -1;
-}
-
-int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
- return ubo ? ubo->binding : -1;
-}
-
-int GPU_shader_get_texture_binding(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *tex = GPU_shaderinterface_uniform(shader->interface, name);
- return tex ? tex->binding : -1;
-}
-
-void *GPU_shader_get_interface(GPUShader *shader)
-{
- return shader->interface;
-}
-
-/* Clement : Temp */
-int GPU_shader_get_program(GPUShader *shader)
-{
- return (int)shader->program;
-}
-
-void GPU_shader_uniform_float(GPUShader *UNUSED(shader), int location, float value)
-{
- if (location == -1) {
- return;
- }
-
- glUniform1f(location, value);
-}
-
-void GPU_shader_uniform_vector(
- GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
-{
- if (location == -1 || value == NULL) {
- return;
- }
-
- switch (length) {
- case 1:
- glUniform1fv(location, arraysize, value);
- break;
- case 2:
- glUniform2fv(location, arraysize, value);
- break;
- case 3:
- glUniform3fv(location, arraysize, value);
- break;
- case 4:
- glUniform4fv(location, arraysize, value);
- break;
- case 9:
- glUniformMatrix3fv(location, arraysize, 0, value);
- break;
- case 16:
- glUniformMatrix4fv(location, arraysize, 0, value);
- break;
- default:
- BLI_assert(0);
- break;
- }
-}
-
-void GPU_shader_uniform_vector_int(
- GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
-{
- if (location == -1) {
- return;
- }
-
- switch (length) {
- case 1:
- glUniform1iv(location, arraysize, value);
- break;
- case 2:
- glUniform2iv(location, arraysize, value);
- break;
- case 3:
- glUniform3iv(location, arraysize, value);
- break;
- case 4:
- glUniform4iv(location, arraysize, value);
- break;
- default:
- BLI_assert(0);
- break;
- }
-}
-
-void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
-{
- if (location == -1) {
- return;
- }
-
- glUniform1i(location, value);
-}
-
-void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface)
-{
- int32_t loc = GPU_shaderinterface_uniform_builtin(interface, GPU_UNIFORM_SRGB_TRANSFORM);
- if (loc != -1) {
- glUniform1i(loc, g_shader_builtin_srgb_transform);
- }
-}
-
-int GPU_shader_get_attribute(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *attr = GPU_shaderinterface_attr(shader->interface, name);
- return attr ? attr->location : -1;
-}
-
-char *GPU_shader_get_binary(GPUShader *shader, uint *r_binary_format, int *r_binary_len)
-{
- BLI_assert(GLEW_ARB_get_program_binary);
- char *r_binary;
- int binary_len = 0;
-
- glGetProgramiv(shader->program, GL_PROGRAM_BINARY_LENGTH, &binary_len);
- r_binary = MEM_mallocN(binary_len, __func__);
- glGetProgramBinary(shader->program, binary_len, NULL, r_binary_format, r_binary);
-
- if (r_binary_len) {
- *r_binary_len = binary_len;
- }
-
- return r_binary;
-}
-
-void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear)
-{
- g_shader_builtin_srgb_transform = use_srgb_to_linear;
-}
-
static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
[GPU_SHADER_TEXT] =
{
@@ -907,16 +180,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.frag = datatoc_gpu_shader_simple_lighting_frag_glsl,
},
- [GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR] =
- {
- .vert = datatoc_gpu_shader_3D_image_vert_glsl,
- .frag = datatoc_gpu_shader_image_mask_uniform_color_frag_glsl,
- },
- [GPU_SHADER_3D_IMAGE_MODULATE_ALPHA] =
- {
- .vert = datatoc_gpu_shader_3D_image_vert_glsl,
- .frag = datatoc_gpu_shader_image_modulate_alpha_frag_glsl,
- },
[GPU_SHADER_2D_CHECKER] =
{
.vert = datatoc_gpu_shader_2D_vert_glsl,
@@ -969,11 +232,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
.vert = datatoc_gpu_shader_2D_image_vert_glsl,
.frag = datatoc_gpu_shader_image_desaturate_frag_glsl,
},
- [GPU_SHADER_2D_IMAGE_ALPHA_COLOR] =
- {
- .vert = datatoc_gpu_shader_2D_image_vert_glsl,
- .frag = datatoc_gpu_shader_image_alpha_color_frag_glsl,
- },
[GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] =
{
.vert = datatoc_gpu_shader_2D_image_vert_glsl,
@@ -1258,6 +516,7 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader,
return *sh_p;
}
+
GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader)
{
return GPU_shader_get_builtin_shader_with_config(shader, GPU_SHADER_CFG_DEFAULT);
diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.cc
index 9d9f98c6bb0..4586b1ce814 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.c
+++ b/source/blender/gpu/intern/gpu_shader_interface.cc
@@ -47,47 +47,66 @@
static const char *BuiltinUniform_name(GPUUniformBuiltin u)
{
- static const char *names[] = {
- [GPU_UNIFORM_MODEL] = "ModelMatrix",
- [GPU_UNIFORM_VIEW] = "ViewMatrix",
- [GPU_UNIFORM_MODELVIEW] = "ModelViewMatrix",
- [GPU_UNIFORM_PROJECTION] = "ProjectionMatrix",
- [GPU_UNIFORM_VIEWPROJECTION] = "ViewProjectionMatrix",
- [GPU_UNIFORM_MVP] = "ModelViewProjectionMatrix",
-
- [GPU_UNIFORM_MODEL_INV] = "ModelMatrixInverse",
- [GPU_UNIFORM_VIEW_INV] = "ViewMatrixInverse",
- [GPU_UNIFORM_MODELVIEW_INV] = "ModelViewMatrixInverse",
- [GPU_UNIFORM_PROJECTION_INV] = "ProjectionMatrixInverse",
- [GPU_UNIFORM_VIEWPROJECTION_INV] = "ViewProjectionMatrixInverse",
-
- [GPU_UNIFORM_NORMAL] = "NormalMatrix",
- [GPU_UNIFORM_ORCO] = "OrcoTexCoFactors",
- [GPU_UNIFORM_CLIPPLANES] = "WorldClipPlanes",
-
- [GPU_UNIFORM_COLOR] = "color",
- [GPU_UNIFORM_BASE_INSTANCE] = "baseInstance",
- [GPU_UNIFORM_RESOURCE_CHUNK] = "resourceChunk",
- [GPU_UNIFORM_RESOURCE_ID] = "resourceId",
- [GPU_UNIFORM_SRGB_TRANSFORM] = "srgbTarget",
-
- [GPU_NUM_UNIFORMS] = NULL,
- };
-
- return names[u];
+ switch (u) {
+ case GPU_UNIFORM_MODEL:
+ return "ModelMatrix";
+ case GPU_UNIFORM_VIEW:
+ return "ViewMatrix";
+ case GPU_UNIFORM_MODELVIEW:
+ return "ModelViewMatrix";
+ case GPU_UNIFORM_PROJECTION:
+ return "ProjectionMatrix";
+ case GPU_UNIFORM_VIEWPROJECTION:
+ return "ViewProjectionMatrix";
+ case GPU_UNIFORM_MVP:
+ return "ModelViewProjectionMatrix";
+
+ case GPU_UNIFORM_MODEL_INV:
+ return "ModelMatrixInverse";
+ case GPU_UNIFORM_VIEW_INV:
+ return "ViewMatrixInverse";
+ case GPU_UNIFORM_MODELVIEW_INV:
+ return "ModelViewMatrixInverse";
+ case GPU_UNIFORM_PROJECTION_INV:
+ return "ProjectionMatrixInverse";
+ case GPU_UNIFORM_VIEWPROJECTION_INV:
+ return "ViewProjectionMatrixInverse";
+
+ case GPU_UNIFORM_NORMAL:
+ return "NormalMatrix";
+ case GPU_UNIFORM_ORCO:
+ return "OrcoTexCoFactors";
+ case GPU_UNIFORM_CLIPPLANES:
+ return "WorldClipPlanes";
+
+ case GPU_UNIFORM_COLOR:
+ return "color";
+ case GPU_UNIFORM_BASE_INSTANCE:
+ return "baseInstance";
+ case GPU_UNIFORM_RESOURCE_CHUNK:
+ return "resourceChunk";
+ case GPU_UNIFORM_RESOURCE_ID:
+ return "resourceId";
+ case GPU_UNIFORM_SRGB_TRANSFORM:
+ return "srgbTarget";
+
+ default:
+ return NULL;
+ }
}
static const char *BuiltinUniformBlock_name(GPUUniformBlockBuiltin u)
{
- static const char *names[] = {
- [GPU_UNIFORM_BLOCK_VIEW] = "viewBlock",
- [GPU_UNIFORM_BLOCK_MODEL] = "modelBlock",
- [GPU_UNIFORM_BLOCK_INFO] = "infoBlock",
-
- [GPU_NUM_UNIFORM_BLOCKS] = NULL,
- };
-
- return names[u];
+ switch (u) {
+ case GPU_UNIFORM_BLOCK_VIEW:
+ return "viewBlock";
+ case GPU_UNIFORM_BLOCK_MODEL:
+ return "modelBlock";
+ case GPU_UNIFORM_BLOCK_INFO:
+ return "infoBlock";
+ default:
+ return NULL;
+ }
}
GPU_INLINE bool match(const char *a, const char *b)
@@ -273,7 +292,7 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
/* Bit set to true if uniform comes from a uniform block. */
BLI_bitmap *uniforms_from_blocks = BLI_BITMAP_NEW(active_uniform_len, __func__);
/* Set uniforms from block for exclusion. */
- GLint *ubo_uni_ids = MEM_mallocN(sizeof(GLint) * max_ubo_uni_len, __func__);
+ GLint *ubo_uni_ids = (GLint *)MEM_mallocN(sizeof(GLint) * max_ubo_uni_len, __func__);
for (int i = 0; i < ubo_len; i++) {
GLint ubo_uni_len;
glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &ubo_uni_len);
@@ -291,16 +310,18 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
int input_tot_len = attr_len + ubo_len + uniform_len;
size_t interface_size = sizeof(GPUShaderInterface) + sizeof(GPUShaderInput) * input_tot_len;
- GPUShaderInterface *shaderface = MEM_callocN(interface_size, "GPUShaderInterface");
+ GPUShaderInterface *shaderface = (GPUShaderInterface *)MEM_callocN(interface_size,
+ "GPUShaderInterface");
shaderface->attribute_len = attr_len;
shaderface->ubo_len = ubo_len;
shaderface->uniform_len = uniform_len;
- shaderface->name_buffer = MEM_mallocN(name_buffer_len, "name_buffer");
+ shaderface->name_buffer = (char *)MEM_mallocN(name_buffer_len, "name_buffer");
GPUShaderInput *inputs = shaderface->inputs;
/* Temp buffer. */
int input_tmp_len = max_iii(attr_len, ubo_len, uniform_len);
- GPUShaderInput *inputs_tmp = MEM_mallocN(sizeof(GPUShaderInput) * input_tmp_len, "name_buffer");
+ GPUShaderInput *inputs_tmp = (GPUShaderInput *)MEM_mallocN(
+ sizeof(GPUShaderInput) * input_tmp_len, "name_buffer");
/* Attributes */
shaderface->enabled_attr_mask = 0;
@@ -366,27 +387,29 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
sort_input_list(inputs, inputs_tmp, shaderface->uniform_len);
/* Builtin Uniforms */
- for (GPUUniformBuiltin u = 0; u < GPU_NUM_UNIFORMS; u++) {
+ for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) {
+ GPUUniformBuiltin u = static_cast<GPUUniformBuiltin>(u_int);
shaderface->builtins[u] = glGetUniformLocation(program, BuiltinUniform_name(u));
}
/* Builtin Uniforms Blocks */
- for (GPUUniformBlockBuiltin u = 0; u < GPU_NUM_UNIFORM_BLOCKS; u++) {
+ for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORM_BLOCKS; u_int++) {
+ GPUUniformBlockBuiltin u = static_cast<GPUUniformBlockBuiltin>(u_int);
const GPUShaderInput *block = GPU_shaderinterface_ubo(shaderface, BuiltinUniformBlock_name(u));
shaderface->builtin_blocks[u] = (block != NULL) ? block->binding : -1;
}
/* Batches ref buffer */
shaderface->batches_len = GPU_SHADERINTERFACE_REF_ALLOC_COUNT;
- shaderface->batches = MEM_callocN(shaderface->batches_len * sizeof(GPUBatch *),
- "GPUShaderInterface batches");
+ shaderface->batches = (GPUBatch **)MEM_callocN(shaderface->batches_len * sizeof(GPUBatch *),
+ "GPUShaderInterface batches");
MEM_freeN(uniforms_from_blocks);
MEM_freeN(inputs_tmp);
/* Resize name buffer to save some memory. */
if (name_buffer_offset < name_buffer_len) {
- shaderface->name_buffer = MEM_reallocN(shaderface->name_buffer, name_buffer_offset);
+ shaderface->name_buffer = (char *)MEM_reallocN(shaderface->name_buffer, name_buffer_offset);
}
#if DEBUG_SHADER_INTERFACE
@@ -501,8 +524,8 @@ void GPU_shaderinterface_add_batch_ref(GPUShaderInterface *shaderface, GPUBatch
/* Not enough place, realloc the array. */
i = shaderface->batches_len;
shaderface->batches_len += GPU_SHADERINTERFACE_REF_ALLOC_COUNT;
- shaderface->batches = MEM_recallocN(shaderface->batches,
- sizeof(GPUBatch *) * shaderface->batches_len);
+ shaderface->batches = (GPUBatch **)MEM_recallocN(shaderface->batches,
+ sizeof(GPUBatch *) * shaderface->batches_len);
}
shaderface->batches[i] = batch;
}
diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h
index e4443e79a8d..0f89fbda737 100644
--- a/source/blender/gpu/intern/gpu_shader_private.h
+++ b/source/blender/gpu/intern/gpu_shader_private.h
@@ -18,12 +18,14 @@
* \ingroup gpu
*/
-#ifndef __GPU_SHADER_PRIVATE_H__
-#define __GPU_SHADER_PRIVATE_H__
+#pragma once
-#include "GPU_glew.h"
#include "GPU_shader_interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct GPUShader {
/** Handle for full program (links shader stages below). */
GLuint program;
@@ -45,6 +47,8 @@ struct GPUShader {
};
/* XXX do not use it. Special hack to use OCIO with batch API. */
-void immGetProgram(GLuint *program, GPUShaderInterface **shaderface);
+GPUShader *immGetShader(void);
-#endif /* __GPU_SHADER_PRIVATE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_state.c b/source/blender/gpu/intern/gpu_state.cc
index 30b258a73d1..794c7a3eb97 100644
--- a/source/blender/gpu/intern/gpu_state.c
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -78,6 +78,28 @@ void GPU_blend_set_func_separate(eGPUBlendFunction src_rgb,
gpu_get_gl_blendfunction(dst_alpha));
}
+void GPU_face_culling(eGPUFaceCull culling)
+{
+ if (culling == GPU_CULL_NONE) {
+ glDisable(GL_CULL_FACE);
+ }
+ else {
+ glEnable(GL_CULL_FACE);
+ glCullFace((culling == GPU_CULL_FRONT) ? GL_FRONT : GL_BACK);
+ }
+}
+
+void GPU_front_facing(bool invert)
+{
+ glFrontFace((invert) ? GL_CW : GL_CCW);
+}
+
+void GPU_provoking_vertex(eGPUProvokingVertex vert)
+{
+ glProvokingVertex((vert == GPU_VERTEX_FIRST) ? GL_FIRST_VERTEX_CONVENTION :
+ GL_LAST_VERTEX_CONVENTION);
+}
+
void GPU_depth_range(float near, float far)
{
/* glDepthRangef is only for OpenGL 4.1 or higher */
@@ -146,11 +168,26 @@ void GPU_program_point_size(bool enable)
}
}
+void GPU_scissor_test(bool enable)
+{
+ if (enable) {
+ glEnable(GL_SCISSOR_TEST);
+ }
+ else {
+ glDisable(GL_SCISSOR_TEST);
+ }
+}
+
void GPU_scissor(int x, int y, int width, int height)
{
glScissor(x, y, width, height);
}
+void GPU_viewport(int x, int y, int width, int height)
+{
+ glViewport(x, y, width, height);
+}
+
void GPU_scissor_get_f(float coords[4])
{
glGetFloatv(GL_SCISSOR_BOX, coords);
@@ -181,20 +218,62 @@ void GPU_finish(void)
glFinish();
}
-void GPU_logic_op_invert_set(bool enable)
+void GPU_unpack_row_length_set(uint len)
+{
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, len);
+}
+
+void GPU_logic_op_xor_set(bool enable)
{
if (enable) {
- glLogicOp(GL_INVERT);
+ glLogicOp(GL_XOR);
glEnable(GL_COLOR_LOGIC_OP);
- glDisable(GL_DITHER);
}
else {
- glLogicOp(GL_COPY);
glDisable(GL_COLOR_LOGIC_OP);
- glEnable(GL_DITHER);
}
}
+void GPU_color_mask(bool r, bool g, bool b, bool a)
+{
+ glColorMask(r, g, b, a);
+}
+
+void GPU_depth_mask(bool depth)
+{
+ glDepthMask(depth);
+}
+
+bool GPU_depth_mask_get(void)
+{
+ GLint mask;
+ glGetIntegerv(GL_DEPTH_WRITEMASK, &mask);
+ return mask == GL_TRUE;
+}
+
+void GPU_stencil_mask(uint stencil)
+{
+ glStencilMask(stencil);
+}
+
+void GPU_clip_distances(int distances_new)
+{
+ static int distances_enabled = 0;
+ for (int i = 0; i < distances_new; i++) {
+ glEnable(GL_CLIP_DISTANCE0 + i);
+ }
+ for (int i = distances_new; i < distances_enabled; i++) {
+ glDisable(GL_CLIP_DISTANCE0 + i);
+ }
+ distances_enabled = distances_new;
+}
+
+bool GPU_mipmap_enabled(void)
+{
+ /* TODO(fclem) this used to be a userdef option. */
+ return true;
+}
+
/** \name GPU Push/Pop State
* \{ */
@@ -203,34 +282,18 @@ void GPU_logic_op_invert_set(bool enable)
typedef struct {
eGPUAttrMask mask;
- /* GL_ENABLE_BIT */
+ /* GL_BLEND_BIT */
uint is_blend : 1;
- uint is_cull_face : 1;
- uint is_depth_test : 1;
- uint is_dither : 1;
- /* uint is_lighting : 1; */ /* UNUSED */
- uint is_line_smooth : 1;
- uint is_color_logic_op : 1;
- uint is_multisample : 1;
- uint is_polygon_offset_line : 1;
- uint is_polygon_offset_fill : 1;
- uint is_polygon_smooth : 1;
- uint is_sample_alpha_to_coverage : 1;
- uint is_scissor_test : 1;
- uint is_stencil_test : 1;
- uint is_framebuffer_srgb : 1;
-
- bool is_clip_plane[6];
/* GL_DEPTH_BUFFER_BIT */
- /* uint is_depth_test : 1; */
+ uint is_depth_test : 1;
int depth_func;
double depth_clear_value;
bool depth_write_mask;
/* GL_SCISSOR_BIT */
int scissor_box[4];
- /* uint is_scissor_test : 1; */
+ uint is_scissor_test : 1;
/* GL_VIEWPORT_BIT */
int viewport[4];
@@ -243,7 +306,8 @@ typedef struct {
} GPUAttrStack;
static GPUAttrStack state = {
- .top = 0,
+ {},
+ 0,
};
#define AttrStack state
@@ -266,27 +330,6 @@ void gpuPushAttr(eGPUAttrMask mask)
glGetBooleanv(GL_DEPTH_WRITEMASK, (GLboolean *)&Attr.depth_write_mask);
}
- if ((mask & GPU_ENABLE_BIT) != 0) {
- Attr.is_blend = glIsEnabled(GL_BLEND);
-
- for (int i = 0; i < 6; i++) {
- Attr.is_clip_plane[i] = glIsEnabled(GL_CLIP_PLANE0 + i);
- }
-
- Attr.is_cull_face = glIsEnabled(GL_CULL_FACE);
- Attr.is_depth_test = glIsEnabled(GL_DEPTH_TEST);
- Attr.is_dither = glIsEnabled(GL_DITHER);
- Attr.is_line_smooth = glIsEnabled(GL_LINE_SMOOTH);
- Attr.is_color_logic_op = glIsEnabled(GL_COLOR_LOGIC_OP);
- Attr.is_multisample = glIsEnabled(GL_MULTISAMPLE);
- Attr.is_polygon_offset_line = glIsEnabled(GL_POLYGON_OFFSET_LINE);
- Attr.is_polygon_offset_fill = glIsEnabled(GL_POLYGON_OFFSET_FILL);
- Attr.is_polygon_smooth = glIsEnabled(GL_POLYGON_SMOOTH);
- Attr.is_sample_alpha_to_coverage = glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE);
- Attr.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
- Attr.is_stencil_test = glIsEnabled(GL_STENCIL_TEST);
- }
-
if ((mask & GPU_SCISSOR_BIT) != 0) {
Attr.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
glGetIntegerv(GL_SCISSOR_BOX, (GLint *)&Attr.scissor_box);
@@ -295,7 +338,6 @@ void gpuPushAttr(eGPUAttrMask mask)
if ((mask & GPU_VIEWPORT_BIT) != 0) {
glGetDoublev(GL_DEPTH_RANGE, (GLdouble *)&Attr.near_far);
glGetIntegerv(GL_VIEWPORT, (GLint *)&Attr.viewport);
- Attr.is_framebuffer_srgb = glIsEnabled(GL_FRAMEBUFFER_SRGB);
}
if ((mask & GPU_BLEND_BIT) != 0) {
@@ -330,31 +372,9 @@ void gpuPopAttr(void)
glDepthMask(Attr.depth_write_mask);
}
- if ((mask & GPU_ENABLE_BIT) != 0) {
- restore_mask(GL_BLEND, Attr.is_blend);
-
- for (int i = 0; i < 6; i++) {
- restore_mask(GL_CLIP_PLANE0 + i, Attr.is_clip_plane[i]);
- }
-
- restore_mask(GL_CULL_FACE, Attr.is_cull_face);
- restore_mask(GL_DEPTH_TEST, Attr.is_depth_test);
- restore_mask(GL_DITHER, Attr.is_dither);
- restore_mask(GL_LINE_SMOOTH, Attr.is_line_smooth);
- restore_mask(GL_COLOR_LOGIC_OP, Attr.is_color_logic_op);
- restore_mask(GL_MULTISAMPLE, Attr.is_multisample);
- restore_mask(GL_POLYGON_OFFSET_LINE, Attr.is_polygon_offset_line);
- restore_mask(GL_POLYGON_OFFSET_FILL, Attr.is_polygon_offset_fill);
- restore_mask(GL_POLYGON_SMOOTH, Attr.is_polygon_smooth);
- restore_mask(GL_SAMPLE_ALPHA_TO_COVERAGE, Attr.is_sample_alpha_to_coverage);
- restore_mask(GL_SCISSOR_TEST, Attr.is_scissor_test);
- restore_mask(GL_STENCIL_TEST, Attr.is_stencil_test);
- }
-
if ((mask & GPU_VIEWPORT_BIT) != 0) {
glViewport(Attr.viewport[0], Attr.viewport[1], Attr.viewport[2], Attr.viewport[3]);
glDepthRange(Attr.near_far[0], Attr.near_far[1]);
- restore_mask(GL_FRAMEBUFFER_SRGB, Attr.is_framebuffer_srgb);
}
if ((mask & GPU_SCISSOR_BIT) != 0) {
@@ -396,6 +416,9 @@ void GPU_state_init(void)
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
/* Is default but better be explicit. */
glEnable(GL_MULTISAMPLE);
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.cc
index 56e82b94fd2..49812abe605 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_image_types.h"
+#include "DNA_userdef_types.h"
#include "BLI_blenlib.h"
#include "BLI_math_base.h"
@@ -36,7 +37,6 @@
#include "GPU_batch.h"
#include "GPU_context.h"
#include "GPU_debug.h"
-#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
#include "GPU_glew.h"
@@ -45,6 +45,16 @@
#include "gpu_context_private.h"
+#define WARN_NOT_BOUND(_tex) \
+ { \
+ if (_tex->number == -1) { \
+ fprintf(stderr, "Warning : Trying to set parameter on a texture not bound.\n"); \
+ BLI_assert(0); \
+ return; \
+ } \
+ } \
+ ((void)0)
+
static struct GPUTextureGlobal {
/** Texture used in place of invalid textures (not loaded correctly, missing). */
GPUTexture *invalid_tex_1D;
@@ -52,6 +62,7 @@ static struct GPUTextureGlobal {
GPUTexture *invalid_tex_3D;
/** Sampler objects used to replace internal texture parameters. */
GLuint samplers[GPU_SAMPLER_MAX];
+ GLuint icon_sampler;
} GG = {NULL};
/* Maximum number of FBOs a texture can be attached to. */
@@ -70,6 +81,8 @@ typedef enum eGPUTextureFormatFlag {
GPU_FORMAT_ARRAY = (1 << 14),
} eGPUTextureFormatFlag;
+ENUM_OPERATORS(eGPUTextureFormatFlag)
+
/* GPUTexture */
struct GPUTexture {
int w, h, d; /* width/height/depth */
@@ -102,7 +115,7 @@ static void gpu_texture_framebuffer_ensure(GPUTexture *tex);
/* ------ Memory Management ------- */
/* Records every texture allocation / free
* to estimate the Texture Pool Memory consumption */
-static uint memory_usage;
+static uint memory_usage = 0;
static uint gpu_texture_memory_footprint_compute(GPUTexture *tex)
{
@@ -160,54 +173,58 @@ uint GPU_texture_memory_usage_get(void)
static const char *gl_enum_to_str(GLenum e)
{
-#define ENUM_TO_STRING(e) [GL_##e] = STRINGIFY_ARG(e)
- static const char *enum_strings[] = {
- ENUM_TO_STRING(TEXTURE_CUBE_MAP),
- ENUM_TO_STRING(TEXTURE_CUBE_MAP_ARRAY),
- ENUM_TO_STRING(TEXTURE_2D),
- ENUM_TO_STRING(TEXTURE_2D_ARRAY),
- ENUM_TO_STRING(TEXTURE_1D),
- ENUM_TO_STRING(TEXTURE_1D_ARRAY),
- ENUM_TO_STRING(TEXTURE_3D),
- ENUM_TO_STRING(TEXTURE_2D_MULTISAMPLE),
- ENUM_TO_STRING(RGBA32F),
- ENUM_TO_STRING(RGBA16F),
- ENUM_TO_STRING(RGBA16UI),
- ENUM_TO_STRING(RGBA16I),
- ENUM_TO_STRING(RGBA16),
- ENUM_TO_STRING(RGBA8UI),
- ENUM_TO_STRING(RGBA8I),
- ENUM_TO_STRING(RGBA8),
- ENUM_TO_STRING(RGB16F),
- ENUM_TO_STRING(RG32F),
- ENUM_TO_STRING(RG16F),
- ENUM_TO_STRING(RG16UI),
- ENUM_TO_STRING(RG16I),
- ENUM_TO_STRING(RG16),
- ENUM_TO_STRING(RG8UI),
- ENUM_TO_STRING(RG8I),
- ENUM_TO_STRING(RG8),
- ENUM_TO_STRING(R8UI),
- ENUM_TO_STRING(R8I),
- ENUM_TO_STRING(R8),
- ENUM_TO_STRING(R32F),
- ENUM_TO_STRING(R32UI),
- ENUM_TO_STRING(R32I),
- ENUM_TO_STRING(R16F),
- ENUM_TO_STRING(R16UI),
- ENUM_TO_STRING(R16I),
- ENUM_TO_STRING(R16),
- ENUM_TO_STRING(R11F_G11F_B10F),
- ENUM_TO_STRING(SRGB8_ALPHA8),
- ENUM_TO_STRING(DEPTH24_STENCIL8),
- ENUM_TO_STRING(DEPTH32F_STENCIL8),
- ENUM_TO_STRING(DEPTH_COMPONENT32F),
- ENUM_TO_STRING(DEPTH_COMPONENT24),
- ENUM_TO_STRING(DEPTH_COMPONENT16),
+#define ENUM_TO_STRING(e) \
+ case GL_##e: { \
+ return STRINGIFY_ARG(e); \
+ }
+
+ switch (e) {
+ ENUM_TO_STRING(TEXTURE_CUBE_MAP);
+ ENUM_TO_STRING(TEXTURE_CUBE_MAP_ARRAY);
+ ENUM_TO_STRING(TEXTURE_2D);
+ ENUM_TO_STRING(TEXTURE_2D_ARRAY);
+ ENUM_TO_STRING(TEXTURE_1D);
+ ENUM_TO_STRING(TEXTURE_1D_ARRAY);
+ ENUM_TO_STRING(TEXTURE_3D);
+ ENUM_TO_STRING(TEXTURE_2D_MULTISAMPLE);
+ ENUM_TO_STRING(RGBA32F);
+ ENUM_TO_STRING(RGBA16F);
+ ENUM_TO_STRING(RGBA16UI);
+ ENUM_TO_STRING(RGBA16I);
+ ENUM_TO_STRING(RGBA16);
+ ENUM_TO_STRING(RGBA8UI);
+ ENUM_TO_STRING(RGBA8I);
+ ENUM_TO_STRING(RGBA8);
+ ENUM_TO_STRING(RGB16F);
+ ENUM_TO_STRING(RG32F);
+ ENUM_TO_STRING(RG16F);
+ ENUM_TO_STRING(RG16UI);
+ ENUM_TO_STRING(RG16I);
+ ENUM_TO_STRING(RG16);
+ ENUM_TO_STRING(RG8UI);
+ ENUM_TO_STRING(RG8I);
+ ENUM_TO_STRING(RG8);
+ ENUM_TO_STRING(R8UI);
+ ENUM_TO_STRING(R8I);
+ ENUM_TO_STRING(R8);
+ ENUM_TO_STRING(R32F);
+ ENUM_TO_STRING(R32UI);
+ ENUM_TO_STRING(R32I);
+ ENUM_TO_STRING(R16F);
+ ENUM_TO_STRING(R16UI);
+ ENUM_TO_STRING(R16I);
+ ENUM_TO_STRING(R16);
+ ENUM_TO_STRING(R11F_G11F_B10F);
+ ENUM_TO_STRING(SRGB8_ALPHA8);
+ ENUM_TO_STRING(DEPTH24_STENCIL8);
+ ENUM_TO_STRING(DEPTH32F_STENCIL8);
+ ENUM_TO_STRING(DEPTH_COMPONENT32F);
+ ENUM_TO_STRING(DEPTH_COMPONENT24);
+ ENUM_TO_STRING(DEPTH_COMPONENT16);
+ default:
+ return "Unkown enum";
};
#undef ENUM_TO_STRING
-
- return enum_strings[e];
}
static int gpu_get_component_count(eGPUTextureFormat format)
@@ -422,6 +439,13 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type)
case GPU_R8:
case GPU_R8UI:
return 1;
+ case GPU_SRGB8_A8_DXT1:
+ case GPU_SRGB8_A8_DXT3:
+ case GPU_SRGB8_A8_DXT5:
+ case GPU_RGBA8_DXT1:
+ case GPU_RGBA8_DXT3:
+ case GPU_RGBA8_DXT5:
+ return 1; /* Incorrect but actual size is fractional. */
default:
BLI_assert(!"Texture format incorrect or unsupported\n");
return 0;
@@ -507,7 +531,18 @@ static GLenum gpu_format_to_gl_internalformat(eGPUTextureFormat format)
case GPU_RGB16F:
return GL_RGB16F;
/* Special formats texture only */
- /* ** Add Format here */
+ case GPU_SRGB8_A8_DXT1:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
+ case GPU_SRGB8_A8_DXT3:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
+ case GPU_SRGB8_A8_DXT5:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
+ case GPU_RGBA8_DXT1:
+ return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ case GPU_RGBA8_DXT3:
+ return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ case GPU_RGBA8_DXT5:
+ return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
/* Depth Formats */
case GPU_DEPTH_COMPONENT32F:
return GL_DEPTH_COMPONENT32F;
@@ -521,99 +556,6 @@ static GLenum gpu_format_to_gl_internalformat(eGPUTextureFormat format)
}
}
-static eGPUTextureFormat gl_internalformat_to_gpu_format(const GLint glformat)
-{
- /* You can add any of the available type to this list
- * For available types see GPU_texture.h */
- switch (glformat) {
- /* Formats texture & renderbuffer */
- case GL_RGBA8UI:
- return GPU_RGBA8UI;
- case GL_RGBA8I:
- return GPU_RGBA8I;
- case GL_RGBA8:
- return GPU_RGBA8;
- case GL_RGBA32UI:
- return GPU_RGBA32UI;
- case GL_RGBA32I:
- return GPU_RGBA32I;
- case GL_RGBA32F:
- return GPU_RGBA32F;
- case GL_RGBA16UI:
- return GPU_RGBA16UI;
- case GL_RGBA16I:
- return GPU_RGBA16I;
- case GL_RGBA16F:
- return GPU_RGBA16F;
- case GL_RGBA16:
- return GPU_RGBA16;
- case GL_RG8UI:
- return GPU_RG8UI;
- case GL_RG8I:
- return GPU_RG8I;
- case GL_RG8:
- return GPU_RG8;
- case GL_RG32UI:
- return GPU_RG32UI;
- case GL_RG32I:
- return GPU_RG32I;
- case GL_RG32F:
- return GPU_RG32F;
- case GL_RG16UI:
- return GPU_RG16UI;
- case GL_RG16I:
- return GPU_RG16I;
- case GL_RG16F:
- return GPU_RGBA32F;
- case GL_RG16:
- return GPU_RG16;
- case GL_R8UI:
- return GPU_R8UI;
- case GL_R8I:
- return GPU_R8I;
- case GL_R8:
- return GPU_R8;
- case GL_R32UI:
- return GPU_R32UI;
- case GL_R32I:
- return GPU_R32I;
- case GL_R32F:
- return GPU_R32F;
- case GL_R16UI:
- return GPU_R16UI;
- case GL_R16I:
- return GPU_R16I;
- case GL_R16F:
- return GPU_R16F;
- case GL_R16:
- return GPU_R16;
- /* Special formats texture & renderbuffer */
- case GL_R11F_G11F_B10F:
- return GPU_R11F_G11F_B10F;
- case GL_DEPTH32F_STENCIL8:
- return GPU_DEPTH32F_STENCIL8;
- case GL_DEPTH24_STENCIL8:
- return GPU_DEPTH24_STENCIL8;
- case GL_SRGB8_ALPHA8:
- return GPU_SRGB8_A8;
- /* Texture only format */
- case GL_RGB16F:
- return GPU_RGB16F;
- /* Special formats texture only */
- /* ** Add Format here */
- /* Depth Formats */
- case GL_DEPTH_COMPONENT32F:
- return GPU_DEPTH_COMPONENT32F;
- case GL_DEPTH_COMPONENT24:
- return GPU_DEPTH_COMPONENT24;
- case GL_DEPTH_COMPONENT16:
- return GPU_DEPTH_COMPONENT16;
- default:
- BLI_assert(!"Internal format incorrect or unsupported\n");
- }
- return -1;
-}
-
static GLenum gpu_get_gl_datatype(eGPUDataFormat format)
{
switch (format) {
@@ -639,8 +581,8 @@ static float *GPU_texture_rescale_3d(
GPUTexture *tex, int w, int h, int d, int channels, const float *fpixels)
{
const uint xf = w / tex->w, yf = h / tex->h, zf = d / tex->d;
- float *nfpixels = MEM_mallocN(channels * sizeof(float) * tex->w * tex->h * tex->d,
- "GPUTexture Rescaled 3Dtex");
+ float *nfpixels = (float *)MEM_mallocN(channels * sizeof(float) * tex->w * tex->h * tex->d,
+ "GPUTexture Rescaled 3Dtex");
if (nfpixels) {
GPU_print_error_debug("You need to scale a 3D texture, feel the pain!");
@@ -732,6 +674,7 @@ static bool gpu_texture_check_capacity(
break;
case GL_PROXY_TEXTURE_1D_ARRAY:
case GL_PROXY_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_CUBE_MAP:
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL);
break;
case GL_PROXY_TEXTURE_2D_ARRAY:
@@ -739,6 +682,10 @@ static bool gpu_texture_check_capacity(
glTexImage3D(
proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL);
break;
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB:
+ glTexImage3D(
+ proxy, 0, internalformat, tex->w, tex->h, tex->d * 6, 0, data_format, data_type, NULL);
+ break;
}
int width = 0;
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &width);
@@ -763,8 +710,11 @@ static bool gpu_texture_try_alloc(GPUTexture *tex,
ret = gpu_texture_check_capacity(tex, proxy, internalformat, data_format, data_type);
if (!ret && try_rescale) {
- BLI_assert(
- !ELEM(proxy, GL_PROXY_TEXTURE_1D_ARRAY, GL_PROXY_TEXTURE_2D_ARRAY)); // not implemented
+ BLI_assert(!ELEM(proxy,
+ GL_PROXY_TEXTURE_1D_ARRAY,
+ GL_PROXY_TEXTURE_2D_ARRAY,
+ GL_PROXY_TEXTURE_CUBE_MAP,
+ GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB)); // not implemented
const int w = tex->w, h = tex->h, d = tex->d;
@@ -827,7 +777,7 @@ GPUTexture *GPU_texture_create_nD(int w,
tex_format = GPU_DEPTH32F_STENCIL8;
}
- GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
tex->w = w;
tex->h = h;
tex->d = d;
@@ -836,7 +786,7 @@ GPUTexture *GPU_texture_create_nD(int w,
tex->format = tex_format;
tex->components = gpu_get_component_count(tex_format);
tex->mipmaps = 0;
- tex->format_flag = 0;
+ tex->format_flag = static_cast<eGPUTextureFormatFlag>(0);
tex->number = -1;
if (n == 2) {
@@ -920,18 +870,20 @@ GPUTexture *GPU_texture_create_nD(int w,
data_type,
tex->components,
can_rescale,
- pixels,
+ (float *)pixels,
&rescaled_pixels);
if (G.debug & G_DEBUG_GPU || !valid) {
- printf("GPUTexture: create : %s, %s, w : %d, h : %d, d : %d, comp : %d, size : %.2f MiB\n",
- gl_enum_to_str(tex->target),
- gl_enum_to_str(internalformat),
- w,
- h,
- d,
- tex->components,
- gpu_texture_memory_footprint_compute(tex) / 1048576.0f);
+ printf(
+ "GPUTexture: create : %s,\t w : %5d, h : %5d, d : %5d, comp : %4d, size : %.2f "
+ "MiB,\t %s\n",
+ gl_enum_to_str(tex->target),
+ w,
+ h,
+ d,
+ tex->components,
+ gpu_texture_memory_footprint_compute(tex) / 1048576.0f,
+ gl_enum_to_str(internalformat));
}
if (!valid) {
@@ -951,7 +903,7 @@ GPUTexture *GPU_texture_create_nD(int w,
gpu_texture_memory_footprint_add(tex);
/* Upload Texture */
- const float *pix = (rescaled_pixels) ? rescaled_pixels : pixels;
+ const void *pix = (rescaled_pixels) ? rescaled_pixels : pixels;
if (tex->target == GL_TEXTURE_2D || tex->target == GL_TEXTURE_2D_MULTISAMPLE ||
tex->target == GL_TEXTURE_1D_ARRAY) {
@@ -1001,7 +953,7 @@ GPUTexture *GPU_texture_cube_create(int w,
eGPUDataFormat gpu_data_format,
char err_out[256])
{
- GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
tex->w = w;
tex->h = w;
tex->d = d;
@@ -1013,10 +965,14 @@ GPUTexture *GPU_texture_cube_create(int w,
tex->format_flag = GPU_FORMAT_CUBE;
tex->number = -1;
+ GLenum proxy;
+
if (d == 0) {
+ proxy = GL_PROXY_TEXTURE_CUBE_MAP;
tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP;
}
else {
+ proxy = GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB;
tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY_ARB;
tex->format_flag |= GPU_FORMAT_ARRAY;
@@ -1052,15 +1008,36 @@ GPUTexture *GPU_texture_cube_create(int w,
return NULL;
}
- if (G.debug & G_DEBUG_GPU) {
- printf("GPUTexture: create : %s, %s, w : %d, h : %d, d : %d, comp : %d, size : %.2f MiB\n",
- gl_enum_to_str(tex->target),
- gl_enum_to_str(internalformat),
- w,
- w,
- d,
- tex->components,
- gpu_texture_memory_footprint_compute(tex) / 1048576.0f);
+ bool valid = gpu_texture_try_alloc(
+ tex, proxy, internalformat, data_format, data_type, tex->components, false, NULL, NULL);
+
+ if (G.debug & G_DEBUG_GPU || !valid) {
+ printf(
+ "GPUTexture: create : %s,\t w : %5d, h : %5d, d : %5d, comp : %4d, size : %.2f "
+ "MiB,\t %s\n",
+ gl_enum_to_str(tex->target),
+ w,
+ w,
+ d * 6,
+ tex->components,
+ gpu_texture_memory_footprint_compute(tex) / 1048576.0f,
+ gl_enum_to_str(internalformat));
+ }
+
+ if (!valid) {
+ if (err_out) {
+ BLI_strncpy(err_out, "GPUTexture: texture alloc failed\n", 256);
+ }
+ else {
+ fprintf(stderr,
+ "GPUTexture: texture alloc failed. Likely not enough Video Memory or the requested "
+ "size is not supported by the implementation.\n");
+ fprintf(stderr,
+ "Current texture memory usage : %.2f MiB.\n",
+ gpu_texture_memory_footprint_compute(tex) / 1048576.0f);
+ }
+ GPU_texture_free(tex);
+ return NULL;
}
gpu_texture_memory_footprint_add(tex);
@@ -1125,11 +1102,11 @@ GPUTexture *GPU_texture_cube_create(int w,
/* Special buffer textures. tex_format must be compatible with the buffer content. */
GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint buffer)
{
- GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
tex->refcount = 1;
tex->format = tex_format;
tex->components = gpu_get_component_count(tex_format);
- tex->format_flag = 0;
+ tex->format_flag = static_cast<eGPUTextureFormatFlag>(0);
tex->target_base = tex->target = GL_TEXTURE_BUFFER;
tex->mipmaps = 0;
tex->number = -1;
@@ -1175,44 +1152,87 @@ GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint
return tex;
}
-GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode)
+static GLenum convert_target_to_gl(int dimension, bool is_array)
+{
+ switch (dimension) {
+ case 1:
+ return is_array ? GL_TEXTURE_1D : GL_TEXTURE_1D_ARRAY;
+ case 2:
+ return is_array ? GL_TEXTURE_2D : GL_TEXTURE_2D_ARRAY;
+ case 3:
+ return GL_TEXTURE_3D;
+ default:
+ BLI_assert(0);
+ return GL_TEXTURE_2D;
+ }
+}
+
+/* Create an error texture that will bind an invalid texture (pink) at draw time. */
+GPUTexture *GPU_texture_create_error(int dimension, bool is_array)
{
- GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
- tex->bindcode = bindcode;
+ GLenum textarget = convert_target_to_gl(dimension, is_array);
+
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
+ tex->bindcode = 0;
tex->refcount = 1;
tex->target = textarget;
tex->target_base = textarget;
tex->samples = 0;
- tex->sampler_state = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO;
- if (GPU_get_mipmap()) {
- tex->sampler_state |= (GPU_SAMPLER_MIPMAP | GPU_SAMPLER_FILTER);
- }
+ tex->sampler_state = GPU_SAMPLER_DEFAULT;
tex->number = -1;
- if (!glIsTexture(tex->bindcode)) {
- GPU_print_error_debug("Blender Texture Not Loaded");
+ GPU_print_error_debug("Blender Texture Not Loaded");
+ return tex;
+}
+
+/* DDS texture loading. Return NULL if support is not available. */
+GPUTexture *GPU_texture_create_compressed(
+ int w, int h, int miplen, eGPUTextureFormat tex_format, const void *data)
+{
+ if (!GLEW_EXT_texture_compression_s3tc) {
+ return NULL;
}
- else {
- GLint w, h, gl_format;
- GLenum gettarget;
- gettarget = (textarget == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : textarget;
-
- glBindTexture(textarget, tex->bindcode);
- glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_WIDTH, &w);
- glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_HEIGHT, &h);
- glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &gl_format);
- tex->w = w;
- tex->h = h;
- tex->format = gl_internalformat_to_gpu_format(gl_format);
- tex->components = gpu_get_component_count(tex->format);
- glBindTexture(textarget, 0);
-
- /* Depending on how this bindcode was obtained, the memory used here could
- * already have been computed.
- * But that is not the case currently. */
- gpu_texture_memory_footprint_add(tex);
+
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
+ tex->w = w;
+ tex->h = h;
+ tex->refcount = 1;
+ tex->target = tex->target_base = GL_TEXTURE_2D;
+ tex->format_flag = static_cast<eGPUTextureFormatFlag>(0);
+ tex->components = gpu_get_component_count(tex_format);
+ tex->mipmaps = miplen - 1;
+ tex->sampler_state = GPU_SAMPLER_DEFAULT;
+ tex->number = -1;
+
+ GLenum internalformat = gpu_format_to_gl_internalformat(tex_format);
+
+ glGenTextures(1, &tex->bindcode);
+ glBindTexture(tex->target, tex->bindcode);
+
+ /* Reset to opengl Defaults. (Untested, might not be needed) */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ int blocksize = (ELEM(tex_format, GPU_RGBA8_DXT1, GPU_SRGB8_A8_DXT1)) ? 8 : 16;
+
+ size_t ofs = 0;
+ for (int mip = 0; mip < miplen && (w || h); mip++, w >>= 1, h >>= 1) {
+ w = max_ii(1, w);
+ h = max_ii(1, h);
+ size_t size = ((w + 3) / 4) * ((h + 3) / 4) * blocksize;
+
+ glCompressedTexImage2D(tex->target, mip, internalformat, w, h, 0, size, (uchar *)data + ofs);
+
+ ofs += size;
}
+ /* Restore Blender default. */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glTexParameteri(tex->target, GL_TEXTURE_MAX_LEVEL, tex->mipmaps);
+ glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glBindTexture(tex->target, 0);
+
return tex;
}
@@ -1464,18 +1484,11 @@ void GPU_texture_update_sub(GPUTexture *tex,
BLI_assert((int)tex->format > -1);
BLI_assert(tex->components > -1);
- const uint bytesize = gpu_get_bytesize(tex->format);
GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
- GLint alignment;
- /* The default pack size for textures is 4, which won't work for byte based textures */
- if (bytesize == 1) {
- glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- }
+ WARN_NOT_BOUND(tex);
- glBindTexture(tex->target, tex->bindcode);
switch (tex->target) {
case GL_TEXTURE_1D:
glTexSubImage1D(tex->target, 0, offset_x, width, data_format, data_type, pixels);
@@ -1503,12 +1516,6 @@ void GPU_texture_update_sub(GPUTexture *tex,
default:
BLI_assert(!"tex->target mode not supported");
}
-
- if (bytesize == 1) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
- }
-
- glBindTexture(tex->target, 0);
}
void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat gpu_data_format, int miplvl)
@@ -1802,16 +1809,6 @@ void GPU_texture_unbind_all(void)
glActiveTexture(GL_TEXTURE0);
}
-#define WARN_NOT_BOUND(_tex) \
- { \
- if (_tex->number == -1) { \
- fprintf(stderr, "Warning : Trying to set parameter on a texture not bound.\n"); \
- BLI_assert(0); \
- return; \
- } \
- } \
- ((void)0)
-
void GPU_texture_generate_mipmap(GPUTexture *tex)
{
WARN_NOT_BOUND(tex);
@@ -1955,21 +1952,54 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter)
SET_FLAG_FROM_TEST(tex->sampler_state, use_filter, GPU_SAMPLER_FILTER);
}
+void GPU_texture_anisotropic_filter(GPUTexture *tex, bool use_aniso)
+{
+ /* Stencil and integer format does not support filtering. */
+ BLI_assert(!(use_aniso) || !(GPU_texture_stencil(tex) || GPU_texture_integer(tex)));
+
+ SET_FLAG_FROM_TEST(tex->sampler_state, use_aniso, GPU_SAMPLER_ANISO);
+}
+
void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp)
{
SET_FLAG_FROM_TEST(tex->sampler_state, use_repeat, GPU_SAMPLER_REPEAT);
SET_FLAG_FROM_TEST(tex->sampler_state, !use_clamp, GPU_SAMPLER_CLAMP_BORDER);
}
-void GPU_texture_swizzle_channel_auto(GPUTexture *tex, int channels)
+static int gpu_texture_swizzle_to_enum(const char swizzle)
+{
+ switch (swizzle) {
+ case 'w':
+ case 'a':
+ return GL_ALPHA;
+ case 'z':
+ case 'b':
+ return GL_BLUE;
+ case 'y':
+ case 'g':
+ return GL_GREEN;
+ case '0':
+ return GL_ZERO;
+ case '1':
+ return GL_ONE;
+ case 'x':
+ case 'r':
+ default:
+ return GL_RED;
+ }
+}
+
+void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4])
{
WARN_NOT_BOUND(tex);
+ GLint gl_swizzle[4] = {gpu_texture_swizzle_to_enum(swizzle[0]),
+ gpu_texture_swizzle_to_enum(swizzle[1]),
+ gpu_texture_swizzle_to_enum(swizzle[2]),
+ gpu_texture_swizzle_to_enum(swizzle[3])};
+
glActiveTexture(GL_TEXTURE0 + tex->number);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R, GL_RED);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G, (channels >= 2) ? GL_GREEN : GL_RED);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B, (channels >= 3) ? GL_BLUE : GL_RED);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, (channels >= 4) ? GL_ALPHA : GL_ONE);
+ glTexParameteriv(tex->target_base, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle);
}
void GPU_texture_free(GPUTexture *tex)
@@ -2144,7 +2174,7 @@ void GPU_samplers_init(void)
{
glGenSamplers(GPU_SAMPLER_MAX, GG.samplers);
for (int i = 0; i < GPU_SAMPLER_MAX; i++) {
- eGPUSamplerState state = i;
+ eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
GLenum clamp_type = (state & GPU_SAMPLER_CLAMP_BORDER) ? GL_CLAMP_TO_BORDER : GL_CLAMP_TO_EDGE;
GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? GL_REPEAT : clamp_type;
GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? GL_REPEAT : clamp_type;
@@ -2154,8 +2184,9 @@ void GPU_samplers_init(void)
((state & GPU_SAMPLER_MIPMAP) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) :
((state & GPU_SAMPLER_MIPMAP) ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST);
GLenum compare_mode = (state & GPU_SAMPLER_COMPARE) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE;
+ /* TODO(fclem) Anisotropic level should be a render engine parameter. */
float aniso_filter = ((state & GPU_SAMPLER_MIPMAP) && (state & GPU_SAMPLER_ANISO)) ?
- GPU_get_anisotropic() :
+ U.anisotropic_filter :
1.0f;
glSamplerParameteri(GG.samplers[i], GL_TEXTURE_WRAP_S, wrap_s);
@@ -2176,11 +2207,23 @@ void GPU_samplers_init(void)
* - GL_TEXTURE_LOD_BIAS is 0.0f.
**/
}
+
+ /* Custom sampler for icons. */
+ glGenSamplers(1, &GG.icon_sampler);
+ glSamplerParameteri(GG.icon_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ glSamplerParameteri(GG.icon_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glSamplerParameterf(GG.icon_sampler, GL_TEXTURE_LOD_BIAS, -0.5f);
+}
+
+void GPU_sampler_icon_bind(int unit)
+{
+ glBindSampler(unit, GG.icon_sampler);
}
void GPU_samplers_free(void)
{
glDeleteSamplers(GPU_SAMPLER_MAX, GG.samplers);
+ glDeleteSamplers(1, &GG.icon_sampler);
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.cc
index 130e8fe7da1..846ab6c8560 100644
--- a/source/blender/gpu/intern/gpu_uniformbuffer.c
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.cc
@@ -25,6 +25,7 @@
#include <string.h>
#include "BLI_blenlib.h"
+#include "BLI_math_base.h"
#include "gpu_context_private.h"
#include "gpu_node_graph.h"
@@ -34,217 +35,63 @@
#include "GPU_material.h"
#include "GPU_uniformbuffer.h"
-typedef enum eGPUUniformBufferFlag {
- GPU_UBO_FLAG_INITIALIZED = (1 << 0),
- GPU_UBO_FLAG_DIRTY = (1 << 1),
-} eGPUUniformBufferFlag;
-
-typedef enum eGPUUniformBufferType {
- GPU_UBO_STATIC = 0,
- GPU_UBO_DYNAMIC = 1,
-} eGPUUniformBufferType;
-
-struct GPUUniformBuffer {
- int size; /* in bytes */
- GLuint bindcode; /* opengl identifier for UBO */
- int bindpoint; /* current binding point */
- eGPUUniformBufferType type;
-};
-
-#define GPUUniformBufferStatic GPUUniformBuffer
-
-typedef struct GPUUniformBufferDynamic {
- GPUUniformBuffer buffer;
- void *data; /* Continuous memory block to copy to GPU. */
- char flag;
-} GPUUniformBufferDynamic;
-
-/* Prototypes */
-static eGPUType get_padded_gpu_type(struct LinkData *link);
-static void gpu_uniformbuffer_inputs_sort(struct ListBase *inputs);
-
-/* 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_MAT4
-
-static void gpu_uniformbuffer_initialize(GPUUniformBuffer *ubo, const void *data)
-{
- glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
- glBufferData(GL_UNIFORM_BUFFER, ubo->size, data, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
-}
+typedef struct GPUUniformBuffer {
+ /** Data size in bytes. */
+ int size;
+ /** GL handle for UBO. */
+ GLuint bindcode;
+ /** Current binding point. */
+ int bindpoint;
+ /** Continuous memory block to copy to GPU. Is own by the GPUUniformBuffer. */
+ void *data;
+} GPUUniformBuffer;
GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256])
{
/* Make sure that UBO is padded to size of vec4 */
BLI_assert((size % 16) == 0);
- GPUUniformBuffer *ubo = MEM_callocN(sizeof(GPUUniformBufferStatic), "GPUUniformBufferStatic");
- ubo->size = size;
- ubo->bindpoint = -1;
-
- /* Generate Buffer object */
- ubo->bindcode = GPU_buf_alloc();
-
- if (!ubo->bindcode) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256);
- }
- GPU_uniformbuffer_free(ubo);
- return NULL;
- }
-
- if (ubo->size > GPU_max_ubo_size()) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256);
- }
- GPU_uniformbuffer_free(ubo);
- return NULL;
- }
-
- gpu_uniformbuffer_initialize(ubo, data);
- return ubo;
-}
-
-/**
- * Create dynamic UBO from parameters
- * Return NULL if failed to create or if \param inputs: is empty.
- *
- * \param inputs: ListBase of #BLI_genericNodeN(#GPUInput).
- */
-GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_out[256])
-{
- /* There is no point on creating an UBO if there is no arguments. */
- if (BLI_listbase_is_empty(inputs)) {
- return NULL;
- }
-
- GPUUniformBufferDynamic *ubo = MEM_callocN(sizeof(GPUUniformBufferDynamic),
- "GPUUniformBufferDynamic");
- ubo->buffer.type = GPU_UBO_DYNAMIC;
- ubo->buffer.bindpoint = -1;
- ubo->flag = GPU_UBO_FLAG_DIRTY;
-
- /* Generate Buffer object. */
- ubo->buffer.bindcode = GPU_buf_alloc();
-
- if (!ubo->buffer.bindcode) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256);
- }
- GPU_uniformbuffer_free(&ubo->buffer);
- return NULL;
- }
-
- if (ubo->buffer.size > GPU_max_ubo_size()) {
+ if (size > GPU_max_ubo_size()) {
if (err_out) {
BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256);
}
- GPU_uniformbuffer_free(&ubo->buffer);
return NULL;
}
- /* Make sure we comply to the ubo alignment requirements. */
- gpu_uniformbuffer_inputs_sort(inputs);
-
- LISTBASE_FOREACH (LinkData *, link, inputs) {
- const eGPUType gputype = get_padded_gpu_type(link);
- ubo->buffer.size += gputype * sizeof(float);
- }
-
- /* Round up to size of vec4 */
- ubo->buffer.size = ((ubo->buffer.size + 15) / 16) * 16;
-
- /* Allocate the data. */
- ubo->data = MEM_mallocN(ubo->buffer.size, __func__);
+ GPUUniformBuffer *ubo = (GPUUniformBuffer *)MEM_mallocN(sizeof(GPUUniformBuffer), __func__);
+ ubo->size = size;
+ ubo->data = NULL;
+ ubo->bindcode = 0;
+ ubo->bindpoint = -1;
- /* Now that we know the total ubo size we can start populating it. */
- float *offset = ubo->data;
- LISTBASE_FOREACH (LinkData *, link, inputs) {
- GPUInput *input = link->data;
- memcpy(offset, input->vec, input->type * sizeof(float));
- offset += get_padded_gpu_type(link);
+ /* Direct init. */
+ if (data != NULL) {
+ GPU_uniformbuffer_update(ubo, data);
}
- /* 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
- */
-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);
- }
+ return ubo;
}
void GPU_uniformbuffer_free(GPUUniformBuffer *ubo)
{
- if (ubo->type == GPU_UBO_DYNAMIC) {
- gpu_uniformbuffer_dynamic_free(ubo);
- }
-
+ MEM_SAFE_FREE(ubo->data);
GPU_buf_free(ubo->bindcode);
MEM_freeN(ubo);
}
-static void gpu_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
-{
- glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
-}
-
-void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
-{
- BLI_assert(ubo->type == GPU_UBO_STATIC);
- gpu_uniformbuffer_update(ubo, data);
-}
-
-/**
- * We need to recalculate the internal data, and re-generate it
- * from its populated items.
- */
-void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_)
-{
- BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
- GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
-
- if (ubo->flag & GPU_UBO_FLAG_INITIALIZED) {
- gpu_uniformbuffer_update(ubo_, ubo->data);
- }
- else {
- ubo->flag |= GPU_UBO_FLAG_INITIALIZED;
- gpu_uniformbuffer_initialize(ubo_, ubo->data);
- }
-
- ubo->flag &= ~GPU_UBO_FLAG_DIRTY;
-}
-
/**
* We need to pad some data types (vec3) on the C side
* To match the GPU expected memory block alignment.
*/
static eGPUType get_padded_gpu_type(LinkData *link)
{
- GPUInput *input = link->data;
+ GPUInput *input = (GPUInput *)link->data;
eGPUType gputype = input->type;
-
/* Unless the vec3 is followed by a float we need to treat it as a vec4. */
if (gputype == GPU_VEC3 && (link->next != NULL) &&
(((GPUInput *)link->next->data)->type != GPU_FLOAT)) {
gputype = GPU_VEC4;
}
-
return gputype;
}
@@ -254,8 +101,9 @@ static eGPUType get_padded_gpu_type(LinkData *link)
*/
static int inputs_cmp(const void *a, const void *b)
{
- const LinkData *link_a = a, *link_b = b;
- const GPUInput *input_a = link_a->data, *input_b = link_b->data;
+ const LinkData *link_a = (const LinkData *)a, *link_b = (const LinkData *)b;
+ const GPUInput *input_a = (const GPUInput *)link_a->data;
+ const GPUInput *input_b = (const GPUInput *)link_b->data;
return input_a->type < input_b->type ? 1 : 0;
}
@@ -265,15 +113,19 @@ static int inputs_cmp(const void *a, const void *b)
*/
static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
{
+/* 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_MAT4
+
/* Order them as mat4, vec4, vec3, vec2, float. */
BLI_listbase_sort(inputs, inputs_cmp);
/* Creates a lookup table for the different types; */
LinkData *inputs_lookup[MAX_UBO_GPU_TYPE + 1] = {NULL};
- eGPUType cur_type = MAX_UBO_GPU_TYPE + 1;
+ eGPUType cur_type = static_cast<eGPUType>(MAX_UBO_GPU_TYPE + 1);
LISTBASE_FOREACH (LinkData *, link, inputs) {
- GPUInput *input = link->data;
+ GPUInput *input = (GPUInput *)link->data;
if (input->type == GPU_MAT3) {
/* Alignment for mat3 is not handled currently, so not supported */
@@ -319,6 +171,74 @@ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
link = link_next;
}
+#undef MAX_UBO_GPU_TYPE
+}
+
+/**
+ * Create dynamic UBO from parameters
+ * Return NULL if failed to create or if \param inputs: is empty.
+ *
+ * \param inputs: ListBase of #BLI_genericNodeN(#GPUInput).
+ */
+GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_out[256])
+{
+ /* There is no point on creating an UBO if there is no arguments. */
+ if (BLI_listbase_is_empty(inputs)) {
+ return NULL;
+ }
+ /* Make sure we comply to the ubo alignment requirements. */
+ gpu_uniformbuffer_inputs_sort(inputs);
+
+ size_t buffer_size = 0;
+
+ LISTBASE_FOREACH (LinkData *, link, inputs) {
+ const eGPUType gputype = get_padded_gpu_type(link);
+ buffer_size += gputype * sizeof(float);
+ }
+ /* Round up to size of vec4. (Opengl Requirement) */
+ size_t alignment = sizeof(float[4]);
+ buffer_size = divide_ceil_u(buffer_size, alignment) * alignment;
+ void *data = MEM_mallocN(buffer_size, __func__);
+
+ /* Now that we know the total ubo size we can start populating it. */
+ float *offset = (float *)data;
+ LISTBASE_FOREACH (LinkData *, link, inputs) {
+ GPUInput *input = (GPUInput *)link->data;
+ memcpy(offset, input->vec, input->type * sizeof(float));
+ offset += get_padded_gpu_type(link);
+ }
+
+ /* Pass data as NULL for late init. */
+ GPUUniformBuffer *ubo = GPU_uniformbuffer_create(buffer_size, NULL, err_out);
+ /* Data will be update just before binding. */
+ ubo->data = data;
+ return ubo;
+}
+
+static void gpu_uniformbuffer_init(GPUUniformBuffer *ubo)
+{
+ BLI_assert(ubo->bindcode == 0);
+ ubo->bindcode = GPU_buf_alloc();
+
+ if (ubo->bindcode == 0) {
+ fprintf(stderr, "GPUUniformBuffer: UBO create failed");
+ BLI_assert(0);
+ return;
+ }
+
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferData(GL_UNIFORM_BUFFER, ubo->size, NULL, GL_DYNAMIC_DRAW);
+}
+
+void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
+{
+ if (ubo->bindcode == 0) {
+ gpu_uniformbuffer_init(ubo);
+ }
+
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
@@ -328,28 +248,30 @@ void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
return;
}
- if (ubo->type == GPU_UBO_DYNAMIC) {
- GPUUniformBufferDynamic *ubo_dynamic = (GPUUniformBufferDynamic *)ubo;
- if (ubo_dynamic->flag & GPU_UBO_FLAG_DIRTY) {
- GPU_uniformbuffer_dynamic_update(ubo);
- }
+ if (ubo->bindcode == 0) {
+ gpu_uniformbuffer_init(ubo);
}
- if (ubo->bindcode != 0) {
- glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode);
+ if (ubo->data != NULL) {
+ GPU_uniformbuffer_update(ubo, ubo->data);
+ MEM_SAFE_FREE(ubo->data);
}
+ glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode);
ubo->bindpoint = number;
}
void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo)
{
- ubo->bindpoint = -1;
+#ifndef NDEBUG
+ glBindBufferBase(GL_UNIFORM_BUFFER, ubo->bindpoint, 0);
+#endif
+ ubo->bindpoint = 0;
}
-int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo)
+void GPU_uniformbuffer_unbind_all(void)
{
- return ubo->bindpoint;
+ for (int i = 0; i < GPU_max_ubo_binds(); i++) {
+ glBindBufferBase(GL_UNIFORM_BUFFER, i, 0);
+ }
}
-
-#undef MAX_UBO_GPU_TYPE
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.cc
index 3b4d469542c..eda6d1c7300 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer.c
+++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc
@@ -39,17 +39,22 @@ static uint vbo_memory_usage;
static GLenum convert_usage_type_to_gl(GPUUsageType type)
{
- static const GLenum table[] = {
- [GPU_USAGE_STREAM] = GL_STREAM_DRAW,
- [GPU_USAGE_STATIC] = GL_STATIC_DRAW,
- [GPU_USAGE_DYNAMIC] = GL_DYNAMIC_DRAW,
- };
- return table[type];
+ switch (type) {
+ case GPU_USAGE_STREAM:
+ return GL_STREAM_DRAW;
+ case GPU_USAGE_DYNAMIC:
+ return GL_DYNAMIC_DRAW;
+ case GPU_USAGE_STATIC:
+ return GL_STATIC_DRAW;
+ default:
+ BLI_assert(0);
+ return GL_STATIC_DRAW;
+ }
}
GPUVertBuf *GPU_vertbuf_create(GPUUsageType usage)
{
- GPUVertBuf *verts = MEM_mallocN(sizeof(GPUVertBuf), "GPUVertBuf");
+ GPUVertBuf *verts = (GPUVertBuf *)MEM_mallocN(sizeof(GPUVertBuf), "GPUVertBuf");
GPU_vertbuf_init(verts, usage);
return verts;
}
@@ -109,7 +114,7 @@ GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts)
}
if (verts->data) {
- verts_dst->data = MEM_dupallocN(verts->data);
+ verts_dst->data = (uchar *)MEM_dupallocN(verts->data);
}
return verts_dst;
}
@@ -161,7 +166,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len)
#endif
verts->dirty = true;
verts->vertex_len = verts->vertex_alloc = v_len;
- verts->data = MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), "GPUVertBuf data");
+ verts->data = (uchar *)MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), __func__);
}
/* resize buffer keeping existing data */
@@ -178,7 +183,7 @@ void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len)
#endif
verts->dirty = true;
verts->vertex_len = verts->vertex_alloc = v_len;
- verts->data = MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts));
+ verts->data = (uchar *)MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts));
}
/* Set vertex count but does not change allocation.
diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.cc
index 585a22277b2..a59a6a468ce 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.c
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -63,21 +63,29 @@ void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat *src)
memcpy(dest, src, sizeof(GPUVertFormat));
}
-static GLenum convert_comp_type_to_gl(GPUVertCompType type)
+GLenum convert_comp_type_to_gl(GPUVertCompType type)
{
- static const GLenum table[] = {
- [GPU_COMP_I8] = GL_BYTE,
- [GPU_COMP_U8] = GL_UNSIGNED_BYTE,
- [GPU_COMP_I16] = GL_SHORT,
- [GPU_COMP_U16] = GL_UNSIGNED_SHORT,
- [GPU_COMP_I32] = GL_INT,
- [GPU_COMP_U32] = GL_UNSIGNED_INT,
-
- [GPU_COMP_F32] = GL_FLOAT,
-
- [GPU_COMP_I10] = GL_INT_2_10_10_10_REV,
- };
- return table[type];
+ switch (type) {
+ case GPU_COMP_I8:
+ return GL_BYTE;
+ case GPU_COMP_U8:
+ return GL_UNSIGNED_BYTE;
+ case GPU_COMP_I16:
+ return GL_SHORT;
+ case GPU_COMP_U16:
+ return GL_UNSIGNED_SHORT;
+ case GPU_COMP_I32:
+ return GL_INT;
+ case GPU_COMP_U32:
+ return GL_UNSIGNED_INT;
+ case GPU_COMP_F32:
+ return GL_FLOAT;
+ case GPU_COMP_I10:
+ return GL_INT_2_10_10_10_REV;
+ default:
+ BLI_assert(0);
+ return GL_FLOAT;
+ }
}
static uint comp_sz(GPUVertCompType type)
@@ -94,7 +102,7 @@ static uint attr_sz(const GPUVertAttr *a)
if (a->comp_type == GPU_COMP_I10) {
return 4; /* always packed as 10_10_10_2 */
}
- return a->comp_len * comp_sz(a->comp_type);
+ return a->comp_len * comp_sz(static_cast<GPUVertCompType>(a->comp_type));
}
static uint attr_align(const GPUVertAttr *a)
@@ -102,7 +110,7 @@ static uint attr_align(const GPUVertAttr *a)
if (a->comp_type == GPU_COMP_I10) {
return 4; /* always packed as 10_10_10_2 */
}
- uint c = comp_sz(a->comp_type);
+ uint c = comp_sz(static_cast<GPUVertCompType>(a->comp_type));
if (a->comp_len == 3 && c <= 2) {
return 4 * c; /* AMD HW can't fetch these well, so pad it out (other vendors too?) */
}
@@ -185,7 +193,6 @@ uint GPU_vertformat_attr_add(GPUVertFormat *format,
attr->names[attr->name_len++] = copy_attr_name(format, name);
attr->comp_type = comp_type;
- attr->gl_comp_type = convert_comp_type_to_gl(comp_type);
attr->comp_len = (comp_type == GPU_COMP_I10) ?
4 :
comp_len; /* system needs 10_10_10_2 to be 4 or BGRA */
@@ -279,7 +286,7 @@ void GPU_vertformat_attr_rename(GPUVertFormat *format, int attr_id, const char *
/* Encode 8 original bytes into 11 safe bytes. */
static void safe_bytes(char out[11], const char data[8])
{
- char safe_chars[63] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
+ char safe_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
uint64_t in = *(uint64_t *)data;
for (int i = 0; i < 11; i++) {
@@ -368,14 +375,6 @@ static void show_pack(uint a_idx, uint sz, uint pad)
void VertexFormat_pack(GPUVertFormat *format)
{
- /* For now, attributes are packed in the order they were added,
- * making sure each attribute is naturally aligned (add padding where necessary)
- * Later we can implement more efficient packing w/ reordering
- * (keep attribute ID order, adjust their offsets to reorder in buffer). */
-
- /* TODO: realloc just enough to hold the final combo string. And just enough to
- * hold used attributes, not all 16. */
-
GPUVertAttr *a0 = &format->attrs[0];
a0->offset = 0;
uint offset = a0->sz;
@@ -512,7 +511,6 @@ void GPU_vertformat_from_shader(GPUVertFormat *format, const GPUShader *shader)
attr->sz = attr->comp_len * 4;
attr->fetch_mode = fetch_mode;
attr->comp_type = comp_type;
- attr->gl_comp_type = convert_comp_type_to_gl(comp_type);
attr += 1;
}
}
diff --git a/source/blender/gpu/intern/gpu_vertex_format_private.h b/source/blender/gpu/intern/gpu_vertex_format_private.h
index a850d17a1dd..45523c0e956 100644
--- a/source/blender/gpu/intern/gpu_vertex_format_private.h
+++ b/source/blender/gpu/intern/gpu_vertex_format_private.h
@@ -23,11 +23,17 @@
* GPU vertex format
*/
-#ifndef __GPU_VERTEX_FORMAT_PRIVATE_H__
-#define __GPU_VERTEX_FORMAT_PRIVATE_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
void VertexFormat_pack(GPUVertFormat *format);
uint padding(uint offset, uint alignment);
uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len);
+GLenum convert_comp_type_to_gl(GPUVertCompType type);
-#endif /* __GPU_VERTEX_FORMAT_PRIVATE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 753da8544ea..81315ec1f92 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -38,7 +38,6 @@
#include "DNA_vec_types.h"
#include "GPU_framebuffer.h"
-#include "GPU_glew.h"
#include "GPU_immediate.h"
#include "GPU_matrix.h"
#include "GPU_texture.h"
@@ -630,13 +629,13 @@ void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo
if (settings == S3D_DISPLAY_ANAGLYPH) {
switch (stereo_format->anaglyph_type) {
case S3D_ANAGLYPH_REDCYAN:
- glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
+ GPU_color_mask(false, true, true, true);
break;
case S3D_ANAGLYPH_GREENMAGENTA:
- glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
+ GPU_color_mask(true, false, true, true);
break;
case S3D_ANAGLYPH_YELLOWBLUE:
- glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
+ GPU_color_mask(false, false, true, true);
break;
}
}
@@ -666,7 +665,7 @@ void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo
GPU_matrix_pop();
if (settings == S3D_DISPLAY_ANAGLYPH) {
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ GPU_color_mask(true, true, true, true);
}
GPU_framebuffer_restore();
@@ -1036,3 +1035,15 @@ void GPU_viewport_free(GPUViewport *viewport)
MEM_freeN(viewport);
}
+
+GPUFrameBuffer *GPU_viewport_framebuffer_default_get(GPUViewport *viewport)
+{
+ DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
+ return fbl->default_fb;
+}
+
+GPUFrameBuffer *GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport)
+{
+ DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
+ return fbl->overlay_fb;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
index 2fd5effccce..d15f48c8f8a 100644
--- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
@@ -9,25 +9,33 @@ uniform vec4 parameters[MAX_PARAM * MAX_INSTANCE];
uniform vec4 parameters[MAX_PARAM];
#endif
-/* gl_InstanceID is 0 if not drawing instances. */
-#define recti parameters[gl_InstanceID * MAX_PARAM + 0]
-#define rect parameters[gl_InstanceID * MAX_PARAM + 1]
-#define radsi parameters[gl_InstanceID * MAX_PARAM + 2].x
-#define rads parameters[gl_InstanceID * MAX_PARAM + 2].y
-#define faci parameters[gl_InstanceID * MAX_PARAM + 2].zw
-#define roundCorners parameters[gl_InstanceID * MAX_PARAM + 3]
-#define colorInner1 parameters[gl_InstanceID * MAX_PARAM + 4]
-#define colorInner2 parameters[gl_InstanceID * MAX_PARAM + 5]
-#define colorEdge parameters[gl_InstanceID * MAX_PARAM + 6]
-#define colorEmboss parameters[gl_InstanceID * MAX_PARAM + 7]
-#define colorTria parameters[gl_InstanceID * MAX_PARAM + 8]
-#define tria1Center parameters[gl_InstanceID * MAX_PARAM + 9].xy
-#define tria2Center parameters[gl_InstanceID * MAX_PARAM + 9].zw
-#define tria1Size parameters[gl_InstanceID * MAX_PARAM + 10].x
-#define tria2Size parameters[gl_InstanceID * MAX_PARAM + 10].y
-#define shadeDir parameters[gl_InstanceID * MAX_PARAM + 10].z
-#define alphaDiscard parameters[gl_InstanceID * MAX_PARAM + 10].w
-#define triaType parameters[gl_InstanceID * MAX_PARAM + 11].x
+/* gl_InstanceID is supposed to be 0 if not drawing instances, but this seems
+ * to be violated in some drivers. For example, macOS 10.15.4 and Intel Iris
+ * causes T78307 when using gl_InstanceID outside of instance. */
+#ifdef USE_INSTANCE
+# define widgetID gl_InstanceID
+#else
+# define widgetID 0
+#endif
+
+#define recti parameters[widgetID * MAX_PARAM + 0]
+#define rect parameters[widgetID * MAX_PARAM + 1]
+#define radsi parameters[widgetID * MAX_PARAM + 2].x
+#define rads parameters[widgetID * MAX_PARAM + 2].y
+#define faci parameters[widgetID * MAX_PARAM + 2].zw
+#define roundCorners parameters[widgetID * MAX_PARAM + 3]
+#define colorInner1 parameters[widgetID * MAX_PARAM + 4]
+#define colorInner2 parameters[widgetID * MAX_PARAM + 5]
+#define colorEdge parameters[widgetID * MAX_PARAM + 6]
+#define colorEmboss parameters[widgetID * MAX_PARAM + 7]
+#define colorTria parameters[widgetID * MAX_PARAM + 8]
+#define tria1Center parameters[widgetID * MAX_PARAM + 9].xy
+#define tria2Center parameters[widgetID * MAX_PARAM + 9].zw
+#define tria1Size parameters[widgetID * MAX_PARAM + 10].x
+#define tria2Size parameters[widgetID * MAX_PARAM + 10].y
+#define shadeDir parameters[widgetID * MAX_PARAM + 10].z
+#define alphaDiscard parameters[widgetID * MAX_PARAM + 10].w
+#define triaType parameters[widgetID * MAX_PARAM + 11].x
/* We encode alpha check and discard factor together. */
#define doAlphaCheck (alphaDiscard < 0.0)
@@ -43,6 +51,10 @@ flat out float lineWidth;
noperspective out float butCo;
flat out float discardFac;
+#ifdef OS_MAC
+in float dummy;
+#endif
+
vec2 do_widget(void)
{
lineWidth = abs(rect.x - recti.x);
diff --git a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
new file mode 100644
index 00000000000..f7bf3d33361
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
@@ -0,0 +1,87 @@
+
+vec3 calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2)
+{
+ vec3 edge21 = pos2 - pos1;
+ vec3 edge10 = pos1 - pos0;
+ vec3 edge02 = pos0 - pos2;
+ vec3 d21 = normalize(edge21);
+ vec3 d10 = normalize(edge10);
+ vec3 d02 = normalize(edge02);
+
+ vec3 dists;
+ float d = dot(d21, edge02);
+ dists.x = sqrt(dot(edge02, edge02) - d * d);
+ d = dot(d02, edge10);
+ dists.y = sqrt(dot(edge10, edge10) - d * d);
+ d = dot(d10, edge21);
+ dists.z = sqrt(dot(edge21, edge21) - d * d);
+ return dists;
+}
+
+vec2 calc_barycentric_co(int vertid)
+{
+ vec2 bary;
+ bary.x = float((vertid % 3) == 0);
+ bary.y = float((vertid % 3) == 1);
+ return bary;
+}
+
+#ifdef HAIR_SHADER
+
+/* Hairs uv and col attributes are passed by bufferTextures. */
+# define DEFINE_ATTR(type, attr) uniform samplerBuffer attr
+# define GET_ATTR(type, attr) hair_get_customdata_##type(attr)
+
+# define barycentric_get() hair_get_barycentric()
+# define barycentric_resolve(bary) hair_resolve_barycentric(bary)
+
+vec3 orco_get(vec3 local_pos, mat4 modelmatinv, vec4 orco_madd[2], const samplerBuffer orco_samp)
+{
+ /* TODO: fix ORCO with modifiers. */
+ vec3 orco = (modelmatinv * vec4(local_pos, 1.0)).xyz;
+ return orco_madd[0].xyz + orco * orco_madd[1].xyz;
+}
+
+vec4 tangent_get(const samplerBuffer attr, mat3 normalmat)
+{
+ /* Unsupported */
+ return vec4(0.0);
+}
+
+#else /* MESH_SHADER */
+
+# define DEFINE_ATTR(type, attr) in type attr
+# define GET_ATTR(type, attr) attr
+
+/* Calculated in geom shader later with calc_barycentric_co. */
+# define barycentric_get() vec2(0)
+# define barycentric_resolve(bary) bary
+
+vec3 orco_get(vec3 local_pos, mat4 modelmatinv, vec4 orco_madd[2], vec4 orco)
+{
+ /* If the object does not have any deformation, the orco layer calculation is done on the fly
+ * using the orco_madd factors.
+ * We know when there is no orco layer when orco.w is 1.0 because it uses the generic vertex
+ * attrib (which is [0,0,0,1]). */
+ if (orco.w == 0.0) {
+ return orco.xyz * 0.5 + 0.5;
+ }
+ else {
+ return orco_madd[0].xyz + local_pos * orco_madd[1].xyz;
+ }
+}
+
+vec4 tangent_get(vec4 attr, mat3 normalmat)
+{
+ vec4 tangent;
+ tangent.xyz = normalmat * attr.xyz;
+ tangent.w = attr.w;
+ float len_sqr = dot(tangent.xyz, tangent.xyz);
+ /* Normalize only if vector is not null. */
+ if (len_sqr > 0.0) {
+ tangent.xyz *= inversesqrt(len_sqr);
+ }
+ return tangent;
+}
+
+#endif
diff --git a/source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl
deleted file mode 100644
index cf71d4ac0c5..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl
+++ /dev/null
@@ -1,14 +0,0 @@
-
-in vec2 texCoord_interp;
-out vec4 fragColor;
-
-uniform vec4 color;
-uniform sampler2D image;
-
-void main()
-{
- fragColor = texture(image, texCoord_interp).r * color.rgba;
- /* Premul by alpha (not texture alpha)
- * Use blending function GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); */
- fragColor.rgb *= color.a;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl
deleted file mode 100644
index e5078d722b4..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl
+++ /dev/null
@@ -1,12 +0,0 @@
-
-in vec2 texCoord_interp;
-out vec4 fragColor;
-
-uniform sampler2D image;
-uniform vec4 color;
-
-void main()
-{
- fragColor.a = texture(image, texCoord_interp).a * color.a;
- fragColor.rgb = color.rgb;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl
deleted file mode 100644
index 613352b4ac8..00000000000
--- a/source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl
+++ /dev/null
@@ -1,12 +0,0 @@
-
-in vec2 texCoord_interp;
-out vec4 fragColor;
-
-uniform float alpha;
-uniform sampler2D image;
-
-void main()
-{
- fragColor = texture(image, texCoord_interp);
- fragColor.a *= alpha;
-}
diff --git a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl
index cc12e3f78a5..d85884e0a25 100644
--- a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl
@@ -136,4 +136,5 @@ void main()
}
fragColor.a *= color_flat.a;
+ fragColor = blender_srgb_to_framebuffer_space(fragColor);
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
index d6d6fbab971..eea8d19efce 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
@@ -3,7 +3,7 @@ void node_ambient_occlusion(
vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao)
{
vec3 bent_normal;
- vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
+ vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal);
result_color = result_ao * color;
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl
index 3b23ac976ae..6330daa4391 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl
@@ -1,3 +1,15 @@
+
+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);
+}
+
void node_hair_info(out float is_strand,
out float intercept,
out float thickness,
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl
index b298fa4f8d1..27ca96501ae 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl
@@ -4,6 +4,7 @@ void node_output_world(Closure surface, Closure volume, out Closure result)
{
#ifndef VOLUMETRICS
float alpha = renderPassEnvironment ? 1.0 : backgroundAlpha;
+ result = CLOSURE_DEFAULT;
result.radiance = surface.radiance * alpha;
result.transmittance = vec3(1.0 - alpha);
#else
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl
index 981d17b4283..b6aad5904ff 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_sky.glsl
@@ -1,4 +1,150 @@
-void node_tex_sky(vec3 co, out vec4 color)
+float sky_angle_between(float thetav, float phiv, float theta, float phi)
+{
+ float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta);
+
+ if (cospsi > 1.0) {
+ return 0.0;
+ }
+ if (cospsi < -1.0) {
+ return M_PI;
+ }
+
+ return acos(cospsi);
+}
+
+vec3 sky_spherical_coordinates(vec3 dir)
+{
+ return vec3(M_PI_2 - atan(dir.z, length(dir.xy)), atan(dir.x, dir.y), 0);
+}
+
+/* Preetham */
+/* lam03+lam4: 5 floats passed as vec4+float */
+float sky_perez_function(vec4 lam03, float lam4, float theta, float gamma)
+{
+ float ctheta = cos(theta);
+ float cgamma = cos(gamma);
+
+ return (1.0 + lam03[0] * exp(lam03[1] / ctheta)) *
+ (1.0 + lam03[2] * exp(lam03[3] * gamma) + lam4 * cgamma * cgamma);
+}
+
+vec3 xyY_to_xyz(float x, float y, float Y)
+{
+ float X, Z;
+
+ if (y != 0.0) {
+ X = (x / y) * Y;
+ }
+ else {
+ X = 0.0;
+ }
+
+ if (y != 0.0 && Y != 0.0) {
+ Z = ((1.0 - x - y) / y) * Y;
+ }
+ else {
+ Z = 0.0;
+ }
+
+ return vec3(X, Y, Z);
+}
+
+void node_tex_sky_preetham(vec3 co,
+ vec4 config_Y03,
+ float config_Y4,
+ vec4 config_x03,
+ float config_x4,
+ vec4 config_y03,
+ float config_y4,
+ vec2 sun_angles,
+ vec3 radiance,
+ vec3 xyz_to_r,
+ vec3 xyz_to_g,
+ vec3 xyz_to_b,
+ out vec4 color)
+{
+ /* convert vector to spherical coordinates */
+ vec3 spherical = sky_spherical_coordinates(co);
+ float theta = spherical[0];
+ float phi = spherical[1];
+
+ float suntheta = sun_angles[0];
+ float sunphi = sun_angles[1];
+
+ /* angle between sun direction and dir */
+ float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
+
+ /* clamp theta to horizon */
+ theta = min(theta, M_PI_2 - 0.001);
+
+ /* compute xyY color space values */
+ float Y = radiance[0] * sky_perez_function(config_Y03, config_Y4, theta, gamma);
+ float x = radiance[1] * sky_perez_function(config_x03, config_x4, theta, gamma);
+ float y = radiance[2] * sky_perez_function(config_y03, config_y4, theta, gamma);
+
+ /* convert to RGB */
+ vec3 xyz = xyY_to_xyz(x, y, Y);
+ color = vec4(dot(xyz_to_r, xyz), dot(xyz_to_g, xyz), dot(xyz_to_b, xyz), 1);
+}
+
+/* Hosek / Wilkie */
+float sky_radiance_hosekwilkie(
+ vec4 config03, vec4 config47, float config8, float theta, float gamma)
+{
+ float ctheta = cos(theta);
+ float cgamma = cos(gamma);
+
+ float expM = exp(config47[0] * gamma);
+ float rayM = cgamma * cgamma;
+ float mieM = (1.0 + rayM) / pow((1.0 + config8 * config8 - 2.0 * config8 * cgamma), 1.5);
+ float zenith = sqrt(ctheta);
+
+ return (1.0 + config03[0] * exp(config03[1] / (ctheta + 0.01))) *
+ (config03[2] + config03[3] * expM + config47[1] * rayM + config47[2] * mieM +
+ config47[3] * zenith);
+}
+
+void node_tex_sky_hosekwilkie(vec3 co,
+ vec4 config_x03,
+ vec4 config_x47,
+ vec4 config_y03,
+ vec4 config_y47,
+ vec4 config_z03,
+ vec4 config_z47,
+ vec3 config_xyz8,
+ vec2 sun_angles,
+ vec3 radiance,
+ vec3 xyz_to_r,
+ vec3 xyz_to_g,
+ vec3 xyz_to_b,
+ out vec4 color)
+{
+ /* convert vector to spherical coordinates */
+ vec3 spherical = sky_spherical_coordinates(co);
+ float theta = spherical[0];
+ float phi = spherical[1];
+
+ float suntheta = sun_angles[0];
+ float sunphi = sun_angles[1];
+
+ /* angle between sun direction and dir */
+ float gamma = sky_angle_between(theta, phi, suntheta, sunphi);
+
+ /* clamp theta to horizon */
+ theta = min(theta, M_PI_2 - 0.001);
+
+ vec3 xyz;
+ xyz.x = sky_radiance_hosekwilkie(config_x03, config_x47, config_xyz8[0], theta, gamma) *
+ radiance.x;
+ xyz.y = sky_radiance_hosekwilkie(config_y03, config_y47, config_xyz8[1], theta, gamma) *
+ radiance.y;
+ xyz.z = sky_radiance_hosekwilkie(config_z03, config_z47, config_xyz8[2], theta, gamma) *
+ radiance.z;
+
+ color = vec4(dot(xyz_to_r, xyz), dot(xyz_to_g, xyz), dot(xyz_to_b, xyz), 1);
+}
+
+void node_tex_sky_nishita(vec3 co, out vec4 color)
{
color = vec4(1.0);
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl
index f9691beee6f..d33465fa846 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl
@@ -6,7 +6,7 @@ void world_normals_get(out vec3 N)
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);
+ vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
/* Random cosine normal distribution on the hair surface. */
cos_theta = rand.x * 2.0 - 1.0;
}
diff --git a/source/blender/ikplugin/BIK_api.h b/source/blender/ikplugin/BIK_api.h
index 2c2053b47a6..674b384adf2 100644
--- a/source/blender/ikplugin/BIK_api.h
+++ b/source/blender/ikplugin/BIK_api.h
@@ -22,8 +22,7 @@
* \ingroup ikplugin
*/
-#ifndef __BIK_API_H__
-#define __BIK_API_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -36,10 +35,10 @@ struct bConstraint;
struct bPose;
struct bPoseChannel;
-void BIK_initialize_tree(struct Depsgraph *depsgraph,
- struct Scene *scene,
- struct Object *ob,
- float ctime);
+void BIK_init_tree(struct Depsgraph *depsgraph,
+ struct Scene *scene,
+ struct Object *ob,
+ float ctime);
void BIK_execute_tree(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
@@ -54,5 +53,3 @@ void BIK_test_constraint(struct Object *ob, struct bConstraint *cons);
#ifdef __cplusplus
}
#endif
-
-#endif /* __BIK_API_H__ */
diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c
index 5e683d36408..233150a77aa 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.c
+++ b/source/blender/ikplugin/intern/ikplugin_api.c
@@ -80,7 +80,7 @@ static IKPlugin *get_plugin(bPose *pose)
/*----------------------------------------*/
/* Plugin API */
-void BIK_initialize_tree(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
+void BIK_init_tree(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
{
IKPlugin *plugin = get_plugin(ob->pose);
diff --git a/source/blender/ikplugin/intern/ikplugin_api.h b/source/blender/ikplugin/intern/ikplugin_api.h
index faf21cecacd..f61ba7e3a63 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.h
+++ b/source/blender/ikplugin/intern/ikplugin_api.h
@@ -22,8 +22,7 @@
* \ingroup ikplugin
*/
-#ifndef __IKPLUGIN_API_H__
-#define __IKPLUGIN_API_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -56,5 +55,3 @@ typedef struct IKPlugin IKPlugin;
#ifdef __cplusplus
}
#endif
-
-#endif /* __IKPLUGIN_API_H__ */
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.h b/source/blender/ikplugin/intern/iksolver_plugin.h
index 20a9e78cc47..28356b4fc9c 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.h
+++ b/source/blender/ikplugin/intern/iksolver_plugin.h
@@ -22,8 +22,7 @@
* \ingroup ikplugin
*/
-#ifndef __IKSOLVER_PLUGIN_H__
-#define __IKSOLVER_PLUGIN_H__
+#pragma once
#include "ikplugin_api.h"
@@ -46,5 +45,3 @@ void iksolver_clear_data(struct bPose *pose);
#ifdef __cplusplus
}
#endif
-
-#endif /* __IKSOLVER_PLUGIN_H__ */
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index 66ed0dd0fa5..8f84d04f602 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -117,12 +117,8 @@ struct IK_Target {
}
~IK_Target()
{
- if (constraint) {
- delete constraint;
- }
- if (target) {
- delete target;
- }
+ delete constraint;
+ delete target;
}
};
@@ -196,29 +192,17 @@ struct IK_Scene {
~IK_Scene()
{
// delete scene first
- if (scene) {
- delete scene;
- }
+ delete scene;
for (std::vector<IK_Target *>::iterator it = targets.begin(); it != targets.end(); ++it) {
delete (*it);
}
targets.clear();
- if (channels) {
- delete[] channels;
- }
- if (solver) {
- delete solver;
- }
- if (armature) {
- delete armature;
- }
- if (base) {
- delete base;
- }
+ delete[] channels;
+ delete solver;
+ delete armature;
+ delete base;
// delete cache last
- if (cache) {
- delete cache;
- }
+ delete cache;
}
};
diff --git a/source/blender/ikplugin/intern/itasc_plugin.h b/source/blender/ikplugin/intern/itasc_plugin.h
index e7a319809b7..89342295b35 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.h
+++ b/source/blender/ikplugin/intern/itasc_plugin.h
@@ -22,8 +22,7 @@
* \ingroup ikplugin
*/
-#ifndef __ITASC_PLUGIN_H__
-#define __ITASC_PLUGIN_H__
+#pragma once
#include "ikplugin_api.h"
@@ -49,5 +48,3 @@ void itasc_test_constraint(struct Object *ob, struct bConstraint *cons);
#ifdef __cplusplus
}
#endif
-
-#endif /* __ITASC_PLUGIN_H__ */
diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt
index cad0be659ec..cf637a06405 100644
--- a/source/blender/imbuf/CMakeLists.txt
+++ b/source/blender/imbuf/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../blenkernel
../blenlib
../blenloader
+ ../gpu
../makesdna
../makesrna
../../../intern/guardedalloc
@@ -63,6 +64,7 @@ set(SRC
intern/thumbs_blend.c
intern/thumbs_font.c
intern/util.c
+ intern/util_gpu.c
intern/writeimage.c
IMB_colormanagement.h
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 3158e3419b0..54f126684ae 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __IMB_COLORMANAGEMENT_H__
-#define __IMB_COLORMANAGEMENT_H__
+#pragma once
/** \file
* \ingroup imbuf
@@ -72,6 +71,7 @@ BLI_INLINE float IMB_colormanagement_get_luminance(const float rgb[3]);
BLI_INLINE unsigned char IMB_colormanagement_get_luminance_byte(const unsigned char[3]);
BLI_INLINE void IMB_colormangement_xyz_to_rgb(float rgb[3], const float xyz[3]);
BLI_INLINE void IMB_colormangement_rgb_to_xyz(float xyz[3], const float rgb[3]);
+const float *IMB_colormangement_get_xyz_to_rgb(void);
/* ** Color space transformation functions ** */
void IMB_colormanagement_transform(float *buffer,
@@ -373,5 +373,3 @@ enum {
#endif
#include "intern/colormanagement_inline.c"
-
-#endif /* __IMB_COLORMANAGEMENT_H__ */
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 83ef910d0bb..37046521dd8 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -53,8 +53,7 @@
* posix-compliant.
*/
-#ifndef __IMB_IMBUF_H__
-#define __IMB_IMBUF_H__
+#pragma once
/* for bool */
#include "../blenlib/BLI_sys_types.h"
@@ -90,6 +89,12 @@ struct Stereo3dFormat;
/**
*
+ * \attention defined in GPU_texture.h
+ */
+struct GPUTexture;
+
+/**
+ *
* \attention Defined in allocimbuf.c
*/
void IMB_init(void);
@@ -291,7 +296,7 @@ void IMB_rectblend_threaded(struct ImBuf *dbuf,
*/
typedef enum IMB_Timecode_Type {
- /** Don't use timecode files at all. */
+ /** Don't use time-code files at all. */
IMB_TC_NONE = 0,
/** use images in the order as they are recorded
* (currently, this is the only one implemented
@@ -318,7 +323,7 @@ typedef enum IMB_Proxy_Size {
IMB_PROXY_MAX_SLOT = 4,
} IMB_Proxy_Size;
-/* defaults to BL_proxy within the directory of the animation */
+/* Defaults to BL_proxy within the directory of the animation. */
void IMB_anim_set_index_dir(struct anim *anim, const char *dir);
void IMB_anim_get_fname(struct anim *anim, char *file, int size);
@@ -328,7 +333,7 @@ IMB_Proxy_Size IMB_anim_proxy_get_existing(struct anim *anim);
struct IndexBuildContext;
-/* prepare context for proxies/imecodes builder */
+/* Prepare context for proxies/time-codes builder. */
struct IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim,
IMB_Timecode_Type tcs_in_use,
IMB_Proxy_Size proxy_sizes_in_use,
@@ -336,13 +341,13 @@ struct IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim,
const bool overwrite,
struct GSet *file_list);
-/* will rebuild all used indices and proxies at once */
+/* Will rebuild all used indices and proxies at once. */
void IMB_anim_index_rebuild(struct IndexBuildContext *context,
short *stop,
short *do_update,
float *progress);
-/* finish rebuilding proxises/timecodes and free temporary contexts used */
+/* Finish rebuilding proxies/time-codes and free temporary contexts used. */
void IMB_anim_index_rebuild_finish(struct IndexBuildContext *context, short stop);
/**
@@ -367,6 +372,7 @@ struct anim *IMB_open_anim(const char *name,
void IMB_suffix_anim(struct anim *anim, const char *suffix);
void IMB_close_anim(struct anim *anim);
void IMB_close_anim_proxies(struct anim *anim);
+bool IMB_anim_can_produce_frames(const struct anim *anim);
/**
*
@@ -390,7 +396,7 @@ struct ImBuf *IMB_anim_absolute(struct anim *anim,
/**
*
* \attention Defined in anim_movie.c
- * fetches a define previewframe, usually half way into the movie
+ * fetches a define preview-frame, usually half way into the movie.
*/
struct ImBuf *IMB_anim_previewframe(struct anim *anim);
@@ -411,7 +417,7 @@ void IMB_free_anim(struct anim *anim);
void IMB_filter(struct ImBuf *ibuf);
void IMB_mask_filter_extend(char *mask, int width, int height);
-void IMB_mask_clear(struct ImBuf *ibuf, char *mask, int val);
+void IMB_mask_clear(struct ImBuf *ibuf, const char *mask, int val);
void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter);
void IMB_makemipmap(struct ImBuf *ibuf, int use_filter);
void IMB_remakemipmap(struct ImBuf *ibuf, int use_filter);
@@ -599,7 +605,7 @@ void bilinear_interpolation_color_wrap(
struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v);
void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]);
-void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]);
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, const float backcol[3]);
void IMB_sampleImageAtLocation(
struct ImBuf *ibuf, float x, float y, bool make_linear_rgb, float color[4]);
@@ -728,6 +734,25 @@ const char *IMB_ffmpeg_last_error(void);
/**
*
+ * \attention defined in util_gpu.c
+ */
+struct GPUTexture *IMB_create_gpu_texture(struct ImBuf *ibuf,
+ bool use_high_bitdepth,
+ bool use_premult);
+struct GPUTexture *IMB_touch_gpu_texture(
+ struct ImBuf *ibuf, int w, int h, int layers, bool use_high_bitdepth);
+void IMB_update_gpu_texture_sub(struct GPUTexture *tex,
+ struct ImBuf *ibuf,
+ int x,
+ int y,
+ int z,
+ int w,
+ int h,
+ bool use_high_bitdepth,
+ bool use_premult);
+
+/**
+ *
* \attention defined in stereoimbuf.c
*/
void IMB_stereo3d_write_dimensions(const char mode,
@@ -765,5 +790,3 @@ void IMB_ImBufFromStereo3d(struct Stereo3dFormat *s3d,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index ddc8394264a..98e9c34a4ff 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __IMB_IMBUF_TYPES_H__
-#define __IMB_IMBUF_TYPES_H__
+#pragma once
#include "DNA_vec_types.h" /* for rcti */
@@ -353,5 +352,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __IMB_IMBUF_TYPES_H__ */
diff --git a/source/blender/imbuf/IMB_metadata.h b/source/blender/imbuf/IMB_metadata.h
index edbdd7be482..501bf9dfba1 100644
--- a/source/blender/imbuf/IMB_metadata.h
+++ b/source/blender/imbuf/IMB_metadata.h
@@ -21,8 +21,7 @@
* \ingroup imbuf
*/
-#ifndef __IMB_METADATA_H__
-#define __IMB_METADATA_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -84,5 +83,3 @@ void IMB_metadata_foreach(struct ImBuf *ibuf, IMBMetadataForeachCb callback, voi
#ifdef __cplusplus
}
#endif
-
-#endif /* __IMB_METADATA_H__ */
diff --git a/source/blender/imbuf/IMB_moviecache.h b/source/blender/imbuf/IMB_moviecache.h
index 5fb158f0d8b..8e5f15a64a0 100644
--- a/source/blender/imbuf/IMB_moviecache.h
+++ b/source/blender/imbuf/IMB_moviecache.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __IMB_MOVIECACHE_H__
-#define __IMB_MOVIECACHE_H__
+#pragma once
/** \file
* \ingroup imbuf
@@ -85,5 +84,3 @@ void *IMB_moviecacheIter_getUserKey(struct MovieCacheIter *iter);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index 00e9a810ef3..e8c244aaba7 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -21,8 +21,7 @@
* \ingroup imbuf
*/
-#ifndef __IMB_THUMBS_H__
-#define __IMB_THUMBS_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -98,5 +97,3 @@ void IMB_thumb_path_unlock(const char *path);
#ifdef __cplusplus
}
#endif /* __cplusplus */
-
-#endif /* __IMB_THUMBS_H__ */
diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h
index 9f89969cf1c..08aa1936a6f 100644
--- a/source/blender/imbuf/intern/IMB_allocimbuf.h
+++ b/source/blender/imbuf/intern/IMB_allocimbuf.h
@@ -21,8 +21,7 @@
* \ingroup imbuf
* \brief Header file for allocimbuf.c
*/
-#ifndef __IMB_ALLOCIMBUF_H__
-#define __IMB_ALLOCIMBUF_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -51,5 +50,3 @@ bool imb_enlargeencodedbufferImBuf(struct ImBuf *ibuf);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index 3d1d99963c7..babff5c34cd 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -21,8 +21,7 @@
* \ingroup imbuf
*/
-#ifndef __IMB_ANIM_H__
-#define __IMB_ANIM_H__
+#pragma once
#ifdef _WIN32
# define INC_OLE2
@@ -152,5 +151,3 @@ struct anim {
struct IDProperty *metadata;
};
-
-#endif
diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
index 79abe8472b9..6b505a7171a 100644
--- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h
+++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __IMB_COLORMANAGEMENT_INTERN_H__
-#define __IMB_COLORMANAGEMENT_INTERN_H__
+#pragma once
/** \file
* \ingroup imbuf
@@ -130,5 +129,3 @@ void colormanage_imbuf_make_linear(struct ImBuf *ibuf, const char *from_colorspa
#ifdef __cplusplus
}
#endif
-
-#endif /* __IMB_COLORMANAGEMENT_INTERN_H__ */
diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h
index ce731a3a86d..2b00b87d3d2 100644
--- a/source/blender/imbuf/intern/IMB_filetype.h
+++ b/source/blender/imbuf/intern/IMB_filetype.h
@@ -18,8 +18,7 @@
* \ingroup imbuf
*/
-#ifndef __IMB_FILETYPE_H__
-#define __IMB_FILETYPE_H__
+#pragma once
#include "IMB_imbuf.h"
@@ -151,5 +150,3 @@ struct ImBuf *imb_loadtiff(const unsigned char *mem,
void imb_loadtiletiff(
struct ImBuf *ibuf, const unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect);
int imb_savetiff(struct ImBuf *ibuf, const char *name, int flags);
-
-#endif /* __IMB_FILETYPE_H__ */
diff --git a/source/blender/imbuf/intern/IMB_filter.h b/source/blender/imbuf/intern/IMB_filter.h
index 2cd785e6889..556362d78c1 100644
--- a/source/blender/imbuf/intern/IMB_filter.h
+++ b/source/blender/imbuf/intern/IMB_filter.h
@@ -22,8 +22,7 @@
* \brief Function declarations for filter.c
*/
-#ifndef __IMB_FILTER_H__
-#define __IMB_FILTER_H__
+#pragma once
struct ImBuf;
@@ -36,5 +35,3 @@ void IMB_unpremultiply_rect(unsigned int *rect, char planes, int w, int h);
void IMB_unpremultiply_rect_float(float *rect_float, int channels, int w, int h);
void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1);
-
-#endif
diff --git a/source/blender/imbuf/intern/IMB_indexer.h b/source/blender/imbuf/intern/IMB_indexer.h
index 61bb50aff38..7cd11e137c2 100644
--- a/source/blender/imbuf/intern/IMB_indexer.h
+++ b/source/blender/imbuf/intern/IMB_indexer.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __IMB_INDEXER_H__
-#define __IMB_INDEXER_H__
+#pragma once
/** \file
* \ingroup imbuf
@@ -31,9 +30,9 @@
/*
* separate animation index files to solve the following problems:
*
- * a) different timecodes within one file (like DTS/PTS, Timecode-Track,
- * "implicit" timecodes within DV-files and HDV-files etc.)
- * b) seeking difficulties within ffmpeg for files with timestamp holes
+ * a) different time-codes within one file (like DTS/PTS, Time-code-Track,
+ * "implicit" time-codes within DV-files and HDV-files etc.)
+ * b) seeking difficulties within FFMPEG for files with timestamp holes
* c) broken files that miss several frames / have varying framerates
* d) use proxies accordingly
*
@@ -113,5 +112,3 @@ struct anim_index *IMB_anim_open_index(struct anim *anim, IMB_Timecode_Type tc);
int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size);
int IMB_timecode_to_array_index(IMB_Timecode_Type tc);
-
-#endif
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 11b30a24cde..9fab450cc76 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -304,6 +304,25 @@ struct anim *IMB_open_anim(const char *name,
return (anim);
}
+bool IMB_anim_can_produce_frames(const struct anim *anim)
+{
+#if !(defined(WITH_AVI) || defined(WITH_FFMPEG))
+ UNUSED_VARS(anim);
+#endif
+
+#ifdef WITH_AVI
+ if (anim->avi != NULL) {
+ return true;
+ }
+#endif
+#ifdef WITH_FFMPEG
+ if (anim->pCodecCtx != NULL) {
+ return true;
+ }
+#endif
+ return false;
+}
+
void IMB_suffix_anim(struct anim *anim, const char *suffix)
{
BLI_strncpy(anim->suffix, suffix, sizeof(anim->suffix));
@@ -1186,7 +1205,29 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Typ
}
IMB_freeImBuf(anim->last_frame);
- anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
+
+ /* Certain versions of FFmpeg have a bug in libswscale which ends up in crash
+ * when destination buffer is not properly aligned. For example, this happens
+ * in FFmpeg 4.3.1. It got fixed later on, but for compatibility reasons is
+ * still best to avoid crash.
+ *
+ * This is achieved by using own allocation call rather than relying on
+ * IMB_allocImBuf() to do so since the IMB_allocImBuf() is not guaranteed
+ * to perform aligned allocation.
+ *
+ * In theory this could give better performance, since SIMD operations on
+ * aligned data are usually faster.
+ *
+ * Note that even though sometimes vertical flip is required it does not
+ * affect on alignment of data passed to sws_scale because if the X dimension
+ * is not 32 byte aligned special intermediate buffer is allocated.
+ *
+ * The issue was reported to FFmpeg under ticket #8747 in the FFmpeg tracker
+ * and is fixed in the newer versions than 4.3.1. */
+ anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, 0);
+ anim->last_frame->rect = MEM_mallocN_aligned((size_t)4 * anim->x * anim->y, 32, "ffmpeg ibuf");
+ anim->last_frame->mall |= IB_rect;
+
anim->last_frame->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace);
ffmpeg_postprocess(anim);
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.h b/source/blender/imbuf/intern/cineon/cineonlib.h
index 040435e44ee..d1225027b4c 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.h
+++ b/source/blender/imbuf/intern/cineon/cineonlib.h
@@ -23,8 +23,7 @@
* Also handles DPX files (almost)
*/
-#ifndef __CINEONLIB_H__
-#define __CINEONLIB_H__
+#pragma once
#include "logImageCore.h"
@@ -135,5 +134,3 @@ LogImageFile *cineonCreate(
#ifdef __cplusplus
}
#endif
-
-#endif /* __CINEONLIB_H__ */
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.h b/source/blender/imbuf/intern/cineon/dpxlib.h
index 3a7ebe9dddf..6b729dba59a 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.h
+++ b/source/blender/imbuf/intern/cineon/dpxlib.h
@@ -22,8 +22,7 @@
* DPX image file format library definitions.
*/
-#ifndef __DPXLIB_H__
-#define __DPXLIB_H__
+#pragma once
#include "logImageCore.h"
@@ -160,5 +159,3 @@ LogImageFile *dpxCreate(const char *filename,
#ifdef __cplusplus
}
#endif
-
-#endif /* __DPXLIB_H__ */
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.h b/source/blender/imbuf/intern/cineon/logImageCore.h
index 3d49da7eb42..a2d50f21a98 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.h
+++ b/source/blender/imbuf/intern/cineon/logImageCore.h
@@ -27,8 +27,7 @@
* Hmm. I thought the two formats would have more in common!
*/
-#ifndef __LOGIMAGECORE_H__
-#define __LOGIMAGECORE_H__
+#pragma once
#include <stdio.h>
@@ -295,5 +294,3 @@ BLI_INLINE unsigned int float_uint(float value, unsigned int max)
#ifdef __cplusplus
}
#endif
-
-#endif /* __LOGIMAGECORE_H__ */
diff --git a/source/blender/imbuf/intern/cineon/logmemfile.h b/source/blender/imbuf/intern/cineon/logmemfile.h
index d0ca03193e5..fd67011ef30 100644
--- a/source/blender/imbuf/intern/cineon/logmemfile.h
+++ b/source/blender/imbuf/intern/cineon/logmemfile.h
@@ -22,8 +22,7 @@
* Cineon image file format library routines.
*/
-#ifndef __LOGMEMFILE_H__
-#define __LOGMEMFILE_H__
+#pragma once
#include "logImageCore.h"
@@ -35,5 +34,3 @@ int logimage_fread(void *buffer, size_t size, unsigned int count, LogImageFile *
int logimage_read_uchar(unsigned char *x, LogImageFile *logFile);
int logimage_read_ushort(unsigned short *x, LogImageFile *logFile);
int logimage_read_uint(unsigned int *x, LogImageFile *logFile);
-
-#endif /* __LOGMEMFILE_H__ */
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 3f5a0f25cc5..136d191c6a0 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -698,7 +698,7 @@ void colormanagement_init(void)
OCIO_configRelease(config);
}
- /* If there're no valid display/views, use fallback mode. */
+ /* If there are no valid display/views, use fallback mode. */
if (global_tot_display == 0 || global_tot_view == 0) {
printf("Color management: no displays/views in the config, using fallback mode instead\n");
@@ -1456,6 +1456,11 @@ bool IMB_colormanagement_space_name_is_data(const char *name)
return (colorspace && colorspace->is_data);
}
+const float *IMB_colormangement_get_xyz_to_rgb()
+{
+ return &imbuf_xyz_to_rgb[0][0];
+}
+
/*********************** Threaded display buffer transform routines *************************/
typedef struct DisplayBufferThread {
@@ -1718,7 +1723,7 @@ static void *do_display_buffer_apply_thread(void *handle_v)
}
static void display_buffer_apply_threaded(ImBuf *ibuf,
- float *buffer,
+ const float *buffer,
unsigned char *byte_buffer,
float *display_buffer,
unsigned char *display_buffer_byte,
@@ -3953,7 +3958,7 @@ static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping,
{
int i;
- BKE_curvemapping_initialize(curve_mapping);
+ BKE_curvemapping_init(curve_mapping);
BKE_curvemapping_premultiply(curve_mapping, false);
BKE_curvemapping_table_RGBA(
curve_mapping, &curve_mapping_settings->lut, &curve_mapping_settings->lut_size);
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
index 4397c1febab..9fd6d71e091 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.cpp
+++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp
@@ -241,7 +241,7 @@ void BlockDXT1::decodeBlockNV5x(ColorBlock *block) const
}
}
-void BlockDXT1::setIndices(int *idx)
+void BlockDXT1::setIndices(const int *idx)
{
indices = 0;
for (uint i = 0; i < 16; i++) {
@@ -580,7 +580,7 @@ void BlockCTX1::decodeBlock(ColorBlock *block) const
}
}
-void BlockCTX1::setIndices(int *idx)
+void BlockCTX1::setIndices(const int *idx)
{
indices = 0;
for (uint i = 0; i < 16; i++) {
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h
index 16937bce042..70ec8808c61 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.h
+++ b/source/blender/imbuf/intern/dds/BlockDXT.h
@@ -48,8 +48,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
-#ifndef __BLOCKDXT_H__
-#define __BLOCKDXT_H__
+#pragma once
#include <Color.h>
#include <ColorBlock.h>
@@ -76,7 +75,7 @@ struct BlockDXT1 {
void decodeBlock(ColorBlock *block) const;
void decodeBlockNV5x(ColorBlock *block) const;
- void setIndices(int *idx);
+ void setIndices(const int *idx);
void flip4();
void flip2();
@@ -289,7 +288,7 @@ struct BlockCTX1 {
};
void evaluatePalette(Color32 color_array[4]) const;
- void setIndices(int *idx);
+ void setIndices(const int *idx);
void decodeBlock(ColorBlock *block) const;
@@ -305,5 +304,3 @@ void mem_read(Stream &mem, BlockDXT5 &block);
void mem_read(Stream &mem, BlockATI1 &block);
void mem_read(Stream &mem, BlockATI2 &block);
void mem_read(Stream &mem, BlockCTX1 &block);
-
-#endif /* __BLOCKDXT_H__ */
diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h
index 36e2615759b..d0b67d4638c 100644
--- a/source/blender/imbuf/intern/dds/Color.h
+++ b/source/blender/imbuf/intern/dds/Color.h
@@ -27,8 +27,7 @@
// This code is in the public domain -- castanyo@yahoo.es
-#ifndef __COLOR_H__
-#define __COLOR_H__
+#pragma once
/// 32 bit color stored as BGRA.
class Color32 {
@@ -116,5 +115,3 @@ class Color16 {
unsigned short u;
};
};
-
-#endif /* __COLOR_H__ */
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
index 2e8a6bbda7f..dd63286e230 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.h
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -27,8 +27,7 @@
// This code is in the public domain -- castanyo@yahoo.es
-#ifndef __COLORBLOCK_H__
-#define __COLORBLOCK_H__
+#pragma once
#include <Color.h>
#include <Image.h>
@@ -91,5 +90,3 @@ inline Color32 &ColorBlock::color(uint x, uint y)
{
return m_color[y * 4 + x];
}
-
-#endif /* __COLORBLOCK_H__ */
diff --git a/source/blender/imbuf/intern/dds/Common.h b/source/blender/imbuf/intern/dds/Common.h
index 56f5d54cf42..90ec347a9ad 100644
--- a/source/blender/imbuf/intern/dds/Common.h
+++ b/source/blender/imbuf/intern/dds/Common.h
@@ -18,8 +18,7 @@
* \ingroup imbdds
*/
-#ifndef __COMMON_H__
-#define __COMMON_H__
+#pragma once
#ifndef MIN
# define MIN(a, b) ((a) <= (b) ? (a) : (b))
@@ -49,5 +48,3 @@ inline uint computePitch(uint w, uint bitsize, uint alignment)
{
return ((w * bitsize + 8 * alignment - 1) / (8 * alignment)) * alignment;
}
-
-#endif
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
index f12c45d11df..ac7f893fddd 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
@@ -48,8 +48,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
-#ifndef __DIRECTDRAWSURFACE_H__
-#define __DIRECTDRAWSURFACE_H__
+#pragma once
#include <ColorBlock.h>
#include <Common.h>
@@ -184,5 +183,3 @@ void mem_read(Stream &mem, DDSPixelFormat &pf);
void mem_read(Stream &mem, DDSCaps &caps);
void mem_read(Stream &mem, DDSHeader &header);
void mem_read(Stream &mem, DDSHeader10 &header);
-
-#endif /* __DIRECTDRAWSURFACE_H__ */
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.h b/source/blender/imbuf/intern/dds/FlipDXT.h
index b7056742430..d35157251bd 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.h
+++ b/source/blender/imbuf/intern/dds/FlipDXT.h
@@ -14,13 +14,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __FLIPDXT_H__
-#define __FLIPDXT_H__
+#pragma once
#include "BLI_sys_types.h"
/* flip compressed DXT image vertically to fit OpenGL convention */
int FlipDXTCImage(
unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data);
-
-#endif
diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp
index d08a61a5a60..31a9927557b 100644
--- a/source/blender/imbuf/intern/dds/Image.cpp
+++ b/source/blender/imbuf/intern/dds/Image.cpp
@@ -51,9 +51,7 @@ void Image::allocate(uint w, uint h)
void Image::free()
{
- if (m_data) {
- delete[] m_data;
- }
+ delete[] m_data;
m_data = NULL;
}
diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h
index 2922d5cfda3..4ccfec99445 100644
--- a/source/blender/imbuf/intern/dds/Image.h
+++ b/source/blender/imbuf/intern/dds/Image.h
@@ -27,8 +27,7 @@
// This code is in the public domain -- castanyo@yahoo.es
-#ifndef __IMAGE_H__
-#define __IMAGE_H__
+#pragma once
#include "Color.h"
#include "Common.h"
@@ -89,5 +88,3 @@ inline Color32 &Image::pixel(uint x, uint y)
{
return pixel(y * width() + x);
}
-
-#endif /* __IMAGE_H__ */
diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h
index 47585147dfb..a9125c64121 100644
--- a/source/blender/imbuf/intern/dds/PixelFormat.h
+++ b/source/blender/imbuf/intern/dds/PixelFormat.h
@@ -48,8 +48,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
-#ifndef __PIXELFORMAT_H__
-#define __PIXELFORMAT_H__
+#pragma once
#include "Common.h"
@@ -126,5 +125,3 @@ inline float quantizeFloor(float f, int bits)
#endif
} // namespace PixelFormat
-
-#endif /* __PIXELFORMAT_H__ */
diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h
index 43cd6b56fb9..ad6b9165801 100644
--- a/source/blender/imbuf/intern/dds/Stream.h
+++ b/source/blender/imbuf/intern/dds/Stream.h
@@ -20,8 +20,7 @@
/* simple memory stream functions with buffer overflow check */
-#ifndef __STREAM_H__
-#define __STREAM_H__
+#pragma once
struct Stream {
unsigned char *mem; // location in memory
@@ -40,5 +39,3 @@ unsigned int mem_read(Stream &mem, unsigned int &i);
unsigned int mem_read(Stream &mem, unsigned short &i);
unsigned int mem_read(Stream &mem, unsigned char &i);
unsigned int mem_read(Stream &mem, unsigned char *i, unsigned int cnt);
-
-#endif /* __STREAM_H__ */
diff --git a/source/blender/imbuf/intern/dds/dds_api.h b/source/blender/imbuf/intern/dds/dds_api.h
index e6782e217fc..930205c9efb 100644
--- a/source/blender/imbuf/intern/dds/dds_api.h
+++ b/source/blender/imbuf/intern/dds/dds_api.h
@@ -18,8 +18,7 @@
* \ingroup imbdds
*/
-#ifndef __DDS_API_H__
-#define __DDS_API_H__
+#pragma once
#include "../../IMB_imbuf.h"
@@ -37,5 +36,3 @@ struct ImBuf *imb_load_dds(const unsigned char *mem,
#ifdef __cplusplus
}
#endif
-
-#endif /* __DDS_API_H */
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index e36088f8eac..d8a5096af71 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -363,7 +363,7 @@ void IMB_mask_filter_extend(char *mask, int width, int height)
MEM_freeN(temprect);
}
-void IMB_mask_clear(ImBuf *ibuf, char *mask, int val)
+void IMB_mask_clear(ImBuf *ibuf, const char *mask, int val)
{
int x, y;
if (ibuf->rect_float) {
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 7ebbd1a7409..bf58f047773 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -456,7 +456,7 @@ void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[
}
}
-void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3])
+void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, const float backcol[3])
{
size_t a = ((size_t)x) * y;
unsigned char *cp = rect;
diff --git a/source/blender/imbuf/intern/imbuf.h b/source/blender/imbuf/intern/imbuf.h
index 912c25f2616..309a911e9ca 100644
--- a/source/blender/imbuf/intern/imbuf.h
+++ b/source/blender/imbuf/intern/imbuf.h
@@ -21,8 +21,7 @@
* \ingroup imbuf
*/
-#ifndef __IMBUF_H__
-#define __IMBUF_H__
+#pragma once
#include <stdio.h>
#include <stdlib.h>
@@ -61,5 +60,3 @@
#endif
#define IMB_DPI_DEFAULT 72.0f
-
-#endif /* __IMBUF_H__ */
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 985a8e977ca..7cc31b99077 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -894,7 +894,7 @@ static void index_rebuild_ffmpeg_proc_decoded_frame(FFmpegIndexBuilderContext *c
}
static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context,
- short *stop,
+ const short *stop,
short *do_update,
float *progress)
{
@@ -1090,7 +1090,7 @@ static void index_rebuild_fallback_finish(FallbackIndexBuilderContext *context,
}
static void index_rebuild_fallback(FallbackIndexBuilderContext *context,
- short *stop,
+ const short *stop,
short *do_update,
float *progress)
{
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index bfcd1ec2cee..2516df22151 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -122,7 +122,7 @@ static int expandrow2(
static void interleaverow(uchar *lptr, const uchar *cptr, int z, int n);
static void interleaverow2(float *lptr, const uchar *cptr, int z, int n);
static int compressrow(uchar *lbuf, uchar *rlebuf, int z, int cnt);
-static void lumrow(uchar *rgbptr, uchar *lumptr, int n);
+static void lumrow(const uchar *rgbptr, uchar *lumptr, int n);
/*
* byte order independent read/write of shorts and ints.
@@ -900,7 +900,7 @@ static int output_iris(uint *lptr, int xsize, int ysize, int zsize, const char *
/* static utility functions for output_iris */
-static void lumrow(uchar *rgbptr, uchar *lumptr, int n)
+static void lumrow(const uchar *rgbptr, uchar *lumptr, int n)
{
lumptr += CHANOFFSET(0);
while (n--) {
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index 5154f50c7e8..f81c005bf06 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -651,7 +651,7 @@ BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
-static int initialise_4K_poc(opj_poc_t *POC, int numres)
+static int init_4K_poc(opj_poc_t *POC, int numres)
{
POC[0].tile = 1;
POC[0].resno0 = 0;
@@ -750,7 +750,7 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters,
else {
parameters->cp_rsiz = DCP_CINEMA2K;
}
- parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution);
+ parameters->numpocs = init_4K_poc(parameters->POC, parameters->numresolution);
break;
case OPJ_OFF:
/* do nothing */
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.h b/source/blender/imbuf/intern/oiio/openimageio_api.h
index 3dd089d65cb..3f5f234099c 100644
--- a/source/blender/imbuf/intern/oiio/openimageio_api.h
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.h
@@ -21,8 +21,7 @@
* \ingroup openimageio
*/
-#ifndef __OPENIMAGEIO_API_H__
-#define __OPENIMAGEIO_API_H__
+#pragma once
#include <stdio.h>
@@ -44,5 +43,3 @@ int OIIO_getVersionHex(void);
}
#endif
-
-#endif /* __OPENIMAGEIO_API_H__ */
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 2a5532a0902..a781c616b1c 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -741,7 +741,7 @@ static void imb_exr_get_views(MultiPartInputFile &file, StringVector &views)
else {
for (int p = 0; p < file.parts(); p++) {
- std::string view = "";
+ std::string view;
if (file.header(p).hasView()) {
view = file.header(p).view();
}
@@ -1209,7 +1209,7 @@ void IMB_exr_read_channels(void *handle)
ExrHandle *data = (ExrHandle *)handle;
int numparts = data->ifile->parts();
- /* check if exr was saved with previous versions of blender which flipped images */
+ /* Check if EXR was saved with previous versions of blender which flipped images. */
const StringAttribute *ta = data->ifile->header(0).findTypedAttribute<StringAttribute>(
"BlenderMultiChannel");
@@ -1723,11 +1723,25 @@ static const char *exr_rgba_channelname(MultiPartInputFile &file, const char *ch
return chan;
}
-static bool exr_has_rgb(MultiPartInputFile &file)
+static int exr_has_rgb(MultiPartInputFile &file, const char *rgb_channels[3])
{
- return file.header(0).channels().findChannel("R") != NULL &&
- file.header(0).channels().findChannel("G") != NULL &&
- file.header(0).channels().findChannel("B") != NULL;
+ /* Common names for RGB-like channels in order. */
+ static const char *channel_names[] = {
+ "R", "Red", "G", "Green", "B", "Blue", "AR", "RA", "AG", "GA", "AB", "BA", NULL};
+
+ const Header &header = file.header(0);
+ int num_channels = 0;
+
+ for (int i = 0; channel_names[i]; i++) {
+ if (header.channels().findChannel(channel_names[i])) {
+ rgb_channels[num_channels++] = channel_names[i];
+ if (num_channels == 3) {
+ break;
+ }
+ }
+ }
+
+ return num_channels;
}
static bool exr_has_luma(MultiPartInputFile &file)
@@ -1735,23 +1749,27 @@ static bool exr_has_luma(MultiPartInputFile &file)
/* Y channel is the luma and should always present fir luma space images,
* optionally it could be also channels for chromas called BY and RY.
*/
- return file.header(0).channels().findChannel("Y") != NULL;
+ const Header &header = file.header(0);
+ return header.channels().findChannel("Y") != NULL;
}
static bool exr_has_chroma(MultiPartInputFile &file)
{
- return file.header(0).channels().findChannel("BY") != NULL &&
- file.header(0).channels().findChannel("RY") != NULL;
+ const Header &header = file.header(0);
+ return header.channels().findChannel("BY") != NULL &&
+ header.channels().findChannel("RY") != NULL;
}
static bool exr_has_zbuffer(MultiPartInputFile &file)
{
- return !(file.header(0).channels().findChannel("Z") == NULL);
+ const Header &header = file.header(0);
+ return !(header.channels().findChannel("Z") == NULL);
}
static bool exr_has_alpha(MultiPartInputFile &file)
{
- return !(file.header(0).channels().findChannel("A") == NULL);
+ const Header &header = file.header(0);
+ return !(header.channels().findChannel("A") == NULL);
}
static bool exr_is_half_float(MultiPartInputFile &file)
@@ -1803,12 +1821,12 @@ static void imb_exr_type_by_channels(ChannelList &channels,
}
if (!layerNames.empty()) {
- /* if layerNames is not empty, it means at least one layer is non-empty,
+ /* If `layerNames` is not empty, it means at least one layer is non-empty,
* but it also could be layers without names in the file and such case
- * shall be considered a multilayer exr
+ * shall be considered a multi-layer EXR.
*
- * that's what we do here: test whether there're empty layer names together
- * with non-empty ones in the file
+ * That's what we do here: test whether there are empty layer names together
+ * with non-empty ones in the file.
*/
for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); i++) {
for (std::set<string>::iterator i = layerNames.begin(); i != layerNames.end(); i++) {
@@ -1957,7 +1975,8 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem,
}
}
else {
- const bool has_rgb = exr_has_rgb(*file);
+ const char *rgb_channels[3];
+ const int num_rgb_channels = exr_has_rgb(*file, rgb_channels);
const bool has_luma = exr_has_luma(*file);
FrameBuffer frameBuffer;
float *first;
@@ -1972,13 +1991,11 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem,
/* but, since we read y-flipped (negative y stride) we move to last scanline */
first += 4 * (height - 1) * width;
- if (has_rgb) {
- frameBuffer.insert(exr_rgba_channelname(*file, "R"),
- Slice(Imf::FLOAT, (char *)first, xstride, ystride));
- frameBuffer.insert(exr_rgba_channelname(*file, "G"),
- Slice(Imf::FLOAT, (char *)(first + 1), xstride, ystride));
- frameBuffer.insert(exr_rgba_channelname(*file, "B"),
- Slice(Imf::FLOAT, (char *)(first + 2), xstride, ystride));
+ if (num_rgb_channels > 0) {
+ for (int i = 0; i < num_rgb_channels; i++) {
+ frameBuffer.insert(exr_rgba_channelname(*file, rgb_channels[i]),
+ Slice(Imf::FLOAT, (char *)(first + i), xstride, ystride));
+ }
}
else if (has_luma) {
frameBuffer.insert(exr_rgba_channelname(*file, "Y"),
@@ -2021,24 +2038,27 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem,
// IMB_rect_from_float(ibuf);
// }
- if (!has_rgb && has_luma) {
- size_t a;
- if (exr_has_chroma(*file)) {
- for (a = 0; a < (size_t)ibuf->x * ibuf->y; a++) {
- float *color = ibuf->rect_float + a * 4;
- ycc_to_rgb(color[0] * 255.0f,
- color[1] * 255.0f,
- color[2] * 255.0f,
- &color[0],
- &color[1],
- &color[2],
- BLI_YCC_ITU_BT709);
- }
+ if (num_rgb_channels == 0 && has_luma && exr_has_chroma(*file)) {
+ for (size_t a = 0; a < (size_t)ibuf->x * ibuf->y; a++) {
+ float *color = ibuf->rect_float + a * 4;
+ ycc_to_rgb(color[0] * 255.0f,
+ color[1] * 255.0f,
+ color[2] * 255.0f,
+ &color[0],
+ &color[1],
+ &color[2],
+ BLI_YCC_ITU_BT709);
}
- else {
- for (a = 0; a < (size_t)ibuf->x * ibuf->y; a++) {
- float *color = ibuf->rect_float + a * 4;
- color[1] = color[2] = color[0];
+ }
+ else if (num_rgb_channels <= 1) {
+ /* Convert 1 to 3 channels. */
+ for (size_t a = 0; a < (size_t)ibuf->x * ibuf->y; a++) {
+ float *color = ibuf->rect_float + a * 4;
+ if (num_rgb_channels <= 1) {
+ color[1] = color[0];
+ }
+ if (num_rgb_channels <= 2) {
+ color[2] = color[0];
}
}
}
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.h b/source/blender/imbuf/intern/openexr/openexr_api.h
index b0835e5082e..73db146849b 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.h
+++ b/source/blender/imbuf/intern/openexr/openexr_api.h
@@ -21,8 +21,7 @@
* \ingroup openexr
*/
-#ifndef __OPENEXR_API_H__
-#define __OPENEXR_API_H__
+#pragma once
#include <stdio.h>
@@ -42,5 +41,3 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem, size_t size, int flags,
#ifdef __cplusplus
}
#endif
-
-#endif /* __OPENEXR_API_H */
diff --git a/source/blender/imbuf/intern/openexr/openexr_multi.h b/source/blender/imbuf/intern/openexr/openexr_multi.h
index 58f103aeba0..7008447313d 100644
--- a/source/blender/imbuf/intern/openexr/openexr_multi.h
+++ b/source/blender/imbuf/intern/openexr/openexr_multi.h
@@ -21,8 +21,7 @@
* \ingroup openexr
*/
-#ifndef __OPENEXR_MULTI_H__
-#define __OPENEXR_MULTI_H__
+#pragma once
/* experiment with more advanced exr api */
@@ -99,5 +98,3 @@ bool IMB_exr_has_multilayer(void *handle);
#ifdef __cplusplus
} // extern "C"
#endif
-
-#endif /* __OPENEXR_MULTI_H */
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index 46d07e74ce3..6ed01c73f04 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -176,7 +176,7 @@ static void RGBE2FLOAT(RGBE rgbe, fCOLOR fcol)
}
/* float color -> rgbe */
-static void FLOAT2RGBE(fCOLOR fcol, RGBE rgbe)
+static void FLOAT2RGBE(const fCOLOR fcol, RGBE rgbe)
{
int e;
float d = (fcol[RED] > fcol[GRN]) ? fcol[RED] : fcol[GRN];
@@ -308,7 +308,8 @@ struct ImBuf *imb_loadhdr(const unsigned char *mem,
}
/* ImBuf write */
-static int fwritecolrs(FILE *file, int width, int channels, unsigned char *ibufscan, float *fpscan)
+static int fwritecolrs(
+ FILE *file, int width, int channels, const unsigned char *ibufscan, const float *fpscan)
{
int beg, c2, cnt = 0;
fCOLOR fcol;
diff --git a/source/blender/imbuf/intern/stereoimbuf.c b/source/blender/imbuf/intern/stereoimbuf.c
index 5569e119b95..247122065de 100644
--- a/source/blender/imbuf/intern/stereoimbuf.c
+++ b/source/blender/imbuf/intern/stereoimbuf.c
@@ -669,17 +669,17 @@ static void imb_stereo3d_squeeze_rect(
/*************************** preparing to call the write functions **************************/
-static void imb_stereo3d_data_initialize(Stereo3DData *s3d_data,
- const bool is_float,
- const size_t x,
- const size_t y,
- const size_t channels,
- int *rect_left,
- int *rect_right,
- int *rect_stereo,
- float *rectf_left,
- float *rectf_right,
- float *rectf_stereo)
+static void imb_stereo3d_data_init(Stereo3DData *s3d_data,
+ const bool is_float,
+ const size_t x,
+ const size_t y,
+ const size_t channels,
+ int *rect_left,
+ int *rect_right,
+ int *rect_stereo,
+ float *rectf_left,
+ float *rectf_right,
+ float *rectf_stereo)
{
s3d_data->is_float = is_float;
s3d_data->x = x;
@@ -709,7 +709,7 @@ int *IMB_stereo3d_from_rect(ImageFormatData *im_format,
im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
r_rect = MEM_mallocN(channels * sizeof(int) * width * height, __func__);
- imb_stereo3d_data_initialize(
+ imb_stereo3d_data_init(
&s3d_data, is_float, x, y, channels, rect_left, rect_right, r_rect, NULL, NULL, NULL);
imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
imb_stereo3d_squeeze_rect(r_rect, &im_format->stereo3d_format, x, y, channels);
@@ -733,7 +733,7 @@ float *IMB_stereo3d_from_rectf(ImageFormatData *im_format,
im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
r_rectf = MEM_mallocN(channels * sizeof(float) * width * height, __func__);
- imb_stereo3d_data_initialize(
+ imb_stereo3d_data_init(
&s3d_data, is_float, x, y, channels, NULL, NULL, NULL, rectf_left, rectf_right, r_rectf);
imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
imb_stereo3d_squeeze_rectf(r_rectf, &im_format->stereo3d_format, x, y, channels);
@@ -759,17 +759,17 @@ ImBuf *IMB_stereo3d_ImBuf(ImageFormatData *im_format, ImBuf *ibuf_left, ImBuf *i
ibuf_stereo->flags = ibuf_left->flags;
- imb_stereo3d_data_initialize(&s3d_data,
- is_float,
- ibuf_left->x,
- ibuf_left->y,
- 4,
- (int *)ibuf_left->rect,
- (int *)ibuf_right->rect,
- (int *)ibuf_stereo->rect,
- ibuf_left->rect_float,
- ibuf_right->rect_float,
- ibuf_stereo->rect_float);
+ imb_stereo3d_data_init(&s3d_data,
+ is_float,
+ ibuf_left->x,
+ ibuf_left->y,
+ 4,
+ (int *)ibuf_left->rect,
+ (int *)ibuf_right->rect,
+ (int *)ibuf_stereo->rect,
+ ibuf_left->rect_float,
+ ibuf_right->rect_float,
+ ibuf_stereo->rect_float);
imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
imb_stereo3d_squeeze_ImBuf(ibuf_stereo, &im_format->stereo3d_format, ibuf_left->x, ibuf_left->y);
@@ -1286,17 +1286,17 @@ void IMB_ImBufFromStereo3d(Stereo3dFormat *s3d,
&height);
imb_stereo3d_unsqueeze_ImBuf(ibuf_stereo3d, s3d, width, height);
- imb_stereo3d_data_initialize(&s3d_data,
- is_float,
- ibuf_left->x,
- ibuf_left->y,
- 4,
- (int *)ibuf_left->rect,
- (int *)ibuf_right->rect,
- (int *)ibuf_stereo3d->rect,
- ibuf_left->rect_float,
- ibuf_right->rect_float,
- ibuf_stereo3d->rect_float);
+ imb_stereo3d_data_init(&s3d_data,
+ is_float,
+ ibuf_left->x,
+ ibuf_left->y,
+ 4,
+ (int *)ibuf_left->rect,
+ (int *)ibuf_right->rect,
+ (int *)ibuf_stereo3d->rect,
+ ibuf_left->rect_float,
+ ibuf_right->rect_float,
+ ibuf_stereo3d->rect_float);
imb_stereo3d_read_doit(&s3d_data, s3d);
@@ -1310,17 +1310,17 @@ void IMB_ImBufFromStereo3d(Stereo3dFormat *s3d,
addzbufImBuf(ibuf_right);
}
- imb_stereo3d_data_initialize(&s3d_data,
- is_float,
- ibuf_left->x,
- ibuf_left->y,
- 1,
- (int *)ibuf_left->zbuf,
- (int *)ibuf_right->zbuf,
- (int *)ibuf_stereo3d->zbuf,
- ibuf_left->zbuf_float,
- ibuf_right->zbuf_float,
- ibuf_stereo3d->zbuf_float);
+ imb_stereo3d_data_init(&s3d_data,
+ is_float,
+ ibuf_left->x,
+ ibuf_left->y,
+ 1,
+ (int *)ibuf_left->zbuf,
+ (int *)ibuf_right->zbuf,
+ (int *)ibuf_stereo3d->zbuf,
+ ibuf_left->zbuf_float,
+ ibuf_right->zbuf_float,
+ ibuf_stereo3d->zbuf_float);
imb_stereo3d_read_doit(&s3d_data, s3d);
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 309de25db03..715f2aaf621 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -81,14 +81,24 @@ typedef struct ImbTIFFMemFile {
* Function implementations. *
*****************************/
-static void imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
+static void imb_tiff_DummyUnmapProc(
+ thandle_t fd,
+ tdata_t base,
+ /* Cannot be const, because this function implements #TIFFUnmapFileProc.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ toff_t size)
{
(void)fd;
(void)base;
(void)size;
}
-static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t *pbase, toff_t *psize)
+static int imb_tiff_DummyMapProc(
+ thandle_t fd,
+ tdata_t *pbase,
+ /* Cannot be const, because this function implements #TIFFMapFileProc.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ toff_t *psize)
{
(void)fd;
(void)pbase;
@@ -100,7 +110,7 @@ static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t *pbase, toff_t *psize)
/**
* Reads data from an in-memory TIFF file.
*
- * \param handle: Handle of the TIFF file (pointer to ImbTIFFMemFile).
+ * \param handle: Handle of the TIFF file (pointer to #ImbTIFFMemFile).
* \param data: Buffer to contain data (treat as (void *)).
* \param n: Number of bytes to read.
*
diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c
new file mode 100644
index 00000000000..52628f5aaad
--- /dev/null
+++ b/source/blender/imbuf/intern/util_gpu.c
@@ -0,0 +1,261 @@
+/*
+ * 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.
+ * util.c
+ */
+
+/** \file
+ * \ingroup imbuf
+ */
+
+#include "imbuf.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "MEM_guardedalloc.h"
+
+#include "BKE_global.h"
+
+#include "GPU_extensions.h"
+#include "GPU_texture.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+/* gpu ibuf utils */
+
+static void imb_gpu_get_format(const ImBuf *ibuf,
+ bool high_bitdepth,
+ eGPUDataFormat *r_data_format,
+ eGPUTextureFormat *r_texture_format)
+{
+ const bool float_rect = (ibuf->rect_float != NULL);
+ const bool use_srgb = (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace) &&
+ !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace));
+ high_bitdepth = (!(ibuf->flags & IB_halffloat) && high_bitdepth);
+
+ *r_data_format = (float_rect) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+
+ if (float_rect) {
+ *r_texture_format = high_bitdepth ? GPU_RGBA32F : GPU_RGBA16F;
+ }
+ else {
+ *r_texture_format = use_srgb ? GPU_SRGB8_A8 : GPU_RGBA8;
+ }
+}
+
+/* Return false if no suitable format was found. */
+#ifdef WITH_DDS
+static bool IMB_gpu_get_compressed_format(const ImBuf *ibuf, eGPUTextureFormat *r_texture_format)
+{
+ /* For DDS we only support data, scene linear and sRGB. Converting to
+ * different colorspace would break the compression. */
+ const bool use_srgb = (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace) &&
+ !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace));
+
+ if (ibuf->dds_data.fourcc == FOURCC_DXT1) {
+ *r_texture_format = (use_srgb) ? GPU_SRGB8_A8_DXT1 : GPU_RGBA8_DXT1;
+ }
+ else if (ibuf->dds_data.fourcc == FOURCC_DXT3) {
+ *r_texture_format = (use_srgb) ? GPU_SRGB8_A8_DXT3 : GPU_RGBA8_DXT3;
+ }
+ else if (ibuf->dds_data.fourcc == FOURCC_DXT5) {
+ *r_texture_format = (use_srgb) ? GPU_SRGB8_A8_DXT5 : GPU_RGBA8_DXT5;
+ }
+ else {
+ return false;
+ }
+ return true;
+}
+#endif
+
+/**
+ * Apply colormanagement and scale buffer if needed.
+ * *r_freedata is set to true if the returned buffer need to be manually freed.
+ **/
+static void *imb_gpu_get_data(const ImBuf *ibuf,
+ const bool do_rescale,
+ const int rescale_size[2],
+ const bool compress_as_srgb,
+ const bool store_premultiplied,
+ bool *r_freedata)
+{
+ const bool is_float_rect = (ibuf->rect_float != NULL);
+ void *data_rect = (is_float_rect) ? (void *)ibuf->rect_float : (void *)ibuf->rect;
+
+ if (is_float_rect) {
+ /* Float image is already in scene linear colorspace or non-color data by
+ * convention, no colorspace conversion needed. But we do require 4 channels
+ * currently. */
+ if (ibuf->channels != 4 || !store_premultiplied) {
+ data_rect = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__);
+ *r_freedata = true;
+
+ if (data_rect == NULL) {
+ return NULL;
+ }
+
+ IMB_colormanagement_imbuf_to_float_texture(
+ (float *)data_rect, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied);
+ }
+ }
+ else {
+ /* Byte image is in original colorspace from the file. If the file is sRGB
+ * scene linear, or non-color data no conversion is needed. Otherwise we
+ * compress as scene linear + sRGB transfer function to avoid precision loss
+ * in common cases.
+ *
+ * We must also convert to premultiplied for correct texture interpolation
+ * and consistency with float images. */
+ if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
+ data_rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__);
+ *r_freedata = true;
+
+ if (data_rect == NULL) {
+ return NULL;
+ }
+
+ /* Texture storage of images is defined by the alpha mode of the image. The
+ * downside of this is that there can be artifacts near alpha edges. However,
+ * this allows us to use sRGB texture formats and preserves color values in
+ * zero alpha areas, and appears generally closer to what game engines that we
+ * want to be compatible with do. */
+ IMB_colormanagement_imbuf_to_byte_texture(
+ (uchar *)data_rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied);
+ }
+ }
+
+ if (do_rescale) {
+ uint *rect = (is_float_rect) ? NULL : (uint *)data_rect;
+ float *rect_float = (is_float_rect) ? (float *)data_rect : NULL;
+
+ ImBuf *scale_ibuf = IMB_allocFromBuffer(rect, rect_float, ibuf->x, ibuf->y, 4);
+ IMB_scaleImBuf(scale_ibuf, UNPACK2(rescale_size));
+
+ data_rect = (is_float_rect) ? (void *)scale_ibuf->rect_float : (void *)scale_ibuf->rect;
+ *r_freedata = true;
+ /* Steal the rescaled buffer to avoid double free. */
+ scale_ibuf->rect_float = NULL;
+ scale_ibuf->rect = NULL;
+ IMB_freeImBuf(scale_ibuf);
+ }
+ return data_rect;
+}
+
+/* The ibuf is only here to detect the storage type. The produced texture will have undefined
+ * content. It will need to be populated by using IMB_update_gpu_texture_sub(). */
+GPUTexture *IMB_touch_gpu_texture(ImBuf *ibuf, int w, int h, int layers, bool use_high_bitdepth)
+{
+ eGPUDataFormat data_format;
+ eGPUTextureFormat tex_format;
+ imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format);
+
+ GPUTexture *tex = GPU_texture_create_nD(
+ w, h, layers, 2, NULL, tex_format, data_format, 0, false, NULL);
+
+ GPU_texture_anisotropic_filter(tex, true);
+ return tex;
+}
+
+/* Will update a GPUTexture using the content of the ImBuf. Only one layer will be updated.
+ * Will resize the ibuf if needed.
+ * z is the layer to update. Unused if the texture is 2D. */
+void IMB_update_gpu_texture_sub(GPUTexture *tex,
+ ImBuf *ibuf,
+ int x,
+ int y,
+ int z,
+ int w,
+ int h,
+ bool use_high_bitdepth,
+ bool use_premult)
+{
+ const bool do_rescale = (ibuf->x != w || ibuf->y != h);
+ int size[2] = {w, h};
+
+ eGPUDataFormat data_format;
+ eGPUTextureFormat tex_format;
+ imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format);
+
+ const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8);
+ bool freebuf = false;
+
+ void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf);
+
+ /* Update Texture. */
+ GPU_texture_update_sub(tex, data_format, data, x, y, z, w, h, 1);
+
+ if (freebuf) {
+ MEM_freeN(data);
+ }
+}
+
+GPUTexture *IMB_create_gpu_texture(ImBuf *ibuf, bool use_high_bitdepth, bool use_premult)
+{
+ GPUTexture *tex = NULL;
+ int size[2] = {GPU_texture_size_with_limit(ibuf->x), GPU_texture_size_with_limit(ibuf->y)};
+ bool do_rescale = (ibuf->x != size[0]) || (ibuf->y != size[1]);
+
+#ifdef WITH_DDS
+ if (ibuf->ftype == IMB_FTYPE_DDS) {
+ eGPUTextureFormat compressed_format;
+ if (!IMB_gpu_get_compressed_format(ibuf, &compressed_format)) {
+ fprintf(stderr, "Unable to find a suitable DXT compression,");
+ }
+ else if (do_rescale) {
+ fprintf(stderr, "Unable to load DXT image resolution,");
+ }
+ else if (!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) {
+ fprintf(stderr, "Unable to load non-power-of-two DXT image resolution,");
+ }
+ else {
+ tex = GPU_texture_create_compressed(
+ ibuf->x, ibuf->y, ibuf->dds_data.nummipmaps, compressed_format, ibuf->dds_data.data);
+
+ if (tex != NULL) {
+ return tex;
+ }
+ else {
+ fprintf(stderr, "ST3C support not found,");
+ }
+ }
+ /* Fallback to uncompressed texture. */
+ fprintf(stderr, " falling back to uncompressed.\n");
+ }
+#endif
+
+ eGPUDataFormat data_format;
+ eGPUTextureFormat tex_format;
+ imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format);
+
+ const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8);
+ bool freebuf = false;
+
+ void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf);
+
+ /* Create Texture. */
+ tex = GPU_texture_create_nD(UNPACK2(size), 0, 2, data, tex_format, data_format, 0, false, NULL);
+
+ GPU_texture_anisotropic_filter(tex, true);
+
+ if (freebuf) {
+ MEM_freeN(data);
+ }
+
+ return tex;
+}
diff --git a/source/blender/io/alembic/ABC_alembic.h b/source/blender/io/alembic/ABC_alembic.h
index ddf75aa3258..67f8aeb0a67 100644
--- a/source/blender/io/alembic/ABC_alembic.h
+++ b/source/blender/io/alembic/ABC_alembic.h
@@ -128,6 +128,16 @@ struct CacheReader *CacheReader_open_alembic_object(struct AbcArchiveHandle *han
struct Object *object,
const char *object_path);
+bool ABC_has_vec3_array_property_named(struct CacheReader *reader, const char *name);
+
+/* r_vertex_velocities should point to a preallocated array of num_vertices floats */
+int ABC_read_velocity_cache(struct CacheReader *reader,
+ const char *velocity_name,
+ float time,
+ float fps,
+ int num_vertices,
+ float *r_vertex_velocities);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/io/alembic/CMakeLists.txt b/source/blender/io/alembic/CMakeLists.txt
index da36272b850..681d6d04acd 100644
--- a/source/blender/io/alembic/CMakeLists.txt
+++ b/source/blender/io/alembic/CMakeLists.txt
@@ -63,8 +63,8 @@ set(SRC
exporter/abc_writer_camera.cc
exporter/abc_writer_curves.cc
exporter/abc_writer_hair.cc
- exporter/abc_writer_mesh.cc
exporter/abc_writer_mball.cc
+ exporter/abc_writer_mesh.cc
exporter/abc_writer_nurbs.cc
exporter/abc_writer_points.cc
exporter/abc_writer_transform.cc
@@ -89,8 +89,8 @@ set(SRC
exporter/abc_writer_camera.h
exporter/abc_writer_curves.h
exporter/abc_writer_hair.h
- exporter/abc_writer_mesh.h
exporter/abc_writer_mball.h
+ exporter/abc_writer_mesh.h
exporter/abc_writer_nurbs.h
exporter/abc_writer_points.h
exporter/abc_writer_transform.h
diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc
index fbc5b2d5c02..8c5f3d89870 100644
--- a/source/blender/io/alembic/exporter/abc_export_capi.cc
+++ b/source/blender/io/alembic/exporter/abc_export_capi.cc
@@ -48,6 +48,7 @@
static CLG_LogRef LOG = {"io.alembic"};
#include <algorithm>
+#include <memory>
struct ExportJobData {
Main *bmain;
@@ -73,7 +74,12 @@ static void build_depsgraph(Depsgraph *depsgraph, Main *bmain)
DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer);
}
-static void export_startjob(void *customdata, short *stop, short *do_update, float *progress)
+static void export_startjob(void *customdata,
+ /* Cannot be const, this function implements wm_jobs_start_callback.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ short *stop,
+ short *do_update,
+ float *progress)
{
ExportJobData *data = static_cast<ExportJobData *>(customdata);
data->was_canceled = false;
@@ -98,17 +104,41 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo
const bool export_animation = (data->params.frame_start != data->params.frame_end);
// Create the Alembic archive.
- ABCArchive abc_archive(data->bmain, scene, data->params, std::string(data->filename));
+ std::unique_ptr<ABCArchive> abc_archive;
+ try {
+ abc_archive = std::make_unique<ABCArchive>(
+ data->bmain, scene, data->params, std::string(data->filename));
+ }
+ catch (const std::exception &ex) {
+ std::stringstream error_message_stream;
+ error_message_stream << "Error writing to " << data->filename;
+ const std::string &error_message = error_message_stream.str();
+
+ // The exception message can be very cryptic (just "iostream error" on Linux, for example), so
+ // better not to include it in the report.
+ CLOG_ERROR(&LOG, "%s: %s", error_message.c_str(), ex.what());
+ WM_report(RPT_ERROR, error_message.c_str());
+ data->export_ok = false;
+ return;
+ }
+ catch (...) {
+ // Unknown exception class, so we cannot include its message.
+ std::stringstream error_message_stream;
+ error_message_stream << "Unknown error writing to " << data->filename;
+ WM_report(RPT_ERROR, error_message_stream.str().c_str());
+ data->export_ok = false;
+ return;
+ }
- ABCHierarchyIterator iter(data->depsgraph, &abc_archive, data->params);
+ ABCHierarchyIterator iter(data->depsgraph, abc_archive.get(), data->params);
if (export_animation) {
CLOG_INFO(&LOG, 2, "Exporting animation");
// Writing the animated frames is not 100% of the work, but it's our best guess.
- const float progress_per_frame = 1.0f / std::max(size_t(1), abc_archive.total_frame_count());
- ABCArchive::Frames::const_iterator frame_it = abc_archive.frames_begin();
- const ABCArchive::Frames::const_iterator frames_end = abc_archive.frames_end();
+ const float progress_per_frame = 1.0f / std::max(size_t(1), abc_archive->total_frame_count());
+ ABCArchive::Frames::const_iterator frame_it = abc_archive->frames_begin();
+ const ABCArchive::Frames::const_iterator frames_end = abc_archive->frames_end();
for (; frame_it != frames_end; frame_it++) {
double frame = *frame_it;
@@ -123,7 +153,7 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo
BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain);
CLOG_INFO(&LOG, 2, "Exporting frame %.2f", frame);
- ExportSubset export_subset = abc_archive.export_subset_for_frame(frame);
+ ExportSubset export_subset = abc_archive->export_subset_for_frame(frame);
iter.set_export_subset(export_subset);
iter.iterate_and_write();
diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
index 90004c0e85b..5b1b1b60b48 100644
--- a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
+++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
@@ -89,7 +89,7 @@ bool ABCHierarchyIterator::mark_as_weak_export(const Object *object) const
return false;
}
-void ABCHierarchyIterator::delete_object_writer(AbstractHierarchyWriter *writer)
+void ABCHierarchyIterator::release_writer(AbstractHierarchyWriter *writer)
{
delete writer;
}
@@ -107,20 +107,23 @@ AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::
determine_graph_index_object(const HierarchyContext *context)
{
if (params_.flatten_hierarchy) {
- return std::make_pair(nullptr, nullptr);
+ return ObjectIdentifier::for_graph_root();
}
return AbstractHierarchyIterator::determine_graph_index_object(context);
}
AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::determine_graph_index_dupli(
- const HierarchyContext *context, const std::set<Object *> &dupli_set)
+ const HierarchyContext *context,
+ const DupliObject *dupli_object,
+ const DupliParentFinder &dupli_parent_finder)
{
if (params_.flatten_hierarchy) {
- return std::make_pair(nullptr, nullptr);
+ return ObjectIdentifier::for_graph_root();
}
- return AbstractHierarchyIterator::determine_graph_index_dupli(context, dupli_set);
+ return AbstractHierarchyIterator::determine_graph_index_dupli(
+ context, dupli_object, dupli_parent_finder);
}
Alembic::Abc::OObject ABCHierarchyIterator::get_alembic_parent(
diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h
index edcb31806ba..bd7e3f27c67 100644
--- a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h
+++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.h
@@ -67,7 +67,9 @@ class ABCHierarchyIterator : public AbstractHierarchyIterator {
virtual ExportGraph::key_type determine_graph_index_object(
const HierarchyContext *context) override;
virtual AbstractHierarchyIterator::ExportGraph::key_type determine_graph_index_dupli(
- const HierarchyContext *context, const std::set<Object *> &dupli_set) override;
+ const HierarchyContext *context,
+ const DupliObject *dupli_object,
+ const DupliParentFinder &dupli_parent_finder) override;
virtual AbstractHierarchyWriter *create_transform_writer(
const HierarchyContext *context) override;
@@ -76,7 +78,7 @@ class ABCHierarchyIterator : public AbstractHierarchyIterator {
virtual AbstractHierarchyWriter *create_particle_writer(
const HierarchyContext *context) override;
- virtual void delete_object_writer(AbstractHierarchyWriter *writer) override;
+ virtual void release_writer(AbstractHierarchyWriter *writer) override;
private:
Alembic::Abc::OObject get_alembic_parent(const HierarchyContext *context) const;
diff --git a/source/blender/io/alembic/exporter/abc_writer_curves.cc b/source/blender/io/alembic/exporter/abc_writer_curves.cc
index f2a46c5e4fe..6f185020b58 100644
--- a/source/blender/io/alembic/exporter/abc_writer_curves.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_curves.cc
@@ -80,9 +80,9 @@ void ABCCurveWriter::do_write(HierarchyContext &context)
std::vector<uint8_t> orders;
Imath::V3f temp_vert;
- Alembic::AbcGeom::BasisType curve_basis;
- Alembic::AbcGeom::CurveType curve_type;
- Alembic::AbcGeom::CurvePeriodicity periodicity;
+ Alembic::AbcGeom::BasisType curve_basis = Alembic::AbcGeom::kNoBasis;
+ Alembic::AbcGeom::CurveType curve_type = Alembic::AbcGeom::kVariableOrder;
+ Alembic::AbcGeom::CurvePeriodicity periodicity = Alembic::AbcGeom::kNonPeriodic;
Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
for (; nurbs; nurbs = nurbs->next) {
diff --git a/source/blender/io/alembic/exporter/abc_writer_nurbs.cc b/source/blender/io/alembic/exporter/abc_writer_nurbs.cc
index 1fd382214a6..14cb7773e67 100644
--- a/source/blender/io/alembic/exporter/abc_writer_nurbs.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_nurbs.cc
@@ -64,7 +64,7 @@ void ABCNurbsWriter::create_alembic_objects(const HierarchyContext *context)
std::string patch_name = patch_name_stream.str();
CLOG_INFO(&LOG, 2, "exporting %s/%s", abc_parent_path, patch_name.c_str());
- ONuPatch nurbs(abc_parent, patch_name.c_str(), timesample_index_);
+ ONuPatch nurbs(abc_parent, patch_name, timesample_index_);
abc_nurbs_.push_back(nurbs);
abc_nurbs_schemas_.push_back(nurbs.getSchema());
}
diff --git a/source/blender/io/alembic/exporter/abc_writer_transform.cc b/source/blender/io/alembic/exporter/abc_writer_transform.cc
index 65d6b7c5b41..39af99c142c 100644
--- a/source/blender/io/alembic/exporter/abc_writer_transform.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_transform.cc
@@ -107,6 +107,9 @@ bool ABCTransformWriter::check_is_animated(const HierarchyContext &context) cons
* depsgraph whether this object instance has a time source. */
return true;
}
+ if (check_has_physics(context)) {
+ return true;
+ }
return BKE_object_moves_in_time(context.object, context.animation_check_include_parent);
}
diff --git a/source/blender/io/alembic/intern/abc_axis_conversion.cc b/source/blender/io/alembic/intern/abc_axis_conversion.cc
index cebab1f2e41..396c8fdb28b 100644
--- a/source/blender/io/alembic/intern/abc_axis_conversion.cc
+++ b/source/blender/io/alembic/intern/abc_axis_conversion.cc
@@ -170,4 +170,4 @@ void create_transform_matrix(Object *obj,
} // namespace alembic
} // namespace io
-} // namespace blender \ No newline at end of file
+} // namespace blender
diff --git a/source/blender/io/alembic/intern/abc_axis_conversion.h b/source/blender/io/alembic/intern/abc_axis_conversion.h
index 9a19e9116be..645d9fc783b 100644
--- a/source/blender/io/alembic/intern/abc_axis_conversion.h
+++ b/source/blender/io/alembic/intern/abc_axis_conversion.h
@@ -100,4 +100,4 @@ void create_transform_matrix(Object *obj,
} // namespace alembic
} // namespace io
-} // namespace blender \ No newline at end of file
+} // namespace blender
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index 756dde3783c..98130eb28cd 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -104,7 +104,7 @@ static void assign_materials(Main *bmain,
for (; it != mat_index_map.end(); ++it) {
std::string mat_name = it->first;
- mat_iter = mat_map.find(mat_name.c_str());
+ mat_iter = mat_map.find(mat_name);
Material *assigned_mat;
diff --git a/source/blender/io/alembic/intern/abc_reader_object.cc b/source/blender/io/alembic/intern/abc_reader_object.cc
index 39b9cd4c161..06b0c07f4c5 100644
--- a/source/blender/io/alembic/intern/abc_reader_object.cc
+++ b/source/blender/io/alembic/intern/abc_reader_object.cc
@@ -236,7 +236,7 @@ Alembic::AbcGeom::IXform AbcObjectReader::xform()
* parent Alembic object should contain the transform. */
IObject abc_parent = m_iobject.getParent();
- /* The archive's top object can be recognised by not having a parent. */
+ /* The archive's top object can be recognized by not having a parent. */
if (abc_parent.getParent() && IXform::matches(abc_parent.getMetaData())) {
try {
return IXform(abc_parent, Alembic::AbcGeom::kWrapExisting);
diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc
index 7cde2d4fe73..eba7f64db02 100644
--- a/source/blender/io/alembic/intern/alembic_capi.cc
+++ b/source/blender/io/alembic/intern/alembic_capi.cc
@@ -22,6 +22,7 @@
#include <Alembic/AbcMaterial/IMaterial.h>
+#include "abc_axis_conversion.h"
#include "abc_reader_archive.h"
#include "abc_reader_camera.h"
#include "abc_reader_curves.h"
@@ -47,18 +48,13 @@
#include "BKE_lib_id.h"
#include "BKE_object.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "ED_undo.h"
-/* SpaceType struct has a member called 'new' which obviously conflicts with C++
- * so temporarily redefining the new keyword to make it compile. */
-#define new extern_new
-#include "BKE_screen.h"
-#undef new
-
#include "BLI_compiler_compat.h"
#include "BLI_fileops.h"
#include "BLI_ghash.h"
@@ -70,7 +66,10 @@
#include "WM_api.h"
#include "WM_types.h"
+using Alembic::Abc::IV3fArrayProperty;
using Alembic::Abc::ObjectHeader;
+using Alembic::Abc::PropertyHeader;
+using Alembic::Abc::V3fArraySamplePtr;
using Alembic::AbcGeom::ICamera;
using Alembic::AbcGeom::ICurves;
using Alembic::AbcGeom::IFaceSet;
@@ -79,9 +78,11 @@ using Alembic::AbcGeom::INuPatch;
using Alembic::AbcGeom::IObject;
using Alembic::AbcGeom::IPoints;
using Alembic::AbcGeom::IPolyMesh;
+using Alembic::AbcGeom::IPolyMeshSchema;
using Alembic::AbcGeom::ISampleSelector;
using Alembic::AbcGeom::ISubD;
using Alembic::AbcGeom::IXform;
+using Alembic::AbcGeom::kWrapExisting;
using Alembic::AbcGeom::MetaData;
using Alembic::AbcMaterial::IMaterial;
@@ -859,3 +860,136 @@ CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle,
return reinterpret_cast<CacheReader *>(abc_reader);
}
+
+/* ************************************************************************** */
+
+static const PropertyHeader *get_property_header(const IPolyMeshSchema &schema, const char *name)
+{
+ const PropertyHeader *prop_header = schema.getPropertyHeader(name);
+
+ if (prop_header) {
+ return prop_header;
+ }
+
+ ICompoundProperty prop = schema.getArbGeomParams();
+
+ if (!has_property(prop, name)) {
+ return nullptr;
+ }
+
+ return prop.getPropertyHeader(name);
+}
+
+bool ABC_has_vec3_array_property_named(struct CacheReader *reader, const char *name)
+{
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+
+ if (!abc_reader) {
+ return false;
+ }
+
+ IObject iobject = abc_reader->iobject();
+
+ if (!iobject.valid()) {
+ return false;
+ }
+
+ const ObjectHeader &header = iobject.getHeader();
+
+ if (!IPolyMesh::matches(header)) {
+ return false;
+ }
+
+ IPolyMesh mesh(iobject, kWrapExisting);
+ IPolyMeshSchema schema = mesh.getSchema();
+
+ const PropertyHeader *prop_header = get_property_header(schema, name);
+
+ if (!prop_header) {
+ return false;
+ }
+
+ return IV3fArrayProperty::matches(prop_header->getMetaData());
+}
+
+static V3fArraySamplePtr get_velocity_prop(const IPolyMeshSchema &schema,
+ const ISampleSelector &iss,
+ const std::string &name)
+{
+ const PropertyHeader *prop_header = schema.getPropertyHeader(name);
+
+ if (prop_header) {
+ const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(schema, name, 0);
+ return velocity_prop.getValue(iss);
+ }
+
+ ICompoundProperty prop = schema.getArbGeomParams();
+
+ if (!has_property(prop, name)) {
+ return V3fArraySamplePtr();
+ }
+
+ const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(prop, name, 0);
+
+ if (velocity_prop) {
+ return velocity_prop.getValue(iss);
+ }
+
+ return V3fArraySamplePtr();
+}
+
+int ABC_read_velocity_cache(CacheReader *reader,
+ const char *velocity_name,
+ const float time,
+ float velocity_scale,
+ int num_vertices,
+ float *r_vertex_velocities)
+{
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+
+ if (!abc_reader) {
+ return -1;
+ }
+
+ IObject iobject = abc_reader->iobject();
+
+ if (!iobject.valid()) {
+ return -1;
+ }
+
+ const ObjectHeader &header = iobject.getHeader();
+
+ if (!IPolyMesh::matches(header)) {
+ return -1;
+ }
+
+ IPolyMesh mesh(iobject, kWrapExisting);
+ IPolyMeshSchema schema = mesh.getSchema();
+ ISampleSelector sample_sel(time);
+ const IPolyMeshSchema::Sample sample = schema.getValue(sample_sel);
+
+ V3fArraySamplePtr velocities = get_velocity_prop(schema, sample_sel, velocity_name);
+
+ if (!velocities) {
+ return -1;
+ }
+
+ float vel[3];
+
+ int num_velocity_vectors = static_cast<int>(velocities->size());
+
+ if (num_velocity_vectors != num_vertices) {
+ return -1;
+ }
+
+ for (size_t i = 0; i < velocities->size(); ++i) {
+ const Imath::V3f &vel_in = (*velocities)[i];
+ copy_zup_from_yup(vel, vel_in.getValue());
+
+ mul_v3_fl(vel, velocity_scale);
+
+ copy_v3_v3(r_vertex_velocities + i * 3, vel);
+ }
+
+ return num_vertices;
+}
diff --git a/source/blender/io/avi/AVI_avi.h b/source/blender/io/avi/AVI_avi.h
index 4f3aa720da3..ba1ef9261a0 100644
--- a/source/blender/io/avi/AVI_avi.h
+++ b/source/blender/io/avi/AVI_avi.h
@@ -39,8 +39,7 @@
* code. So we keep it like this.
*/
-#ifndef __AVI_AVI_H__
-#define __AVI_AVI_H__
+#pragma once
#include "BLI_sys_types.h"
#include <stdio.h> /* for FILE */
@@ -295,5 +294,3 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...);
* Unused but still external
*/
AviError AVI_print_error(AviError error);
-
-#endif /* __AVI_AVI_H__ */
diff --git a/source/blender/io/avi/intern/avi_endian.h b/source/blender/io/avi/intern/avi_endian.h
index d1253f488e7..88c13d17950 100644
--- a/source/blender/io/avi/intern/avi_endian.h
+++ b/source/blender/io/avi/intern/avi_endian.h
@@ -23,8 +23,7 @@
* This is external code.
*/
-#ifndef __AVI_ENDIAN_H__
-#define __AVI_ENDIAN_H__
+#pragma once
#define AVI_RAW 0
#define AVI_CHUNK 1
@@ -36,5 +35,3 @@
#define AVI_MJPEGU 7
void awrite(AviMovie *movie, void *datain, int block, int size, FILE *fp, int type);
-
-#endif /* __AVI_ENDIAN_H__ */
diff --git a/source/blender/io/avi/intern/avi_intern.h b/source/blender/io/avi/intern/avi_intern.h
index 6ce91ce7f70..28ab999f6e3 100644
--- a/source/blender/io/avi/intern/avi_intern.h
+++ b/source/blender/io/avi/intern/avi_intern.h
@@ -21,8 +21,7 @@
* \ingroup avi
*/
-#ifndef __AVI_INTERN_H__
-#define __AVI_INTERN_H__
+#pragma once
#include <stdio.h> /* for FILE */
@@ -61,5 +60,3 @@ int avi_get_data_id(AviFormat format, int stream);
int avi_get_format_type(AviFormat format);
int avi_get_format_fcc(AviFormat format);
int avi_get_format_compression(AviFormat format);
-
-#endif
diff --git a/source/blender/io/avi/intern/avi_mjpeg.c b/source/blender/io/avi/intern/avi_mjpeg.c
index 70ddca28060..75059c202e5 100644
--- a/source/blender/io/avi/intern/avi_mjpeg.c
+++ b/source/blender/io/avi/intern/avi_mjpeg.c
@@ -20,7 +20,7 @@
/** \file
* \ingroup avi
*
- * This is external code. Converts between avi and mpeg/jpeg.
+ * This is external code. Converts between AVI and MPEG/JPEG.
*/
#include <stdlib.h>
@@ -39,7 +39,9 @@
#include "avi_mjpeg.h"
static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, size_t bufsize);
-static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, size_t bufsize);
+static void jpegmemsrcmgr_build(j_decompress_ptr dinfo,
+ const unsigned char *buffer,
+ size_t bufsize);
static size_t numbytes;
@@ -381,7 +383,10 @@ static void deinterlace(int odd, unsigned char *to, unsigned char *from, int wid
}
}
-void *avi_converter_from_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_from_mjpeg(AviMovie *movie,
+ int stream,
+ unsigned char *buffer,
+ const size_t *size)
{
int deint;
unsigned char *buf;
@@ -553,7 +558,9 @@ static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo)
MEM_freeN(dinfo->src);
}
-static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, size_t bufsize)
+static void jpegmemsrcmgr_build(j_decompress_ptr dinfo,
+ const unsigned char *buffer,
+ size_t bufsize)
{
dinfo->src = MEM_mallocN(sizeof(*(dinfo->src)), "avi.jpegmemsrcmgr_build");
diff --git a/source/blender/io/avi/intern/avi_mjpeg.h b/source/blender/io/avi/intern/avi_mjpeg.h
index 30e46bf1d0c..3ee1b611f70 100644
--- a/source/blender/io/avi/intern/avi_mjpeg.h
+++ b/source/blender/io/avi/intern/avi_mjpeg.h
@@ -21,10 +21,10 @@
* \ingroup avi
*/
-#ifndef __AVI_MJPEG_H__
-#define __AVI_MJPEG_H__
+#pragma once
-void *avi_converter_from_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size);
+void *avi_converter_from_mjpeg(AviMovie *movie,
+ int stream,
+ unsigned char *buffer,
+ const size_t *size);
void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size);
-
-#endif /* __AVI_MJPEG_H__ */
diff --git a/source/blender/io/avi/intern/avi_rgb.c b/source/blender/io/avi/intern/avi_rgb.c
index 6f4f33d72d1..44542af96ae 100644
--- a/source/blender/io/avi/intern/avi_rgb.c
+++ b/source/blender/io/avi/intern/avi_rgb.c
@@ -37,7 +37,10 @@
/* implementation */
-void *avi_converter_from_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
+void *avi_converter_from_avi_rgb(AviMovie *movie,
+ int stream,
+ unsigned char *buffer,
+ const size_t *size)
{
unsigned char *buf;
AviBitmapInfoHeader *bi;
diff --git a/source/blender/io/avi/intern/avi_rgb.h b/source/blender/io/avi/intern/avi_rgb.h
index 7c8ce590d27..aac8a2dffbf 100644
--- a/source/blender/io/avi/intern/avi_rgb.h
+++ b/source/blender/io/avi/intern/avi_rgb.h
@@ -21,10 +21,10 @@
* \ingroup avi
*/
-#ifndef __AVI_RGB_H__
-#define __AVI_RGB_H__
+#pragma once
-void *avi_converter_from_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, size_t *size);
+void *avi_converter_from_avi_rgb(AviMovie *movie,
+ int stream,
+ unsigned char *buffer,
+ const size_t *size);
void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, size_t *size);
-
-#endif /* __AVI_RGB_H__ */
diff --git a/source/blender/io/avi/intern/avi_rgb32.h b/source/blender/io/avi/intern/avi_rgb32.h
index eb4b9ca4e21..675b1ced41e 100644
--- a/source/blender/io/avi/intern/avi_rgb32.h
+++ b/source/blender/io/avi/intern/avi_rgb32.h
@@ -21,10 +21,7 @@
* \ingroup avi
*/
-#ifndef __AVI_RGB32_H__
-#define __AVI_RGB32_H__
+#pragma once
void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffer, size_t *size);
void *avi_converter_to_rgb32(AviMovie *movie, int stream, unsigned char *buffer, size_t *size);
-
-#endif /* __AVI_RGB32_H__ */
diff --git a/source/blender/io/collada/AnimationClipExporter.h b/source/blender/io/collada/AnimationClipExporter.h
index 9d782eac094..a19fcb4d372 100644
--- a/source/blender/io/collada/AnimationClipExporter.h
+++ b/source/blender/io/collada/AnimationClipExporter.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __ANIMATIONCLIPEXPORTER_H__
-#define __ANIMATIONCLIPEXPORTER_H__
+#pragma once
#include <math.h>
#include <stdio.h>
@@ -49,5 +48,3 @@ class AnimationClipExporter : COLLADASW::LibraryAnimationClips {
void exportAnimationClips(Scene *sce);
};
-
-#endif /* __ANIMATIONCLIPEXPORTER_H__ */
diff --git a/source/blender/io/collada/AnimationExporter.cpp b/source/blender/io/collada/AnimationExporter.cpp
index c25b4ea543b..1515e5413f0 100644
--- a/source/blender/io/collada/AnimationExporter.cpp
+++ b/source/blender/io/collada/AnimationExporter.cpp
@@ -230,7 +230,7 @@ void AnimationExporter::export_matrix_animation(Object *ob, BCAnimationSampler &
std::string name = encode_xml(id_name(ob));
std::string action_name = (action == NULL) ? name + "-action" : id_name(action);
std::string channel_type = "transform";
- std::string axis = "";
+ std::string axis;
std::string id = bc_get_action_id(action_name, name, channel_type, axis);
std::string target = translate_id(name) + '/' + channel_type;
diff --git a/source/blender/io/collada/AnimationExporter.h b/source/blender/io/collada/AnimationExporter.h
index b4564eb7b2d..48279b0c867 100644
--- a/source/blender/io/collada/AnimationExporter.h
+++ b/source/blender/io/collada/AnimationExporter.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __ANIMATIONEXPORTER_H__
-#define __ANIMATIONEXPORTER_H__
+#pragma once
#include <math.h>
#include <stdio.h>
@@ -258,5 +257,3 @@ class AnimationExporter : COLLADASW::LibraryAnimations {
void export_morph_animation(Object *ob, BCAnimationSampler &sampler);
#endif
};
-
-#endif /* __ANIMATIONEXPORTER_H__ */
diff --git a/source/blender/io/collada/AnimationImporter.cpp b/source/blender/io/collada/AnimationImporter.cpp
index 0e211f08d1f..b53aa95a11f 100644
--- a/source/blender/io/collada/AnimationImporter.cpp
+++ b/source/blender/io/collada/AnimationImporter.cpp
@@ -306,7 +306,7 @@ bool AnimationImporter::write_animation(const COLLADAFW::Animation *anim)
animation_to_fcurves(curve);
break;
default:
- /* TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types */
+ /* TODO there are also CARDINAL, HERMITE, BSPLINE and STEP types. */
fprintf(stderr,
"CARDINAL, HERMITE and BSPLINE anim interpolation types not supported yet.\n");
break;
@@ -967,8 +967,6 @@ void AnimationImporter::apply_matrix_curves(Object *ob,
else {
ob->rotmode = ROT_MODE_QUAT;
}
-
- return;
}
/*
diff --git a/source/blender/io/collada/AnimationImporter.h b/source/blender/io/collada/AnimationImporter.h
index 51041c6ee3e..5c6f9400286 100644
--- a/source/blender/io/collada/AnimationImporter.h
+++ b/source/blender/io/collada/AnimationImporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __ANIMATIONIMPORTER_H__
-#define __ANIMATIONIMPORTER_H__
+#pragma once
#include <map>
#include <vector>
@@ -250,5 +249,3 @@ class AnimationImporter : private TransformReader, public AnimationImporterBase
void extra_data_importer(std::string elementName);
};
-
-#endif
diff --git a/source/blender/io/collada/ArmatureExporter.h b/source/blender/io/collada/ArmatureExporter.h
index 3bc9dfe2639..193dc9cde3a 100644
--- a/source/blender/io/collada/ArmatureExporter.h
+++ b/source/blender/io/collada/ArmatureExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __ARMATUREEXPORTER_H__
-#define __ARMATUREEXPORTER_H__
+#pragma once
#include <list>
#include <string>
@@ -103,5 +102,3 @@ class ArmatureExporter : public COLLADASW::LibraryControllers,
void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone);
};
-
-#endif
diff --git a/source/blender/io/collada/ArmatureImporter.cpp b/source/blender/io/collada/ArmatureImporter.cpp
index 3755b71f300..bd5bd913a18 100644
--- a/source/blender/io/collada/ArmatureImporter.cpp
+++ b/source/blender/io/collada/ArmatureImporter.cpp
@@ -969,8 +969,8 @@ void ArmatureImporter::make_shape_keys(bContext *C)
/* insert other shape keys */
for (int i = 0; i < morphTargetIds.getCount(); i++) {
- /* better to have a separate map of morph objects,
- * This'll do for now since only mesh morphing is imported */
+ /* Better to have a separate map of morph objects,
+ * This will do for now since only mesh morphing is imported. */
Mesh *me = this->mesh_importer->get_mesh_by_geom_uid(morphTargetIds[i]);
diff --git a/source/blender/io/collada/ArmatureImporter.h b/source/blender/io/collada/ArmatureImporter.h
index 7393b882f4b..a1c4a25b80f 100644
--- a/source/blender/io/collada/ArmatureImporter.h
+++ b/source/blender/io/collada/ArmatureImporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __ARMATUREIMPORTER_H__
-#define __ARMATUREIMPORTER_H__
+#pragma once
#include "COLLADAFWMorphController.h"
#include "COLLADAFWNode.h"
@@ -181,5 +180,3 @@ class ArmatureImporter : private TransformReader {
void set_tags_map(TagsMap &tags_map);
};
-
-#endif
diff --git a/source/blender/io/collada/BCAnimationCurve.h b/source/blender/io/collada/BCAnimationCurve.h
index e0216ee6849..779678bca1d 100644
--- a/source/blender/io/collada/BCAnimationCurve.h
+++ b/source/blender/io/collada/BCAnimationCurve.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BCANIMATIONCURVE_H__
-#define __BCANIMATIONCURVE_H__
+#pragma once
#include "BCSampleData.h"
#include "collada_utils.h"
@@ -147,5 +146,3 @@ class BCAnimationCurve {
};
typedef std::map<BCCurveKey, BCAnimationCurve *> BCAnimationCurveMap;
-
-#endif /* __BCANIMATIONCURVE_H__ */
diff --git a/source/blender/io/collada/BCAnimationSampler.h b/source/blender/io/collada/BCAnimationSampler.h
index 3273ac8e0a0..5ab4be3722c 100644
--- a/source/blender/io/collada/BCAnimationSampler.h
+++ b/source/blender/io/collada/BCAnimationSampler.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BCANIMATIONSAMPLER_H__
-#define __BCANIMATIONSAMPLER_H__
+#pragma once
#include "BCAnimationCurve.h"
#include "BCSampleData.h"
@@ -190,5 +189,3 @@ class BCAnimationSampler {
ListBase *conlist,
std::set<Object *> &animated_objects);
};
-
-#endif /* __BCANIMATIONSAMPLER_H__ */
diff --git a/source/blender/io/collada/BCMath.cpp b/source/blender/io/collada/BCMath.cpp
index e8765fa2bcd..a03e2ad6488 100644
--- a/source/blender/io/collada/BCMath.cpp
+++ b/source/blender/io/collada/BCMath.cpp
@@ -72,27 +72,30 @@ BCMatrix::BCMatrix(BC_global_forward_axis global_forward_axis, BC_global_up_axis
set_transform(mat);
}
-void BCMatrix::add_transform(const Matrix &mat, bool inverse)
+void BCMatrix::add_transform(const Matrix &mat, bool inverted)
{
- add_transform(this->matrix, mat, this->matrix, inverse);
+ add_transform(this->matrix, mat, this->matrix, inverted);
}
-void BCMatrix::add_transform(const BCMatrix &mat, bool inverse)
+void BCMatrix::add_transform(const BCMatrix &mat, bool inverted)
{
- add_transform(this->matrix, mat.matrix, this->matrix, inverse);
+ add_transform(this->matrix, mat.matrix, this->matrix, inverted);
}
-void BCMatrix::apply_transform(const BCMatrix &mat, bool inverse)
+void BCMatrix::apply_transform(const BCMatrix &mat, bool inverted)
{
- apply_transform(this->matrix, mat.matrix, this->matrix, inverse);
+ apply_transform(this->matrix, mat.matrix, this->matrix, inverted);
}
-void BCMatrix::add_transform(Matrix &to, const Matrix &transform, const Matrix &from, bool inverse)
+void BCMatrix::add_transform(Matrix &to,
+ const Matrix &transform,
+ const Matrix &from,
+ bool inverted)
{
- if (inverse) {
+ if (inverted) {
Matrix globinv;
invert_m4_m4(globinv, transform);
- add_transform(to, globinv, from, /*inverse=*/false);
+ add_transform(to, globinv, from, /*inverted=*/false);
}
else {
mul_m4_m4m4(to, transform, from);
@@ -107,7 +110,7 @@ void BCMatrix::apply_transform(Matrix &to,
Matrix globinv;
invert_m4_m4(globinv, transform);
if (inverse) {
- add_transform(to, globinv, from, /*inverse=*/false);
+ add_transform(to, globinv, from, /*inverted=*/false);
}
else {
mul_m4_m4m4(to, transform, from);
diff --git a/source/blender/io/collada/BCMath.h b/source/blender/io/collada/BCMath.h
index 38158751740..79a0ea941cd 100644
--- a/source/blender/io/collada/BCMath.h
+++ b/source/blender/io/collada/BCMath.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __BCMATH_H__
-#define __BCMATH_H__
+#pragma once
#include "BlenderTypes.h"
@@ -105,5 +104,3 @@ class BCMatrix {
static void sanitize(DMatrix &matrix, int precision);
static void transpose(Matrix &matrix);
};
-
-#endif /* __BCMATH_H__ */
diff --git a/source/blender/io/collada/BCSampleData.h b/source/blender/io/collada/BCSampleData.h
index 6f3ca9135b3..39e34355b72 100644
--- a/source/blender/io/collada/BCSampleData.h
+++ b/source/blender/io/collada/BCSampleData.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __BCSAMPLEDATA_H__
-#define __BCSAMPLEDATA_H__
+#pragma once
#include <algorithm>
#include <map>
@@ -62,5 +61,3 @@ class BCSample {
typedef std::map<Object *, BCSample *> BCSampleMap;
typedef std::map<int, const BCSample *> BCFrameSampleMap;
typedef std::map<int, const BCMatrix *> BCMatrixSampleMap;
-
-#endif /* __BCSAMPLEDATA_H__ */
diff --git a/source/blender/io/collada/BlenderContext.h b/source/blender/io/collada/BlenderContext.h
index bf6fde134fa..9163b30c86f 100644
--- a/source/blender/io/collada/BlenderContext.h
+++ b/source/blender/io/collada/BlenderContext.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __BLENDERCONTEXT_H__
-#define __BLENDERCONTEXT_H__
+#pragma once
#include "BKE_context.h"
#include "BKE_main.h"
@@ -68,5 +67,3 @@ class BlenderContext {
Main *get_main();
};
#endif
-
-#endif
diff --git a/source/blender/io/collada/BlenderTypes.h b/source/blender/io/collada/BlenderTypes.h
index 0e024be2374..63b0471ef6f 100644
--- a/source/blender/io/collada/BlenderTypes.h
+++ b/source/blender/io/collada/BlenderTypes.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __BLENDERTYPES_H__
-#define __BLENDERTYPES_H__
+#pragma once
typedef float(Vector)[3];
typedef float(Quat)[4];
@@ -44,5 +43,3 @@ typedef enum BC_global_up_axis {
BC_GLOBAL_UP_MINUS_Y = 4,
BC_GLOBAL_UP_MINUS_Z = 5
} BC_global_up_axis;
-
-#endif
diff --git a/source/blender/io/collada/CameraExporter.h b/source/blender/io/collada/CameraExporter.h
index 0dda6392d03..cc4f7aee165 100644
--- a/source/blender/io/collada/CameraExporter.h
+++ b/source/blender/io/collada/CameraExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __CAMERAEXPORTER_H__
-#define __CAMERAEXPORTER_H__
+#pragma once
#include "COLLADASWLibraryCameras.h"
#include "COLLADASWStreamWriter.h"
@@ -40,5 +39,3 @@ class CamerasExporter : COLLADASW::LibraryCameras {
bool exportBlenderProfile(COLLADASW::Camera &cla, Camera *cam);
BCExportSettings &export_settings;
};
-
-#endif
diff --git a/source/blender/io/collada/ControllerExporter.h b/source/blender/io/collada/ControllerExporter.h
index fb84af6ebc9..753538d8e98 100644
--- a/source/blender/io/collada/ControllerExporter.h
+++ b/source/blender/io/collada/ControllerExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __CONTROLLEREXPORTER_H__
-#define __CONTROLLEREXPORTER_H__
+#pragma once
#include <list>
#include <string>
@@ -133,5 +132,3 @@ class ControllerExporter : public COLLADASW::LibraryControllers,
void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone);
};
-
-#endif
diff --git a/source/blender/io/collada/DocumentExporter.h b/source/blender/io/collada/DocumentExporter.h
index 1fe52420534..850eb4fbbb2 100644
--- a/source/blender/io/collada/DocumentExporter.h
+++ b/source/blender/io/collada/DocumentExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __DOCUMENTEXPORTER_H__
-#define __DOCUMENTEXPORTER_H__
+#pragma once
#include "BlenderContext.h"
#include "collada.h"
@@ -38,5 +37,3 @@ class DocumentExporter {
BCExportSettings export_settings;
KeyImageMap key_image_map;
};
-
-#endif
diff --git a/source/blender/io/collada/DocumentImporter.h b/source/blender/io/collada/DocumentImporter.h
index d9be4880b35..e382a44c3c2 100644
--- a/source/blender/io/collada/DocumentImporter.h
+++ b/source/blender/io/collada/DocumentImporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __DOCUMENTIMPORTER_H__
-#define __DOCUMENTIMPORTER_H__
+#pragma once
#include "COLLADAFWColor.h"
#include "COLLADAFWController.h"
@@ -168,5 +167,3 @@ class DocumentImporter : COLLADAFW::IWriter {
void report_unknown_reference(const COLLADAFW::Node &node, const std::string object_type);
};
-
-#endif
diff --git a/source/blender/io/collada/EffectExporter.h b/source/blender/io/collada/EffectExporter.h
index 36d02bb1c8f..c844d93b040 100644
--- a/source/blender/io/collada/EffectExporter.h
+++ b/source/blender/io/collada/EffectExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __EFFECTEXPORTER_H__
-#define __EFFECTEXPORTER_H__
+#pragma once
#include <string>
#include <vector>
@@ -85,5 +84,3 @@ class EffectsExporter : COLLADASW::LibraryEffects {
Scene *scene;
bContext *mContext;
};
-
-#endif
diff --git a/source/blender/io/collada/ErrorHandler.h b/source/blender/io/collada/ErrorHandler.h
index 0c082a3b9dd..60253a08cda 100644
--- a/source/blender/io/collada/ErrorHandler.h
+++ b/source/blender/io/collada/ErrorHandler.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __ERRORHANDLER_H__
-#define __ERRORHANDLER_H__
+#pragma once
#include <algorithm> // sort()
#include <map>
@@ -53,5 +52,3 @@ class ErrorHandler : public COLLADASaxFWL::IErrorHandler {
/** Hold error status. */
bool mError;
};
-
-#endif /* __ERRORHANDLER_H__ */
diff --git a/source/blender/io/collada/ExportSettings.h b/source/blender/io/collada/ExportSettings.h
index 477f0b8b678..2f647cefa8b 100644
--- a/source/blender/io/collada/ExportSettings.h
+++ b/source/blender/io/collada/ExportSettings.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __EXPORTSETTINGS_H__
-#define __EXPORTSETTINGS_H__
+#pragma once
#include "BLI_linklist.h"
#include "BlenderContext.h"
@@ -291,5 +290,3 @@ class BCExportSettings {
};
#endif
-
-#endif
diff --git a/source/blender/io/collada/ExtraHandler.h b/source/blender/io/collada/ExtraHandler.h
index 04ac963b530..8f98e1dec1b 100644
--- a/source/blender/io/collada/ExtraHandler.h
+++ b/source/blender/io/collada/ExtraHandler.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __EXTRAHANDLER_H__
-#define __EXTRAHANDLER_H__
+#pragma once
#include <algorithm> // sort()
#include <map>
@@ -79,5 +78,3 @@ class ExtraHandler : public COLLADASaxFWL::IExtraDataCallbackHandler {
ExtraTags *currentExtraTags;
std::string currentElement;
};
-
-#endif /* __EXTRAHANDLER_H__ */
diff --git a/source/blender/io/collada/ExtraTags.h b/source/blender/io/collada/ExtraTags.h
index c806b8fa904..a72cdeb32a8 100644
--- a/source/blender/io/collada/ExtraTags.h
+++ b/source/blender/io/collada/ExtraTags.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __EXTRATAGS_H__
-#define __EXTRATAGS_H__
+#pragma once
#include <map>
#include <string>
@@ -73,5 +72,3 @@ class ExtraTags {
/** Get text data for tag as a string. */
std::string asString(std::string tag, bool *ok);
};
-
-#endif /* __EXTRATAGS_H__ */
diff --git a/source/blender/io/collada/GeometryExporter.h b/source/blender/io/collada/GeometryExporter.h
index 5090158177f..d91f3d1ec5a 100644
--- a/source/blender/io/collada/GeometryExporter.h
+++ b/source/blender/io/collada/GeometryExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __GEOMETRYEXPORTER_H__
-#define __GEOMETRYEXPORTER_H__
+#pragma once
#include <set>
#include <string>
@@ -136,5 +135,3 @@ struct GeometryFunctor {
}
}
};
-
-#endif
diff --git a/source/blender/io/collada/ImageExporter.h b/source/blender/io/collada/ImageExporter.h
index 20f9b95a512..e1fdcc12272 100644
--- a/source/blender/io/collada/ImageExporter.h
+++ b/source/blender/io/collada/ImageExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __IMAGEEXPORTER_H__
-#define __IMAGEEXPORTER_H__
+#pragma once
#include <string>
#include <vector>
@@ -47,5 +46,3 @@ class ImagesExporter : COLLADASW::LibraryImages {
KeyImageMap &key_image_map;
void export_UV_Image(Image *image, bool use_texture_copies);
};
-
-#endif
diff --git a/source/blender/io/collada/ImportSettings.h b/source/blender/io/collada/ImportSettings.h
index 608d8bff882..e8a5bf8ce81 100644
--- a/source/blender/io/collada/ImportSettings.h
+++ b/source/blender/io/collada/ImportSettings.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __IMPORTSETTINGS_H__
-#define __IMPORTSETTINGS_H__
+#pragma once
typedef struct ImportSettings {
bool import_units;
@@ -30,5 +29,3 @@ typedef struct ImportSettings {
char *filepath;
bool keep_bind_info;
} ImportSettings;
-
-#endif
diff --git a/source/blender/io/collada/InstanceWriter.h b/source/blender/io/collada/InstanceWriter.h
index cfec1cf7006..c79d6691842 100644
--- a/source/blender/io/collada/InstanceWriter.h
+++ b/source/blender/io/collada/InstanceWriter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __INSTANCEWRITER_H__
-#define __INSTANCEWRITER_H__
+#pragma once
#include "COLLADASWBindMaterial.h"
@@ -31,5 +30,3 @@ class InstanceWriter {
Object *ob,
bool active_uv_only);
};
-
-#endif
diff --git a/source/blender/io/collada/LightExporter.h b/source/blender/io/collada/LightExporter.h
index a5c7f5c6dee..90256691c06 100644
--- a/source/blender/io/collada/LightExporter.h
+++ b/source/blender/io/collada/LightExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __LIGHTEXPORTER_H__
-#define __LIGHTEXPORTER_H__
+#pragma once
#include "COLLADASWLibraryLights.h"
#include "COLLADASWStreamWriter.h"
@@ -40,5 +39,3 @@ class LightsExporter : COLLADASW::LibraryLights {
bool exportBlenderProfile(COLLADASW::Light &cla, Light *la);
BCExportSettings &export_settings;
};
-
-#endif
diff --git a/source/blender/io/collada/MaterialExporter.h b/source/blender/io/collada/MaterialExporter.h
index babb113567f..7d40347097c 100644
--- a/source/blender/io/collada/MaterialExporter.h
+++ b/source/blender/io/collada/MaterialExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __MATERIALEXPORTER_H__
-#define __MATERIALEXPORTER_H__
+#pragma once
#include <string>
#include <vector>
@@ -93,5 +92,3 @@ struct MaterialFunctor {
gf.forEachMeshObjectInExportSet<ForEachMaterialFunctor<Functor>>(sce, matfunc, export_set);
}
};
-
-#endif
diff --git a/source/blender/io/collada/Materials.h b/source/blender/io/collada/Materials.h
index e1d12246a2b..f671a00758d 100644
--- a/source/blender/io/collada/Materials.h
+++ b/source/blender/io/collada/Materials.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MATERIALS_H__
-#define __MATERIALS_H__
+#pragma once
#include <map>
#include <string>
@@ -70,5 +69,3 @@ class MaterialNode {
COLLADAFW::ColorOrTexture &cot,
COLLADAFW::FloatOrParam &val);
};
-
-#endif /* __MATERIALS_H__ */
diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp
index 495af60488b..9fbb7324f8f 100644
--- a/source/blender/io/collada/MeshImporter.cpp
+++ b/source/blender/io/collada/MeshImporter.cpp
@@ -205,7 +205,7 @@ MeshImporter::MeshImporter(
}
bool MeshImporter::set_poly_indices(
- MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count)
+ MPoly *mpoly, MLoop *mloop, int loop_index, const unsigned int *indices, int loop_count)
{
mpoly->loopstart = loop_index;
mpoly->totloop = loop_count;
diff --git a/source/blender/io/collada/MeshImporter.h b/source/blender/io/collada/MeshImporter.h
index 2f2a18ff11a..a63cb0da987 100644
--- a/source/blender/io/collada/MeshImporter.h
+++ b/source/blender/io/collada/MeshImporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __MESHIMPORTER_H__
-#define __MESHIMPORTER_H__
+#pragma once
#include <map>
#include <vector>
@@ -105,7 +104,7 @@ class MeshImporter : public MeshImporterBase {
std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId> materials_mapped_to_geom;
bool set_poly_indices(
- MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count);
+ MPoly *mpoly, MLoop *mloop, int loop_index, const unsigned int *indices, int loop_count);
void set_face_uv(MLoopUV *mloopuv,
UVDataWrapper &uvs,
@@ -177,5 +176,3 @@ class MeshImporter : public MeshImporterBase {
bool write_geometry(const COLLADAFW::Geometry *geom);
std::string *get_geometry_name(const std::string &mesh_name);
};
-
-#endif
diff --git a/source/blender/io/collada/SceneExporter.h b/source/blender/io/collada/SceneExporter.h
index 3ea6a9fac8e..5b8ec37152f 100644
--- a/source/blender/io/collada/SceneExporter.h
+++ b/source/blender/io/collada/SceneExporter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __SCENEEXPORTER_H__
-#define __SCENEEXPORTER_H__
+#pragma once
#include <math.h>
#include <stdio.h>
@@ -110,5 +109,3 @@ class SceneExporter : COLLADASW::LibraryVisualScenes,
void writeNodeList(std::vector<Object *> &child_objects, Object *parent);
void writeNode(Object *ob);
};
-
-#endif
diff --git a/source/blender/io/collada/SkinInfo.h b/source/blender/io/collada/SkinInfo.h
index e8b13f86e9c..3b94e403b6d 100644
--- a/source/blender/io/collada/SkinInfo.h
+++ b/source/blender/io/collada/SkinInfo.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __SKININFO_H__
-#define __SKININFO_H__
+#pragma once
#include <map>
#include <vector>
@@ -126,5 +125,3 @@ class SkinInfo {
bool find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root);
};
-
-#endif
diff --git a/source/blender/io/collada/TransformReader.h b/source/blender/io/collada/TransformReader.h
index 5a778e6aba5..f8a73ce3912 100644
--- a/source/blender/io/collada/TransformReader.h
+++ b/source/blender/io/collada/TransformReader.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __TRANSFORMREADER_H__
-#define __TRANSFORMREADER_H__
+#pragma once
#include "COLLADAFWMatrix.h"
#include "COLLADAFWNode.h"
@@ -68,5 +67,3 @@ class TransformReader {
void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]);
void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]);
};
-
-#endif
diff --git a/source/blender/io/collada/TransformWriter.cpp b/source/blender/io/collada/TransformWriter.cpp
index 0a66db72cb9..b7455837379 100644
--- a/source/blender/io/collada/TransformWriter.cpp
+++ b/source/blender/io/collada/TransformWriter.cpp
@@ -129,9 +129,9 @@ void TransformWriter::add_node_transform_identity(COLLADASW::Node &node,
}
void TransformWriter::add_transform(COLLADASW::Node &node,
- float loc[3],
- float rot[3],
- float scale[3])
+ const float loc[3],
+ const float rot[3],
+ const float scale[3])
{
node.addScale("scale", scale[0], scale[1], scale[2]);
node.addRotateZ("rotationZ", RAD2DEGF(rot[2]));
diff --git a/source/blender/io/collada/TransformWriter.h b/source/blender/io/collada/TransformWriter.h
index 3c71fc9d36e..200f641b064 100644
--- a/source/blender/io/collada/TransformWriter.h
+++ b/source/blender/io/collada/TransformWriter.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __TRANSFORMWRITER_H__
-#define __TRANSFORMWRITER_H__
+#pragma once
#include "COLLADASWNode.h"
@@ -42,7 +41,8 @@ class TransformWriter {
void add_node_transform_identity(COLLADASW::Node &node, BCExportSettings &export_settings);
private:
- void add_transform(COLLADASW::Node &node, float loc[3], float rot[3], float scale[3]);
+ void add_transform(COLLADASW::Node &node,
+ const float loc[3],
+ const float rot[3],
+ const float scale[3]);
};
-
-#endif
diff --git a/source/blender/io/collada/collada.h b/source/blender/io/collada/collada.h
index d8e498ef4b2..2668be6153b 100644
--- a/source/blender/io/collada/collada.h
+++ b/source/blender/io/collada/collada.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __COLLADA_H__
-#define __COLLADA_H__
+#pragma once
#include <stdlib.h>
@@ -46,5 +45,3 @@ int collada_export(struct bContext *C, ExportSettings *export_settings);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/io/collada/collada_internal.cpp b/source/blender/io/collada/collada_internal.cpp
index f123e8ea31f..b3fa9ba1251 100644
--- a/source/blender/io/collada/collada_internal.cpp
+++ b/source/blender/io/collada/collada_internal.cpp
@@ -277,7 +277,7 @@ std::string encode_xml(std::string xml)
{'<', "&lt;"}, {'>', "&gt;"}, {'"', "&quot;"}, {'\'', "&apos;"}, {'&', "&amp;"}};
std::map<char, std::string>::const_iterator it;
- std::string encoded_xml = "";
+ std::string encoded_xml;
for (unsigned int i = 0; i < xml.size(); i++) {
char c = xml.at(i);
diff --git a/source/blender/io/collada/collada_internal.h b/source/blender/io/collada/collada_internal.h
index d9fe0ba0b58..de4e1d7e0d4 100644
--- a/source/blender/io/collada/collada_internal.h
+++ b/source/blender/io/collada/collada_internal.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __COLLADA_INTERNAL_H__
-#define __COLLADA_INTERNAL_H__
+#pragma once
#include <map>
#include <string>
@@ -94,5 +93,3 @@ extern std::string get_morph_id(Object *ob);
extern std::string get_effect_id(Material *mat);
extern std::string get_material_id(Material *mat);
-
-#endif /* __COLLADA_INTERNAL_H__ */
diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp
index d2e05c7ae5b..df35a1d2780 100644
--- a/source/blender/io/collada/collada_utils.cpp
+++ b/source/blender/io/collada/collada_utils.cpp
@@ -528,9 +528,7 @@ BoneExtensionManager::~BoneExtensionManager()
for (BoneExtensionMap::iterator ext_it = extended_bones->begin();
ext_it != extended_bones->end();
++ext_it) {
- if (ext_it->second != NULL) {
- delete ext_it->second;
- }
+ delete ext_it->second;
}
extended_bones->clear();
delete extended_bones;
@@ -605,7 +603,7 @@ float BoneExtended::get_roll()
return this->roll;
}
-void BoneExtended::set_tail(float vec[])
+void BoneExtended::set_tail(const float vec[])
{
this->tail[0] = vec[0];
this->tail[1] = vec[1];
@@ -674,8 +672,7 @@ void BoneExtended::set_bone_layers(std::string layerString, std::vector<std::str
std::string BoneExtended::get_bone_layers(int bitfield)
{
- std::string result = "";
- std::string sep = "";
+ std::string sep;
int bit = 1u;
std::ostringstream ss;
diff --git a/source/blender/io/collada/collada_utils.h b/source/blender/io/collada/collada_utils.h
index b1ec2c8b81a..657a82f70d2 100644
--- a/source/blender/io/collada/collada_utils.h
+++ b/source/blender/io/collada/collada_utils.h
@@ -18,8 +18,7 @@
* \ingroup collada
*/
-#ifndef __COLLADA_UTILS_H__
-#define __COLLADA_UTILS_H__
+#pragma once
#include "COLLADAFWColorOrTexture.h"
#include "COLLADAFWFloatOrDoubleArray.h"
@@ -343,7 +342,7 @@ class BoneExtended {
bool has_roll();
float get_roll();
- void set_tail(float vec[]);
+ void set_tail(const float vec[]);
float *get_tail();
bool has_tail();
@@ -393,5 +392,3 @@ COLLADASW::ColorOrTexture bc_get_cot_from_shader(bNode *shader,
COLLADASW::ColorOrTexture bc_get_cot(float r, float g, float b, float a);
COLLADASW::ColorOrTexture bc_get_cot(Color col, bool with_alpha = true);
-
-#endif
diff --git a/source/blender/io/common/CMakeLists.txt b/source/blender/io/common/CMakeLists.txt
index 4ed6f12762e..d3341767f8b 100644
--- a/source/blender/io/common/CMakeLists.txt
+++ b/source/blender/io/common/CMakeLists.txt
@@ -31,8 +31,13 @@ set(INC_SYS
set(SRC
intern/abstract_hierarchy_iterator.cc
+ intern/dupli_parent_finder.cc
+ intern/dupli_persistent_id.cc
+ intern/object_identifier.cc
IO_abstract_hierarchy_iterator.h
+ IO_dupli_persistent_id.hh
+ intern/dupli_parent_finder.hh
)
set(LIB
@@ -43,3 +48,17 @@ set(LIB
blender_add_lib(bf_io_common "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
target_link_libraries(bf_io_common INTERFACE)
+
+if(WITH_GTESTS)
+ set(TEST_SRC
+ intern/abstract_hierarchy_iterator_test.cc
+ intern/hierarchy_context_order_test.cc
+ intern/object_identifier_test.cc
+ )
+ set(TEST_LIB
+ bf_blenloader_test
+ bf_io_common
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_io_common_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
+endif()
diff --git a/source/blender/io/common/IO_abstract_hierarchy_iterator.h b/source/blender/io/common/IO_abstract_hierarchy_iterator.h
index 5f84fd48b71..d0d9d72b880 100644
--- a/source/blender/io/common/IO_abstract_hierarchy_iterator.h
+++ b/source/blender/io/common/IO_abstract_hierarchy_iterator.h
@@ -33,8 +33,9 @@
* Selections like "selected only" or "no hair systems" are left to concrete subclasses.
*/
-#ifndef __ABSTRACT_HIERARCHY_ITERATOR_H__
-#define __ABSTRACT_HIERARCHY_ITERATOR_H__
+#pragma once
+
+#include "IO_dupli_persistent_id.hh"
#include <map>
#include <set>
@@ -52,6 +53,7 @@ namespace blender {
namespace io {
class AbstractHierarchyWriter;
+class DupliParentFinder;
/* HierarchyContext structs are created by the AbstractHierarchyIterator. Each HierarchyContext
* struct contains everything necessary to export a single object to a file. */
@@ -60,6 +62,7 @@ struct HierarchyContext {
Object *object; /* Evaluated object. */
Object *export_parent;
Object *duplicator;
+ PersistentID persistent_id;
float matrix_world[4][4];
std::string export_name;
@@ -125,7 +128,14 @@ class AbstractHierarchyWriter {
// but wasn't used while exporting the current frame (for example, a particle-instanced mesh of
// which the particle is no longer alive).
protected:
+ /* Return true if the data written by this writer changes over time.
+ * Note that this function assumes this is an object data writer. Transform writers should not
+ * call this but implement their own logic. */
virtual bool check_is_animated(const HierarchyContext &context) const;
+
+ /* Helper functions for animation checks. */
+ static bool check_has_physics(const HierarchyContext &context);
+ static bool check_has_deforming_physics(const HierarchyContext &context);
};
/* Determines which subset of the writers actually gets to write. */
@@ -161,6 +171,35 @@ class EnsuredWriter {
AbstractHierarchyWriter *operator->();
};
+/* Unique identifier for a (potentially duplicated) object.
+ *
+ * Instances of this class serve as key in the export graph of the
+ * AbstractHierarchyIterator. */
+class ObjectIdentifier {
+ public:
+ Object *object;
+ Object *duplicated_by; /* nullptr for real objects. */
+ PersistentID persistent_id;
+
+ protected:
+ ObjectIdentifier(Object *object, Object *duplicated_by, const PersistentID &persistent_id);
+
+ public:
+ ObjectIdentifier(const ObjectIdentifier &other);
+ ~ObjectIdentifier();
+
+ static ObjectIdentifier for_graph_root();
+ static ObjectIdentifier for_real_object(Object *object);
+ static ObjectIdentifier for_hierarchy_context(const HierarchyContext *context);
+ static ObjectIdentifier for_duplicated_object(const DupliObject *dupli_object,
+ Object *duplicated_by);
+
+ bool is_root() const;
+};
+
+bool operator<(const ObjectIdentifier &obj_ident_a, const ObjectIdentifier &obj_ident_b);
+bool operator==(const ObjectIdentifier &obj_ident_a, const ObjectIdentifier &obj_ident_b);
+
/* AbstractHierarchyIterator iterates over objects in a dependency graph, and constructs export
* writers. These writers are then called to perform the actual writing to a USD or Alembic file.
*
@@ -172,14 +211,10 @@ class AbstractHierarchyIterator {
public:
/* Mapping from export path to writer. */
typedef std::map<std::string, AbstractHierarchyWriter *> WriterMap;
- /* Pair of a (potentially duplicated) object and its duplicator (or nullptr).
- * This is typically used to store a pair of HierarchyContext::object and
- * HierarchyContext::duplicator. */
- typedef std::pair<Object *, Object *> DupliAndDuplicator;
/* All the children of some object, as per the export hierarchy. */
typedef std::set<HierarchyContext *> ExportChildren;
/* Mapping from an object and its duplicator to the object's export-children. */
- typedef std::map<DupliAndDuplicator, ExportChildren> ExportGraph;
+ typedef std::map<ObjectIdentifier, ExportChildren> ExportGraph;
/* Mapping from ID to its export path. This is used for instancing; given an
* instanced datablock, the export path of the original can be looked up. */
typedef std::map<ID *, std::string> ExportPathMap;
@@ -237,7 +272,7 @@ class AbstractHierarchyIterator {
void visit_object(Object *object, Object *export_parent, bool weak_export);
void visit_dupli_object(DupliObject *dupli_object,
Object *duplicator,
- const std::set<Object *> &dupli_set);
+ const DupliParentFinder &dupli_parent_finder);
void context_update_for_graph_index(HierarchyContext *context,
const ExportGraph::key_type &graph_index) const;
@@ -291,8 +326,10 @@ class AbstractHierarchyIterator {
virtual bool should_visit_dupli_object(const DupliObject *dupli_object) const;
virtual ExportGraph::key_type determine_graph_index_object(const HierarchyContext *context);
- virtual ExportGraph::key_type determine_graph_index_dupli(const HierarchyContext *context,
- const std::set<Object *> &dupli_set);
+ virtual ExportGraph::key_type determine_graph_index_dupli(
+ const HierarchyContext *context,
+ const DupliObject *dupli_object,
+ const DupliParentFinder &dupli_parent_finder);
/* These functions should create an AbstractHierarchyWriter subclass instance, or return
* nullptr if the object or its data should not be exported. Returning a nullptr for
@@ -309,7 +346,7 @@ class AbstractHierarchyIterator {
virtual AbstractHierarchyWriter *create_particle_writer(const HierarchyContext *context) = 0;
/* Called by release_writers() to free what the create_XXX_writer() functions allocated. */
- virtual void delete_object_writer(AbstractHierarchyWriter *writer) = 0;
+ virtual void release_writer(AbstractHierarchyWriter *writer) = 0;
AbstractHierarchyWriter *get_writer(const std::string &export_path) const;
ExportChildren &graph_children(const HierarchyContext *parent_context);
@@ -317,5 +354,3 @@ class AbstractHierarchyIterator {
} // namespace io
} // namespace blender
-
-#endif /* __ABSTRACT_HIERARCHY_ITERATOR_H__ */
diff --git a/source/blender/io/common/IO_dupli_persistent_id.hh b/source/blender/io/common/IO_dupli_persistent_id.hh
new file mode 100644
index 00000000000..6fabafd9d51
--- /dev/null
+++ b/source/blender/io/common/IO_dupli_persistent_id.hh
@@ -0,0 +1,65 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+#pragma once
+
+#include "BKE_duplilist.h"
+
+#include "DNA_object_types.h" /* For MAX_DUPLI_RECUR */
+
+#include <array>
+#include <optional>
+#include <ostream>
+
+namespace blender::io {
+
+/* Wrapper for DupliObject::persistent_id that can act as a map key. */
+class PersistentID {
+ protected:
+ constexpr static int array_length_ = MAX_DUPLI_RECUR;
+ typedef std::array<int, array_length_> PIDArray;
+ PIDArray persistent_id_;
+
+ explicit PersistentID(const PIDArray &persistent_id_values);
+
+ public:
+ PersistentID();
+ explicit PersistentID(const DupliObject *dupli_ob);
+
+ /* Return true iff the persistent IDs are the same, ignoring the first digit. */
+ bool is_from_same_instancer_as(const PersistentID &other) const;
+
+ /* Construct the persistent ID of this instance's instancer. */
+ PersistentID instancer_pid() const;
+
+ /* Construct a string representation by reversing the persistent ID.
+ * In case of a duplicator that is duplicated itself as well, this
+ * results in strings like:
+ * "3" for the duplicated duplicator, and
+ * "3-0", "3-1", etc. for its duplis. */
+ std::string as_object_name_suffix() const;
+
+ friend bool operator==(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b);
+ friend bool operator<(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b);
+ friend std::ostream &operator<<(std::ostream &os, const PersistentID &persistent_id);
+
+ private:
+ void copy_values_from(const PIDArray &persistent_id_values);
+};
+
+} // namespace blender::io
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
index dce6b8e178b..fbefc8c8e7e 100644
--- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
@@ -17,6 +17,7 @@
* All rights reserved.
*/
#include "IO_abstract_hierarchy_iterator.h"
+#include "dupli_parent_finder.hh"
#include <iostream>
#include <limits.h>
@@ -38,6 +39,7 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
+#include "DNA_rigidbody_types.h"
#include "DEG_depsgraph_query.h"
@@ -126,6 +128,9 @@ bool AbstractHierarchyWriter::check_is_animated(const HierarchyContext &context)
if (BKE_key_from_object(object) != nullptr) {
return true;
}
+ if (check_has_deforming_physics(context)) {
+ return true;
+ }
/* Test modifiers. */
/* TODO(Sybren): replace this with a check on the depsgraph to properly check for dependency on
@@ -141,6 +146,18 @@ bool AbstractHierarchyWriter::check_is_animated(const HierarchyContext &context)
return false;
}
+bool AbstractHierarchyWriter::check_has_physics(const HierarchyContext &context)
+{
+ const RigidBodyOb *rbo = context.object->rigidbody_object;
+ return rbo != nullptr && rbo->type == RBO_TYPE_ACTIVE;
+}
+
+bool AbstractHierarchyWriter::check_has_deforming_physics(const HierarchyContext &context)
+{
+ const RigidBodyOb *rbo = context.object->rigidbody_object;
+ return rbo != nullptr && rbo->type == RBO_TYPE_ACTIVE && (rbo->flag & RBO_FLAG_USE_DEFORM) != 0;
+}
+
AbstractHierarchyIterator::AbstractHierarchyIterator(Depsgraph *depsgraph)
: depsgraph_(depsgraph), writers_(), export_subset_({true, true})
{
@@ -148,6 +165,12 @@ AbstractHierarchyIterator::AbstractHierarchyIterator(Depsgraph *depsgraph)
AbstractHierarchyIterator::~AbstractHierarchyIterator()
{
+ /* release_writers() cannot be called here directly, as it calls into the pure-virtual
+ * release_writer() function. By the time this destructor is called, the subclass that implements
+ * that pure-virtual function is already destructed. */
+ BLI_assert(
+ writers_.empty() ||
+ !"release_writers() should be called before the AbstractHierarchyIterator goes out of scope");
}
void AbstractHierarchyIterator::iterate_and_write()
@@ -164,7 +187,7 @@ void AbstractHierarchyIterator::iterate_and_write()
void AbstractHierarchyIterator::release_writers()
{
for (WriterMap::value_type it : writers_) {
- delete_object_writer(it.second);
+ release_writer(it.second);
}
writers_.clear();
}
@@ -200,9 +223,9 @@ void AbstractHierarchyIterator::debug_print_export_graph(const ExportGraph &grap
{
size_t total_graph_size = 0;
for (const ExportGraph::value_type &map_iter : graph) {
- const DupliAndDuplicator &parent_info = map_iter.first;
- Object *const export_parent = parent_info.first;
- Object *const duplicator = parent_info.second;
+ const ObjectIdentifier &parent_info = map_iter.first;
+ const Object *const export_parent = parent_info.object;
+ const Object *const duplicator = parent_info.duplicated_by;
if (duplicator != nullptr) {
printf(" DU %s (as dupped by %s):\n",
@@ -217,7 +240,7 @@ void AbstractHierarchyIterator::debug_print_export_graph(const ExportGraph &grap
for (HierarchyContext *child_ctx : map_iter.second) {
if (child_ctx->duplicator == nullptr) {
printf(" - %s%s%s\n",
- child_ctx->object->id.name + 2,
+ child_ctx->export_name.c_str(),
child_ctx->weak_export ? " (weak)" : "",
child_ctx->original_export_path.empty() ?
"" :
@@ -225,7 +248,7 @@ void AbstractHierarchyIterator::debug_print_export_graph(const ExportGraph &grap
}
else {
printf(" - %s (dup by %s%s) %s\n",
- child_ctx->object->id.name + 2,
+ child_ctx->export_name.c_str(),
child_ctx->duplicator->id.name + 2,
child_ctx->weak_export ? ", weak" : "",
child_ctx->original_export_path.empty() ?
@@ -234,7 +257,7 @@ void AbstractHierarchyIterator::debug_print_export_graph(const ExportGraph &grap
}
}
}
- printf(" (Total graph size: %zu objects\n", total_graph_size);
+ printf(" (Total graph size: %zu objects)\n", total_graph_size);
}
void AbstractHierarchyIterator::export_graph_construct()
@@ -257,22 +280,21 @@ void AbstractHierarchyIterator::export_graph_construct()
// Export the duplicated objects instanced by this object.
ListBase *lb = object_duplilist(depsgraph_, scene, object);
if (lb) {
- // Construct the set of duplicated objects, so that later we can determine whether a parent
- // is also duplicated itself.
- std::set<Object *> dupli_set;
+ DupliParentFinder dupli_parent_finder;
+
LISTBASE_FOREACH (DupliObject *, dupli_object, lb) {
+ PersistentID persistent_id(dupli_object);
if (!should_visit_dupli_object(dupli_object)) {
continue;
}
- dupli_set.insert(dupli_object->ob);
+ dupli_parent_finder.insert(dupli_object);
}
LISTBASE_FOREACH (DupliObject *, dupli_object, lb) {
if (!should_visit_dupli_object(dupli_object)) {
continue;
}
-
- visit_dupli_object(dupli_object, object, dupli_set);
+ visit_dupli_object(dupli_object, object, dupli_parent_finder);
}
}
@@ -291,29 +313,30 @@ void AbstractHierarchyIterator::connect_loose_objects()
for (const ExportGraph::value_type &map_iter : export_graph_) {
for (const HierarchyContext *child : map_iter.second) {
// An object that is marked as a child of another object is not considered 'loose'.
- loose_objects_graph.erase(std::make_pair(child->object, child->duplicator));
+ ObjectIdentifier child_oid = ObjectIdentifier::for_hierarchy_context(child);
+ loose_objects_graph.erase(child_oid);
}
}
// The root of the hierarchy is always found, so it's never considered 'loose'.
- loose_objects_graph.erase(std::make_pair(nullptr, nullptr));
+ loose_objects_graph.erase(ObjectIdentifier::for_graph_root());
// Iterate over the loose objects and connect them to their export parent.
for (const ExportGraph::value_type &map_iter : loose_objects_graph) {
- const DupliAndDuplicator &export_info = map_iter.first;
- Object *object = export_info.first;
+ const ObjectIdentifier &graph_key = map_iter.first;
+ Object *object = graph_key.object;
while (true) {
// Loose objects will all be real objects, as duplicated objects always have
// their duplicator or other exported duplicated object as ancestor.
ExportGraph::iterator found_parent_iter = export_graph_.find(
- std::make_pair(object->parent, nullptr));
+ ObjectIdentifier::for_real_object(object->parent));
visit_object(object, object->parent, true);
if (found_parent_iter != export_graph_.end()) {
break;
}
// 'object->parent' will never be nullptr here, as the export graph contains the
- // tuple <nullptr, nullptr> as root and thus will cause a break.
+ // root as nullptr and thus will cause a break above.
BLI_assert(object->parent != nullptr);
object = object->parent;
@@ -326,10 +349,8 @@ static bool remove_weak_subtrees(const HierarchyContext *context,
const AbstractHierarchyIterator::ExportGraph &input_graph)
{
bool all_is_weak = context != nullptr && context->weak_export;
- Object *object = context != nullptr ? context->object : nullptr;
- Object *duplicator = context != nullptr ? context->duplicator : nullptr;
+ const ObjectIdentifier map_key = ObjectIdentifier::for_hierarchy_context(context);
- const AbstractHierarchyIterator::DupliAndDuplicator map_key = std::make_pair(object, duplicator);
AbstractHierarchyIterator::ExportGraph::const_iterator child_iterator;
child_iterator = input_graph.find(map_key);
@@ -399,7 +420,7 @@ void AbstractHierarchyIterator::visit_object(Object *object,
// check on whether an object is part of the export, rather than having to check all objects in
// the map. Note that it's not possible to simply search for (object->parent, nullptr), as the
// object's parent in Blender may not be the same as its export-parent.
- ExportGraph::key_type object_key = std::make_pair(object, nullptr);
+ ExportGraph::key_type object_key = ObjectIdentifier::for_real_object(object);
if (export_graph_.find(object_key) == export_graph_.end()) {
export_graph_[object_key] = ExportChildren();
}
@@ -408,16 +429,17 @@ void AbstractHierarchyIterator::visit_object(Object *object,
AbstractHierarchyIterator::ExportGraph::key_type AbstractHierarchyIterator::
determine_graph_index_object(const HierarchyContext *context)
{
- return std::make_pair(context->export_parent, nullptr);
+ return ObjectIdentifier::for_real_object(context->export_parent);
}
void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object,
Object *duplicator,
- const std::set<Object *> &dupli_set)
+ const DupliParentFinder &dupli_parent_finder)
{
HierarchyContext *context = new HierarchyContext();
context->object = dupli_object->ob;
context->duplicator = duplicator;
+ context->persistent_id = PersistentID(dupli_object);
context->weak_export = false;
context->export_path = "";
context->original_export_path = "";
@@ -427,38 +449,36 @@ void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object,
copy_m4_m4(context->matrix_world, dupli_object->mat);
// Construct export name for the dupli-instance.
- std::stringstream suffix_stream;
- suffix_stream << std::hex;
- for (int i = 0; i < MAX_DUPLI_RECUR && dupli_object->persistent_id[i] != INT_MAX; i++) {
- suffix_stream << "-" << dupli_object->persistent_id[i];
- }
- context->export_name = make_valid_name(get_object_name(context->object) + suffix_stream.str());
+ std::stringstream export_name_stream;
+ export_name_stream << get_object_name(context->object) << "-"
+ << context->persistent_id.as_object_name_suffix();
+ context->export_name = make_valid_name(export_name_stream.str());
- ExportGraph::key_type graph_index = determine_graph_index_dupli(context, dupli_set);
+ ExportGraph::key_type graph_index = determine_graph_index_dupli(
+ context, dupli_object, dupli_parent_finder);
context_update_for_graph_index(context, graph_index);
+
export_graph_[graph_index].insert(context);
}
AbstractHierarchyIterator::ExportGraph::key_type AbstractHierarchyIterator::
determine_graph_index_dupli(const HierarchyContext *context,
- const std::set<Object *> &dupli_set)
+ const DupliObject *dupli_object,
+ const DupliParentFinder &dupli_parent_finder)
{
- /* If the dupli-object's parent is also instanced by this object, use that as the
- * export parent. Otherwise use the dupli-parent as export parent. */
+ const DupliObject *dupli_parent = dupli_parent_finder.find_suitable_export_parent(dupli_object);
- Object *parent = context->object->parent;
- if (parent != nullptr && dupli_set.find(parent) != dupli_set.end()) {
- // The parent object is part of the duplicated collection.
- return std::make_pair(parent, context->duplicator);
+ if (dupli_parent != nullptr) {
+ return ObjectIdentifier::for_duplicated_object(dupli_parent, context->duplicator);
}
- return std::make_pair(context->duplicator, nullptr);
+ return ObjectIdentifier::for_real_object(context->duplicator);
}
void AbstractHierarchyIterator::context_update_for_graph_index(
HierarchyContext *context, const ExportGraph::key_type &graph_index) const
{
// Update the HierarchyContext so that it is consistent with the graph index.
- context->export_parent = graph_index.first;
+ context->export_parent = graph_index.object;
if (context->export_parent != context->object->parent) {
/* The parent object in Blender is NOT used as the export parent. This means
* that the world transform of this object can be influenced by objects that
@@ -470,11 +490,7 @@ void AbstractHierarchyIterator::context_update_for_graph_index(
AbstractHierarchyIterator::ExportChildren &AbstractHierarchyIterator::graph_children(
const HierarchyContext *context)
{
- if (context == nullptr) {
- return export_graph_[std::make_pair(nullptr, nullptr)];
- }
-
- return export_graph_[std::make_pair(context->object, context->duplicator)];
+ return export_graph_[ObjectIdentifier::for_hierarchy_context(context)];
}
void AbstractHierarchyIterator::determine_export_paths(const HierarchyContext *parent_context)
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc
new file mode 100644
index 00000000000..2bc7560e177
--- /dev/null
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc
@@ -0,0 +1,319 @@
+/*
+ * 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) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+#include "IO_abstract_hierarchy_iterator.h"
+#include "blenloader/blendfile_loading_base_test.h"
+
+#include "BLI_math.h"
+#include "DEG_depsgraph.h"
+#include "DNA_object_types.h"
+
+#include <map>
+#include <set>
+
+namespace blender::io {
+
+namespace {
+
+/* Mapping from ID.name to set of export hierarchy path. Duplicated objects can be exported
+ * multiple times with different export paths, hence the set. */
+typedef std::map<std::string, std::set<std::string>> used_writers;
+
+class TestHierarchyWriter : public AbstractHierarchyWriter {
+ public:
+ std::string writer_type;
+ used_writers &writers_map;
+
+ TestHierarchyWriter(const std::string &writer_type, used_writers &writers_map)
+ : writer_type(writer_type), writers_map(writers_map)
+ {
+ }
+
+ void write(HierarchyContext &context) override
+ {
+ const char *id_name = context.object->id.name;
+ used_writers::mapped_type &writers = writers_map[id_name];
+
+ if (writers.find(context.export_path) != writers.end()) {
+ ADD_FAILURE() << "Unexpectedly found another " << writer_type << " writer for " << id_name
+ << " to export to " << context.export_path;
+ }
+ writers.insert(context.export_path);
+ }
+};
+
+} // namespace
+
+class TestingHierarchyIterator : public AbstractHierarchyIterator {
+ public: /* Public so that the test cases can directly inspect the created writers. */
+ used_writers transform_writers;
+ used_writers data_writers;
+ used_writers hair_writers;
+ used_writers particle_writers;
+
+ explicit TestingHierarchyIterator(Depsgraph *depsgraph) : AbstractHierarchyIterator(depsgraph)
+ {
+ }
+ virtual ~TestingHierarchyIterator()
+ {
+ release_writers();
+ }
+
+ protected:
+ AbstractHierarchyWriter *create_transform_writer(const HierarchyContext * /*context*/) override
+ {
+ return new TestHierarchyWriter("transform", transform_writers);
+ }
+ AbstractHierarchyWriter *create_data_writer(const HierarchyContext * /*context*/) override
+ {
+ return new TestHierarchyWriter("data", data_writers);
+ }
+ AbstractHierarchyWriter *create_hair_writer(const HierarchyContext * /*context*/) override
+ {
+ return new TestHierarchyWriter("hair", hair_writers);
+ }
+ AbstractHierarchyWriter *create_particle_writer(const HierarchyContext * /*context*/) override
+ {
+ return new TestHierarchyWriter("particle", particle_writers);
+ }
+
+ void release_writer(AbstractHierarchyWriter *writer) override
+ {
+ delete writer;
+ }
+};
+
+class USDHierarchyIteratorTest : public BlendfileLoadingBaseTest {
+ protected:
+ TestingHierarchyIterator *iterator;
+
+ virtual void SetUp()
+ {
+ BlendfileLoadingBaseTest::SetUp();
+ iterator = nullptr;
+ }
+
+ virtual void TearDown()
+ {
+ iterator_free();
+ BlendfileLoadingBaseTest::TearDown();
+ }
+
+ /* Create a test iterator. */
+ void iterator_create()
+ {
+ iterator = new TestingHierarchyIterator(depsgraph);
+ }
+ /* Free the test iterator if it is not nullptr. */
+ void iterator_free()
+ {
+ if (iterator == nullptr) {
+ return;
+ }
+ delete iterator;
+ iterator = nullptr;
+ }
+};
+
+TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest)
+{
+ /* Load the test blend file. */
+ if (!blendfile_load("usd/usd_hierarchy_export_test.blend")) {
+ return;
+ }
+ depsgraph_create(DAG_EVAL_RENDER);
+ iterator_create();
+
+ iterator->iterate_and_write();
+
+ // Mapping from object name to set of export paths.
+ used_writers expected_transforms = {
+ {"OBCamera", {"/Camera"}},
+ {"OBDupli1", {"/Dupli1"}},
+ {"OBDupli2", {"/ParentOfDupli2/Dupli2"}},
+ {"OBGEO_Ear_L",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_L-1",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_L",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_L-1"}},
+ {"OBGEO_Ear_R",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_R-2",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_R",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_R-2"}},
+ {"OBGEO_Head",
+ {"/Dupli1/GEO_Head-0",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0"}},
+ {"OBGEO_Nose",
+ {"/Dupli1/GEO_Head-0/GEO_Nose-3",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Nose",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Nose-3"}},
+ {"OBGround plane", {"/Ground plane"}},
+ {"OBOutsideDupliGrandParent", {"/Ground plane/OutsideDupliGrandParent"}},
+ {"OBOutsideDupliParent", {"/Ground plane/OutsideDupliGrandParent/OutsideDupliParent"}},
+ {"OBParentOfDupli2", {"/ParentOfDupli2"}}};
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+
+ used_writers expected_data = {
+ {"OBCamera", {"/Camera/Camera"}},
+ {"OBGEO_Ear_L",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_L-1/Ear",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_L/Ear",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_L-1/Ear"}},
+ {"OBGEO_Ear_R",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_R-2/Ear",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_R/Ear",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_R-2/Ear"}},
+ {"OBGEO_Head",
+ {"/Dupli1/GEO_Head-0/Face",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/Face",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/Face"}},
+ {"OBGEO_Nose",
+ {"/Dupli1/GEO_Head-0/GEO_Nose-3/Nose",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Nose/Nose",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Nose-3/Nose"}},
+ {"OBGround plane", {"/Ground plane/Plane"}},
+ {"OBParentOfDupli2", {"/ParentOfDupli2/Icosphere"}},
+ };
+
+ EXPECT_EQ(expected_data, iterator->data_writers);
+
+ // The scene has no hair or particle systems.
+ EXPECT_EQ(0, iterator->hair_writers.size());
+ EXPECT_EQ(0, iterator->particle_writers.size());
+
+ // On the second iteration, everything should be written as well.
+ // This tests the default value of iterator->export_subset_.
+ iterator->transform_writers.clear();
+ iterator->data_writers.clear();
+ iterator->iterate_and_write();
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+ EXPECT_EQ(expected_data, iterator->data_writers);
+}
+
+TEST_F(USDHierarchyIteratorTest, ExportSubsetTest)
+{
+ // The scene has no hair or particle systems, and this is already covered by ExportHierarchyTest,
+ // so not included here. Update this test when hair & particle systems are included.
+
+ /* Load the test blend file. */
+ if (!blendfile_load("usd/usd_hierarchy_export_test.blend")) {
+ return;
+ }
+ depsgraph_create(DAG_EVAL_RENDER);
+ iterator_create();
+
+ // Mapping from object name to set of export paths.
+ used_writers expected_transforms = {
+ {"OBCamera", {"/Camera"}},
+ {"OBDupli1", {"/Dupli1"}},
+ {"OBDupli2", {"/ParentOfDupli2/Dupli2"}},
+ {"OBGEO_Ear_L",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_L-1",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_L",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_L-1"}},
+ {"OBGEO_Ear_R",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_R-2",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_R",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_R-2"}},
+ {"OBGEO_Head",
+ {"/Dupli1/GEO_Head-0",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0"}},
+ {"OBGEO_Nose",
+ {"/Dupli1/GEO_Head-0/GEO_Nose-3",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Nose",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Nose-3"}},
+ {"OBGround plane", {"/Ground plane"}},
+ {"OBOutsideDupliGrandParent", {"/Ground plane/OutsideDupliGrandParent"}},
+ {"OBOutsideDupliParent", {"/Ground plane/OutsideDupliGrandParent/OutsideDupliParent"}},
+ {"OBParentOfDupli2", {"/ParentOfDupli2"}}};
+
+ used_writers expected_data = {
+ {"OBCamera", {"/Camera/Camera"}},
+ {"OBGEO_Ear_L",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_L-1/Ear",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_L/Ear",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_L-1/Ear"}},
+ {"OBGEO_Ear_R",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_R-2/Ear",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_R/Ear",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_R-2/Ear"}},
+ {"OBGEO_Head",
+ {"/Dupli1/GEO_Head-0/Face",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/Face",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/Face"}},
+ {"OBGEO_Nose",
+ {"/Dupli1/GEO_Head-0/GEO_Nose-3/Nose",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Nose/Nose",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Nose-3/Nose"}},
+ {"OBGround plane", {"/Ground plane/Plane"}},
+ {"OBParentOfDupli2", {"/ParentOfDupli2/Icosphere"}},
+ };
+
+ // Even when only asking an export of transforms, on the first frame everything should be
+ // exported.
+ {
+ ExportSubset export_subset = {0};
+ export_subset.transforms = true;
+ export_subset.shapes = false;
+ iterator->set_export_subset(export_subset);
+ }
+ iterator->iterate_and_write();
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+ EXPECT_EQ(expected_data, iterator->data_writers);
+
+ // Clear data to prepare for the next iteration.
+ iterator->transform_writers.clear();
+ iterator->data_writers.clear();
+
+ // Second iteration, should only write transforms now.
+ iterator->iterate_and_write();
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+ EXPECT_EQ(0, iterator->data_writers.size());
+
+ // Clear data to prepare for the next iteration.
+ iterator->transform_writers.clear();
+ iterator->data_writers.clear();
+
+ // Third iteration, should only write data now.
+ {
+ ExportSubset export_subset = {0};
+ export_subset.transforms = false;
+ export_subset.shapes = true;
+ iterator->set_export_subset(export_subset);
+ }
+ iterator->iterate_and_write();
+ EXPECT_EQ(0, iterator->transform_writers.size());
+ EXPECT_EQ(expected_data, iterator->data_writers);
+
+ // Clear data to prepare for the next iteration.
+ iterator->transform_writers.clear();
+ iterator->data_writers.clear();
+
+ // Fourth iteration, should export everything now.
+ {
+ ExportSubset export_subset = {0};
+ export_subset.transforms = true;
+ export_subset.shapes = true;
+ iterator->set_export_subset(export_subset);
+ }
+ iterator->iterate_and_write();
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+ EXPECT_EQ(expected_data, iterator->data_writers);
+}
+} // namespace blender::io
diff --git a/source/blender/io/common/intern/dupli_parent_finder.cc b/source/blender/io/common/intern/dupli_parent_finder.cc
new file mode 100644
index 00000000000..73e33eff164
--- /dev/null
+++ b/source/blender/io/common/intern/dupli_parent_finder.cc
@@ -0,0 +1,104 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "dupli_parent_finder.hh"
+
+#include "BLI_utildefines.h"
+
+#include <iostream>
+
+namespace blender::io {
+
+DupliParentFinder::DupliParentFinder()
+{
+}
+
+DupliParentFinder::~DupliParentFinder()
+{
+}
+
+void DupliParentFinder::insert(const DupliObject *dupli_ob)
+{
+ dupli_set_.insert(dupli_ob->ob);
+
+ PersistentID dupli_pid(dupli_ob);
+ pid_to_dupli_[dupli_pid] = dupli_ob;
+ instancer_pid_to_duplis_[dupli_pid.instancer_pid()].insert(dupli_ob);
+}
+
+bool DupliParentFinder::is_duplicated(const Object *object) const
+{
+ return dupli_set_.find(object) != dupli_set_.end();
+}
+
+const DupliObject *DupliParentFinder::find_suitable_export_parent(
+ const DupliObject *dupli_ob) const
+{
+ if (dupli_ob->ob->parent != nullptr) {
+ const DupliObject *parent = find_duplicated_parent(dupli_ob);
+ if (parent != nullptr) {
+ return parent;
+ }
+ }
+
+ return find_instancer(dupli_ob);
+}
+
+const DupliObject *DupliParentFinder::find_duplicated_parent(const DupliObject *dupli_ob) const
+{
+ const PersistentID dupli_pid(dupli_ob);
+ PersistentID parent_pid = dupli_pid.instancer_pid();
+
+ const Object *parent_ob = dupli_ob->ob->parent;
+ BLI_assert(parent_ob != nullptr);
+
+ InstancerPIDToDuplisMap::const_iterator found = instancer_pid_to_duplis_.find(parent_pid);
+ if (found == instancer_pid_to_duplis_.end()) {
+ /* Unexpected, as there should be at least one entry here, for the dupli_ob itself. */
+ return nullptr;
+ }
+
+ for (const DupliObject *potential_parent_dupli : found->second) {
+ if (potential_parent_dupli->ob != parent_ob) {
+ continue;
+ }
+
+ PersistentID potential_parent_pid(potential_parent_dupli);
+ if (potential_parent_pid.is_from_same_instancer_as(dupli_pid)) {
+ return potential_parent_dupli;
+ }
+ }
+ return nullptr;
+}
+
+const DupliObject *DupliParentFinder::find_instancer(const DupliObject *dupli_ob) const
+{
+ PersistentID dupli_pid(dupli_ob);
+ PersistentID parent_pid = dupli_pid.instancer_pid();
+
+ PIDToDupliMap::const_iterator found = pid_to_dupli_.find(parent_pid);
+ if (found == pid_to_dupli_.end()) {
+ return nullptr;
+ }
+
+ const DupliObject *instancer_dupli = found->second;
+ return instancer_dupli;
+}
+
+} // namespace blender::io
diff --git a/source/blender/io/common/intern/dupli_parent_finder.hh b/source/blender/io/common/intern/dupli_parent_finder.hh
new file mode 100644
index 00000000000..3dcf037bb5e
--- /dev/null
+++ b/source/blender/io/common/intern/dupli_parent_finder.hh
@@ -0,0 +1,59 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+#pragma once
+
+#include "IO_dupli_persistent_id.hh"
+
+#include "BKE_duplilist.h"
+
+#include <map>
+#include <set>
+
+namespace blender::io {
+
+/* Find relations between duplicated objects. This class should be instanced for a single real
+ * object, and fed its dupli-objects. */
+class DupliParentFinder final {
+ private:
+ /* To check whether an Object * is instanced by this duplicator. */
+ std::set<const Object *> dupli_set_;
+
+ /* To find the DupliObject given its Persistent ID. */
+ typedef std::map<const PersistentID, const DupliObject *> PIDToDupliMap;
+ PIDToDupliMap pid_to_dupli_;
+
+ /* Mapping from instancer PID to duplis instanced by it. */
+ typedef std::map<const PersistentID, std::set<const DupliObject *>> InstancerPIDToDuplisMap;
+ InstancerPIDToDuplisMap instancer_pid_to_duplis_;
+
+ public:
+ DupliParentFinder();
+ ~DupliParentFinder();
+
+ void insert(const DupliObject *dupli_ob);
+
+ bool is_duplicated(const Object *object) const;
+ const DupliObject *find_suitable_export_parent(const DupliObject *dupli_ob) const;
+
+ private:
+ const DupliObject *find_duplicated_parent(const DupliObject *dupli_ob) const;
+ const DupliObject *find_instancer(const DupliObject *dupli_ob) const;
+};
+
+} // namespace blender::io
diff --git a/source/blender/io/common/intern/dupli_persistent_id.cc b/source/blender/io/common/intern/dupli_persistent_id.cc
new file mode 100644
index 00000000000..b40cd83ef44
--- /dev/null
+++ b/source/blender/io/common/intern/dupli_persistent_id.cc
@@ -0,0 +1,167 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "dupli_parent_finder.hh"
+
+#include <climits>
+#include <cstring>
+#include <ostream>
+#include <sstream>
+
+namespace blender::io {
+
+PersistentID::PersistentID()
+{
+ persistent_id_[0] = INT_MAX;
+}
+
+PersistentID::PersistentID(const DupliObject *dupli_ob)
+{
+ for (int index = 0; index < array_length_; ++index) {
+ persistent_id_[index] = dupli_ob->persistent_id[index];
+ }
+}
+
+PersistentID::PersistentID(const PIDArray &persistent_id_values)
+{
+ persistent_id_ = persistent_id_values;
+}
+
+bool PersistentID::is_from_same_instancer_as(const PersistentID &other) const
+{
+ if (persistent_id_[0] == INT_MAX || other.persistent_id_[0] == INT_MAX) {
+ /* Either one or the other is not instanced at all, so definitely not from the same instancer.
+ */
+ return false;
+ }
+
+ /* Start at index 1 to skip the first digit. */
+ for (int index = 1; index < array_length_; ++index) {
+ const int pid_digit_a = persistent_id_[index];
+ const int pid_digit_b = other.persistent_id_[index];
+
+ if (pid_digit_a != pid_digit_b) {
+ return false;
+ }
+
+ if (pid_digit_a == INT_MAX) {
+ /* Both persistent IDs were identical so far, and this marks the end of the useful data. */
+ break;
+ }
+ }
+ return true;
+}
+
+PersistentID PersistentID::instancer_pid() const
+{
+ if (persistent_id_[0] == INT_MAX) {
+ return PersistentID();
+ }
+
+ /* Left-shift the entire PID by 1. */
+ PIDArray new_pid_values;
+ int index;
+ for (index = 0; index < array_length_ - 1; ++index) {
+ new_pid_values[index] = persistent_id_[index + 1];
+ }
+ new_pid_values[index] = INT_MAX;
+
+ return PersistentID(new_pid_values);
+}
+
+std::string PersistentID::as_object_name_suffix() const
+{
+ std::stringstream stream;
+
+ /* Find one past the last index. */
+ int index;
+ for (index = 0; index < array_length_ && persistent_id_[index] < INT_MAX; ++index) {
+ ;
+ }
+
+ /* Iterate backward to construct the string. */
+ --index;
+ for (; index >= 0; --index) {
+ stream << persistent_id_[index];
+ if (index > 0) {
+ stream << "-";
+ }
+ }
+
+ return stream.str();
+}
+
+bool operator<(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b)
+{
+ const PersistentID::PIDArray &pid_a = persistent_id_a.persistent_id_;
+ const PersistentID::PIDArray &pid_b = persistent_id_b.persistent_id_;
+
+ for (int index = 0; index < PersistentID::array_length_; ++index) {
+ const int pid_digit_a = pid_a[index];
+ const int pid_digit_b = pid_b[index];
+
+ if (pid_digit_a != pid_digit_b) {
+ return pid_digit_a < pid_digit_b;
+ }
+
+ if (pid_a[index] == INT_MAX) {
+ break;
+ }
+ }
+ /* Both Persistent IDs were equal, so not less-than. */
+ return false;
+}
+
+bool operator==(const PersistentID &persistent_id_a, const PersistentID &persistent_id_b)
+{
+ const PersistentID::PIDArray &pid_a = persistent_id_a.persistent_id_;
+ const PersistentID::PIDArray &pid_b = persistent_id_b.persistent_id_;
+
+ for (int index = 0; index < PersistentID::array_length_; ++index) {
+ const int pid_digit_a = pid_a[index];
+ const int pid_digit_b = pid_b[index];
+
+ if (pid_digit_a != pid_digit_b) {
+ return false;
+ }
+
+ if (pid_a[index] == INT_MAX) {
+ break;
+ }
+ }
+ return true;
+}
+
+std::ostream &operator<<(std::ostream &os, const PersistentID &persistent_id)
+{
+ if (persistent_id.persistent_id_[0] == INT_MAX) {
+ return os;
+ }
+
+ const PersistentID::PIDArray &pid_array = persistent_id.persistent_id_;
+ for (int index = 0; index < PersistentID::array_length_ && pid_array[index] < INT_MAX; ++index) {
+ if (index > 0) {
+ os << "-";
+ }
+ os << pid_array[index];
+ }
+ return os;
+}
+
+} // namespace blender::io
diff --git a/source/blender/io/common/intern/hierarchy_context_order_test.cc b/source/blender/io/common/intern/hierarchy_context_order_test.cc
new file mode 100644
index 00000000000..f4e2b81b39b
--- /dev/null
+++ b/source/blender/io/common/intern/hierarchy_context_order_test.cc
@@ -0,0 +1,127 @@
+/*
+ * 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) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+#include "IO_abstract_hierarchy_iterator.h"
+
+#include "testing/testing.h"
+
+#include "BLI_utildefines.h"
+
+namespace blender::io {
+
+namespace {
+
+Object *fake_pointer(int value)
+{
+ return static_cast<Object *>(POINTER_FROM_INT(value));
+}
+
+} // namespace
+
+class HierarchyContextOrderTest : public testing::Test {
+};
+
+TEST_F(HierarchyContextOrderTest, ObjectPointerTest)
+{
+ HierarchyContext ctx_a = {0};
+ ctx_a.object = fake_pointer(1);
+ ctx_a.duplicator = nullptr;
+
+ HierarchyContext ctx_b = {0};
+ ctx_b.object = fake_pointer(2);
+ ctx_b.duplicator = nullptr;
+
+ EXPECT_LT(ctx_a, ctx_b);
+ EXPECT_FALSE(ctx_b < ctx_a);
+ EXPECT_FALSE(ctx_a < ctx_a);
+}
+
+TEST_F(HierarchyContextOrderTest, DuplicatorPointerTest)
+{
+ HierarchyContext ctx_a = {0};
+ ctx_a.object = fake_pointer(1);
+ ctx_a.duplicator = fake_pointer(1);
+ ctx_a.export_name = "A";
+
+ HierarchyContext ctx_b = {0};
+ ctx_b.object = fake_pointer(1);
+ ctx_b.duplicator = fake_pointer(1);
+ ctx_b.export_name = "B";
+
+ EXPECT_LT(ctx_a, ctx_b);
+ EXPECT_FALSE(ctx_b < ctx_a);
+ EXPECT_FALSE(ctx_a < ctx_a);
+}
+
+TEST_F(HierarchyContextOrderTest, ExportParentTest)
+{
+ HierarchyContext ctx_a = {0};
+ ctx_a.object = fake_pointer(1);
+ ctx_a.export_parent = fake_pointer(1);
+
+ HierarchyContext ctx_b = {0};
+ ctx_b.object = fake_pointer(1);
+ ctx_b.export_parent = fake_pointer(2);
+
+ EXPECT_LT(ctx_a, ctx_b);
+ EXPECT_FALSE(ctx_b < ctx_a);
+ EXPECT_FALSE(ctx_a < ctx_a);
+}
+
+TEST_F(HierarchyContextOrderTest, TransitiveTest)
+{
+ HierarchyContext ctx_a = {0};
+ ctx_a.object = fake_pointer(1);
+ ctx_a.export_parent = fake_pointer(1);
+ ctx_a.duplicator = nullptr;
+ ctx_a.export_name = "A";
+
+ HierarchyContext ctx_b = {0};
+ ctx_b.object = fake_pointer(2);
+ ctx_b.export_parent = nullptr;
+ ctx_b.duplicator = fake_pointer(1);
+ ctx_b.export_name = "B";
+
+ HierarchyContext ctx_c = {0};
+ ctx_c.object = fake_pointer(2);
+ ctx_c.export_parent = fake_pointer(2);
+ ctx_c.duplicator = fake_pointer(1);
+ ctx_c.export_name = "C";
+
+ HierarchyContext ctx_d = {0};
+ ctx_d.object = fake_pointer(2);
+ ctx_d.export_parent = fake_pointer(3);
+ ctx_d.duplicator = nullptr;
+ ctx_d.export_name = "D";
+
+ EXPECT_LT(ctx_a, ctx_b);
+ EXPECT_LT(ctx_a, ctx_c);
+ EXPECT_LT(ctx_a, ctx_d);
+ EXPECT_LT(ctx_b, ctx_c);
+ EXPECT_LT(ctx_b, ctx_d);
+ EXPECT_LT(ctx_c, ctx_d);
+
+ EXPECT_FALSE(ctx_b < ctx_a);
+ EXPECT_FALSE(ctx_c < ctx_a);
+ EXPECT_FALSE(ctx_d < ctx_a);
+ EXPECT_FALSE(ctx_c < ctx_b);
+ EXPECT_FALSE(ctx_d < ctx_b);
+ EXPECT_FALSE(ctx_d < ctx_c);
+}
+
+} // namespace blender::io
diff --git a/source/blender/io/common/intern/object_identifier.cc b/source/blender/io/common/intern/object_identifier.cc
new file mode 100644
index 00000000000..696bc5d2c34
--- /dev/null
+++ b/source/blender/io/common/intern/object_identifier.cc
@@ -0,0 +1,116 @@
+/*
+ * 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) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+#include "IO_abstract_hierarchy_iterator.h"
+
+#include "BKE_duplilist.h"
+
+extern "C" {
+#include <limits.h> /* For INT_MAX. */
+}
+#include <cstring>
+#include <sstream>
+
+namespace blender {
+namespace io {
+
+ObjectIdentifier::ObjectIdentifier(Object *object,
+ Object *duplicated_by,
+ const PersistentID &persistent_id)
+ : object(object), duplicated_by(duplicated_by), persistent_id(persistent_id)
+{
+}
+
+ObjectIdentifier::ObjectIdentifier(const ObjectIdentifier &other)
+ : object(other.object), duplicated_by(other.duplicated_by), persistent_id(other.persistent_id)
+{
+}
+
+ObjectIdentifier::~ObjectIdentifier()
+{
+}
+
+ObjectIdentifier ObjectIdentifier::for_real_object(Object *object)
+{
+ return ObjectIdentifier(object, nullptr, PersistentID());
+}
+
+ObjectIdentifier ObjectIdentifier::for_hierarchy_context(const HierarchyContext *context)
+{
+ if (context == nullptr) {
+ return for_graph_root();
+ }
+ if (context->duplicator != nullptr) {
+ return ObjectIdentifier(context->object, context->duplicator, context->persistent_id);
+ }
+ return for_real_object(context->object);
+}
+
+ObjectIdentifier ObjectIdentifier::for_duplicated_object(const DupliObject *dupli_object,
+ Object *duplicated_by)
+{
+ return ObjectIdentifier(dupli_object->ob, duplicated_by, PersistentID(dupli_object));
+}
+
+ObjectIdentifier ObjectIdentifier::for_graph_root()
+{
+ return ObjectIdentifier(nullptr, nullptr, PersistentID());
+}
+
+bool ObjectIdentifier::is_root() const
+{
+ return object == nullptr;
+}
+
+bool operator<(const ObjectIdentifier &obj_ident_a, const ObjectIdentifier &obj_ident_b)
+{
+ if (obj_ident_a.object != obj_ident_b.object) {
+ return obj_ident_a.object < obj_ident_b.object;
+ }
+
+ if (obj_ident_a.duplicated_by != obj_ident_b.duplicated_by) {
+ return obj_ident_a.duplicated_by < obj_ident_b.duplicated_by;
+ }
+
+ if (obj_ident_a.duplicated_by == nullptr) {
+ /* Both are real objects, no need to check the persistent ID. */
+ return false;
+ }
+
+ /* Same object, both are duplicated, use the persistent IDs to determine order. */
+ return obj_ident_a.persistent_id < obj_ident_b.persistent_id;
+}
+
+bool operator==(const ObjectIdentifier &obj_ident_a, const ObjectIdentifier &obj_ident_b)
+{
+ if (obj_ident_a.object != obj_ident_b.object) {
+ return false;
+ }
+ if (obj_ident_a.duplicated_by != obj_ident_b.duplicated_by) {
+ return false;
+ }
+ if (obj_ident_a.duplicated_by == nullptr) {
+ return true;
+ }
+
+ /* Same object, both are duplicated, use the persistent IDs to determine equality. */
+ return obj_ident_a.persistent_id == obj_ident_b.persistent_id;
+}
+
+} // namespace io
+} // namespace blender
diff --git a/source/blender/io/common/intern/object_identifier_test.cc b/source/blender/io/common/intern/object_identifier_test.cc
new file mode 100644
index 00000000000..2b565876f22
--- /dev/null
+++ b/source/blender/io/common/intern/object_identifier_test.cc
@@ -0,0 +1,234 @@
+/*
+ * 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) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+#include "IO_abstract_hierarchy_iterator.h"
+
+#include "testing/testing.h"
+
+#include "BLI_utildefines.h"
+
+#include <climits>
+
+namespace blender::io {
+
+namespace {
+
+/* Return object pointer for use in tests. This makes it possible to reliably test for
+ * order/equality functions while using hard-coded values for simplicity. */
+Object *fake_pointer(int value)
+{
+ return static_cast<Object *>(POINTER_FROM_INT(value));
+}
+
+/* PersistentID subclass for use in tests, making it easier to construct test values. */
+class TestPersistentID : public PersistentID {
+ public:
+ TestPersistentID(int value0,
+ int value1,
+ int value2,
+ int value3,
+ int value4,
+ int value5,
+ int value6,
+ int value7)
+ {
+ persistent_id_[0] = value0;
+ persistent_id_[1] = value1;
+ persistent_id_[2] = value2;
+ persistent_id_[3] = value3;
+ persistent_id_[4] = value4;
+ persistent_id_[5] = value5;
+ persistent_id_[6] = value6;
+ persistent_id_[7] = value7;
+ }
+ TestPersistentID(int value0, int value1, int value2)
+ : TestPersistentID(value0, value1, value2, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX)
+ {
+ }
+ TestPersistentID(int value0, int value1) : TestPersistentID(value0, value1, INT_MAX)
+ {
+ }
+ explicit TestPersistentID(int value0) : TestPersistentID(value0, INT_MAX)
+ {
+ }
+};
+
+/* ObjectIdentifier subclass for use in tests, making it easier to construct test values. */
+class TestObjectIdentifier : public ObjectIdentifier {
+ public:
+ TestObjectIdentifier(Object *object, Object *duplicated_by, const PersistentID &persistent_id)
+ : ObjectIdentifier(object, duplicated_by, persistent_id)
+ {
+ }
+};
+
+} // namespace
+
+class ObjectIdentifierOrderTest : public testing::Test {
+};
+
+TEST_F(ObjectIdentifierOrderTest, graph_root)
+{
+ ObjectIdentifier id_root_1 = ObjectIdentifier::for_graph_root();
+ ObjectIdentifier id_root_2 = ObjectIdentifier::for_graph_root();
+ EXPECT_TRUE(id_root_1 == id_root_2);
+ EXPECT_FALSE(id_root_1 < id_root_2);
+ EXPECT_FALSE(id_root_2 < id_root_1);
+
+ ObjectIdentifier id_a = ObjectIdentifier::for_real_object(fake_pointer(1));
+ EXPECT_FALSE(id_root_1 == id_a);
+ EXPECT_TRUE(id_root_1 < id_a);
+ EXPECT_FALSE(id_a < id_root_1);
+
+ ObjectIdentifier id_accidental_root = ObjectIdentifier::for_real_object(nullptr);
+ EXPECT_TRUE(id_root_1 == id_accidental_root);
+ EXPECT_FALSE(id_root_1 < id_accidental_root);
+ EXPECT_FALSE(id_accidental_root < id_root_1);
+}
+
+TEST_F(ObjectIdentifierOrderTest, real_objects)
+{
+ ObjectIdentifier id_a = ObjectIdentifier::for_real_object(fake_pointer(1));
+ ObjectIdentifier id_b = ObjectIdentifier::for_real_object(fake_pointer(2));
+ EXPECT_FALSE(id_a == id_b);
+ EXPECT_TRUE(id_a < id_b);
+}
+
+TEST_F(ObjectIdentifierOrderTest, duplicated_objects)
+{
+ ObjectIdentifier id_real_a = ObjectIdentifier::for_real_object(fake_pointer(1));
+ TestObjectIdentifier id_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
+ TestObjectIdentifier id_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
+ TestObjectIdentifier id_different_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(1));
+
+ EXPECT_FALSE(id_real_a == id_dupli_a);
+ EXPECT_FALSE(id_dupli_a == id_dupli_b);
+ EXPECT_TRUE(id_real_a < id_dupli_a);
+ EXPECT_TRUE(id_real_a < id_dupli_b);
+ EXPECT_TRUE(id_dupli_a < id_dupli_b);
+ EXPECT_TRUE(id_dupli_a < id_different_dupli_b);
+
+ EXPECT_FALSE(id_dupli_b == id_different_dupli_b);
+ EXPECT_FALSE(id_dupli_a == id_different_dupli_b);
+ EXPECT_TRUE(id_dupli_b < id_different_dupli_b);
+ EXPECT_FALSE(id_different_dupli_b < id_dupli_b);
+}
+
+TEST_F(ObjectIdentifierOrderTest, behaviour_as_map_keys)
+{
+ ObjectIdentifier id_root = ObjectIdentifier::for_graph_root();
+ ObjectIdentifier id_another_root = ObjectIdentifier::for_graph_root();
+ ObjectIdentifier id_real_a = ObjectIdentifier::for_real_object(fake_pointer(1));
+ TestObjectIdentifier id_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
+ TestObjectIdentifier id_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
+ AbstractHierarchyIterator::ExportGraph graph;
+
+ /* This inserts the keys with default values. */
+ graph[id_root];
+ graph[id_real_a];
+ graph[id_dupli_a];
+ graph[id_dupli_b];
+ graph[id_another_root];
+
+ EXPECT_EQ(4, graph.size());
+
+ graph.erase(id_another_root);
+ EXPECT_EQ(3, graph.size());
+
+ TestObjectIdentifier id_another_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
+ graph.erase(id_another_dupli_b);
+ EXPECT_EQ(2, graph.size());
+}
+
+TEST_F(ObjectIdentifierOrderTest, map_copy_and_update)
+{
+ ObjectIdentifier id_root = ObjectIdentifier::for_graph_root();
+ ObjectIdentifier id_real_a = ObjectIdentifier::for_real_object(fake_pointer(1));
+ TestObjectIdentifier id_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
+ TestObjectIdentifier id_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
+ TestObjectIdentifier id_dupli_c(fake_pointer(1), fake_pointer(3), TestPersistentID(1));
+ AbstractHierarchyIterator::ExportGraph graph;
+
+ /* This inserts the keys with default values. */
+ graph[id_root];
+ graph[id_real_a];
+ graph[id_dupli_a];
+ graph[id_dupli_b];
+ graph[id_dupli_c];
+ EXPECT_EQ(5, graph.size());
+
+ AbstractHierarchyIterator::ExportGraph graph_copy = graph;
+ EXPECT_EQ(5, graph_copy.size());
+
+ // Updating a value in a copy should not update the original.
+ HierarchyContext ctx1;
+ HierarchyContext ctx2;
+ ctx1.object = fake_pointer(1);
+ ctx2.object = fake_pointer(2);
+
+ graph_copy[id_root].insert(&ctx1);
+ EXPECT_EQ(0, graph[id_root].size());
+
+ // Deleting a key in the copy should not update the original.
+ graph_copy.erase(id_dupli_c);
+ EXPECT_EQ(4, graph_copy.size());
+ EXPECT_EQ(5, graph.size());
+}
+
+class PersistentIDTest : public testing::Test {
+};
+
+TEST_F(PersistentIDTest, is_from_same_instancer)
+{
+ PersistentID child_id_a = TestPersistentID(42, 327);
+ PersistentID child_id_b = TestPersistentID(17, 327);
+ PersistentID child_id_c = TestPersistentID(17);
+
+ EXPECT_TRUE(child_id_a.is_from_same_instancer_as(child_id_b));
+ EXPECT_FALSE(child_id_a.is_from_same_instancer_as(child_id_c));
+}
+
+TEST_F(PersistentIDTest, instancer_id)
+{
+ PersistentID child_id = TestPersistentID(42, 327);
+
+ PersistentID expect_instancer_id = TestPersistentID(327);
+ EXPECT_EQ(expect_instancer_id, child_id.instancer_pid());
+
+ PersistentID empty_id;
+ EXPECT_EQ(empty_id, child_id.instancer_pid().instancer_pid());
+
+ EXPECT_LT(child_id, expect_instancer_id);
+ EXPECT_LT(expect_instancer_id, empty_id);
+}
+
+TEST_F(PersistentIDTest, as_object_name_suffix)
+{
+ EXPECT_EQ("", PersistentID().as_object_name_suffix());
+ EXPECT_EQ("47", TestPersistentID(47).as_object_name_suffix());
+ EXPECT_EQ("327-47", TestPersistentID(47, 327).as_object_name_suffix());
+ EXPECT_EQ("42-327-47", TestPersistentID(47, 327, 42).as_object_name_suffix());
+
+ EXPECT_EQ("7-6-5-4-3-2-1-0", TestPersistentID(0, 1, 2, 3, 4, 5, 6, 7).as_object_name_suffix());
+
+ EXPECT_EQ("0-0-0", TestPersistentID(0, 0, 0).as_object_name_suffix());
+ EXPECT_EQ("0-0", TestPersistentID(0, 0).as_object_name_suffix());
+ EXPECT_EQ("-3--2--1", TestPersistentID(-1, -2, -3).as_object_name_suffix());
+}
+
+} // namespace blender::io
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index 19e16a5b328..79b15c60b94 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -109,3 +109,15 @@ else()
endif()
target_link_libraries(bf_usd INTERFACE ${TBB_LIBRARIES})
+
+if(WITH_GTESTS)
+ set(TEST_SRC
+ tests/usd_stage_creation_test.cc
+ )
+ set(TEST_INC
+ )
+ set(TEST_LIB
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_io_usd_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
+endif()
diff --git a/source/blender/io/usd/intern/usd_capi.cc b/source/blender/io/usd/intern/usd_capi.cc
index 2d3972410a4..98aef62f38e 100644
--- a/source/blender/io/usd/intern/usd_capi.cc
+++ b/source/blender/io/usd/intern/usd_capi.cc
@@ -59,7 +59,12 @@ struct ExportJobData {
bool export_ok;
};
-static void export_startjob(void *customdata, short *stop, short *do_update, float *progress)
+static void export_startjob(void *customdata,
+ /* Cannot be const, this function implements wm_jobs_start_callback.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ short *stop,
+ short *do_update,
+ float *progress)
{
ExportJobData *data = static_cast<ExportJobData *>(customdata);
data->export_ok = false;
diff --git a/source/blender/io/usd/intern/usd_exporter_context.h b/source/blender/io/usd/intern/usd_exporter_context.h
index 07a9d0fc0c5..5513768b527 100644
--- a/source/blender/io/usd/intern/usd_exporter_context.h
+++ b/source/blender/io/usd/intern/usd_exporter_context.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
-#ifndef __USD_EXPORTER_CONTEXT_H__
-#define __USD_EXPORTER_CONTEXT_H__
+#pragma once
#include "usd.h"
@@ -44,5 +43,3 @@ struct USDExporterContext {
} // namespace usd
} // namespace io
} // namespace blender
-
-#endif /* __USD_EXPORTER_CONTEXT_H__ */
diff --git a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc
index 388b588b331..39fbef70e81 100644
--- a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc
+++ b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc
@@ -34,6 +34,7 @@
#include "BKE_duplilist.h"
#include "BLI_assert.h"
+#include "BLI_utildefines.h"
#include "DEG_depsgraph_query.h"
@@ -60,7 +61,7 @@ bool USDHierarchyIterator::mark_as_weak_export(const Object *object) const
return false;
}
-void USDHierarchyIterator::delete_object_writer(AbstractHierarchyWriter *writer)
+void USDHierarchyIterator::release_writer(AbstractHierarchyWriter *writer)
{
delete static_cast<USDAbstractWriter *>(writer);
}
@@ -72,7 +73,7 @@ std::string USDHierarchyIterator::make_valid_name(const std::string &name) const
void USDHierarchyIterator::set_export_frame(float frame_nr)
{
- // The USD stage is already set up to have FPS timecodes per frame.
+ /* The USD stage is already set up to have FPS time-codes per frame. */
export_time_ = pxr::UsdTimeCode(frame_nr);
}
@@ -142,7 +143,8 @@ AbstractHierarchyWriter *USDHierarchyIterator::create_hair_writer(const Hierarch
return new USDHairWriter(create_usd_export_context(context));
}
-AbstractHierarchyWriter *USDHierarchyIterator::create_particle_writer(const HierarchyContext *)
+AbstractHierarchyWriter *USDHierarchyIterator::create_particle_writer(
+ const HierarchyContext *UNUSED(context))
{
return nullptr;
}
diff --git a/source/blender/io/usd/intern/usd_hierarchy_iterator.h b/source/blender/io/usd/intern/usd_hierarchy_iterator.h
index 7d750bff0cb..03e80ce735a 100644
--- a/source/blender/io/usd/intern/usd_hierarchy_iterator.h
+++ b/source/blender/io/usd/intern/usd_hierarchy_iterator.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
-#ifndef __USD_HIERARCHY_ITERATOR_H__
-#define __USD_HIERARCHY_ITERATOR_H__
+#pragma once
#include "IO_abstract_hierarchy_iterator.h"
#include "usd.h"
@@ -66,7 +65,7 @@ class USDHierarchyIterator : public AbstractHierarchyIterator {
virtual AbstractHierarchyWriter *create_particle_writer(
const HierarchyContext *context) override;
- virtual void delete_object_writer(AbstractHierarchyWriter *writer) override;
+ virtual void release_writer(AbstractHierarchyWriter *writer) override;
private:
USDExporterContext create_usd_export_context(const HierarchyContext *context);
@@ -75,5 +74,3 @@ class USDHierarchyIterator : public AbstractHierarchyIterator {
} // namespace usd
} // namespace io
} // namespace blender
-
-#endif /* __USD_HIERARCHY_ITERATOR_H__ */
diff --git a/source/blender/io/usd/intern/usd_writer_abstract.h b/source/blender/io/usd/intern/usd_writer_abstract.h
index f81cf5197af..a689deaf0d8 100644
--- a/source/blender/io/usd/intern/usd_writer_abstract.h
+++ b/source/blender/io/usd/intern/usd_writer_abstract.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
-#ifndef __USD_WRITER_ABSTRACT_H__
-#define __USD_WRITER_ABSTRACT_H__
+#pragma once
#include "IO_abstract_hierarchy_iterator.h"
#include "usd_exporter_context.h"
@@ -78,5 +77,3 @@ class USDAbstractWriter : public AbstractHierarchyWriter {
} // namespace usd
} // namespace io
} // namespace blender
-
-#endif /* __USD_WRITER_ABSTRACT_H__ */
diff --git a/source/blender/io/usd/intern/usd_writer_camera.h b/source/blender/io/usd/intern/usd_writer_camera.h
index 8b5795d7d9f..1c613d7879b 100644
--- a/source/blender/io/usd/intern/usd_writer_camera.h
+++ b/source/blender/io/usd/intern/usd_writer_camera.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
-#ifndef __USD_WRITER_CAMERA_H__
-#define __USD_WRITER_CAMERA_H__
+#pragma once
#include "usd_writer_abstract.h"
@@ -38,5 +37,3 @@ class USDCameraWriter : public USDAbstractWriter {
} // namespace usd
} // namespace io
} // namespace blender
-
-#endif /* __USD_WRITER_CAMERA_H__ */
diff --git a/source/blender/io/usd/intern/usd_writer_hair.cc b/source/blender/io/usd/intern/usd_writer_hair.cc
index 0e0256bdb69..0fd5c4ce727 100644
--- a/source/blender/io/usd/intern/usd_writer_hair.cc
+++ b/source/blender/io/usd/intern/usd_writer_hair.cc
@@ -82,7 +82,7 @@ void USDHairWriter::do_write(HierarchyContext &context)
}
}
-bool USDHairWriter::check_is_animated(const HierarchyContext &) const
+bool USDHairWriter::check_is_animated(const HierarchyContext &UNUSED(context)) const
{
return true;
}
diff --git a/source/blender/io/usd/intern/usd_writer_hair.h b/source/blender/io/usd/intern/usd_writer_hair.h
index cecacd0a355..b9a28013875 100644
--- a/source/blender/io/usd/intern/usd_writer_hair.h
+++ b/source/blender/io/usd/intern/usd_writer_hair.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
-#ifndef __USD_WRITER_HAIR_H__
-#define __USD_WRITER_HAIR_H__
+#pragma once
#include "usd_writer_abstract.h"
@@ -38,5 +37,3 @@ class USDHairWriter : public USDAbstractWriter {
} // namespace usd
} // namespace io
} // namespace blender
-
-#endif /* __USD_WRITER_HAIR_H__ */
diff --git a/source/blender/io/usd/intern/usd_writer_light.h b/source/blender/io/usd/intern/usd_writer_light.h
index 73666622af1..082050ad071 100644
--- a/source/blender/io/usd/intern/usd_writer_light.h
+++ b/source/blender/io/usd/intern/usd_writer_light.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
-#ifndef __USD_WRITER_LIGHT_H__
-#define __USD_WRITER_LIGHT_H__
+#pragma once
#include "usd_writer_abstract.h"
@@ -37,5 +36,3 @@ class USDLightWriter : public USDAbstractWriter {
} // namespace usd
} // namespace io
} // namespace blender
-
-#endif /* __USD_WRITER_LIGHT_H__ */
diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc
index 29a9734f876..bd2c549e729 100644
--- a/source/blender/io/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/io/usd/intern/usd_writer_mesh.cc
@@ -338,7 +338,7 @@ void USDGenericMeshWriter::assign_materials(const HierarchyContext &context,
* https://github.com/PixarAnimationStudios/USD/issues/542 for more info. */
bool mesh_material_bound = false;
pxr::UsdShadeMaterialBindingAPI material_binding_api(usd_mesh.GetPrim());
- for (short mat_num = 0; mat_num < context.object->totcol; mat_num++) {
+ for (int mat_num = 0; mat_num < context.object->totcol; mat_num++) {
Material *material = BKE_object_material_get(context.object, mat_num + 1);
if (material == nullptr) {
continue;
diff --git a/source/blender/io/usd/intern/usd_writer_mesh.h b/source/blender/io/usd/intern/usd_writer_mesh.h
index a14ceecfa53..078daa05501 100644
--- a/source/blender/io/usd/intern/usd_writer_mesh.h
+++ b/source/blender/io/usd/intern/usd_writer_mesh.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
-#ifndef __USD_WRITER_MESH_H__
-#define __USD_WRITER_MESH_H__
+#pragma once
#include "usd_writer_abstract.h"
@@ -66,5 +65,3 @@ class USDMeshWriter : public USDGenericMeshWriter {
} // namespace usd
} // namespace io
} // namespace blender
-
-#endif /* __USD_WRITER_MESH_H__ */
diff --git a/source/blender/io/usd/intern/usd_writer_metaball.h b/source/blender/io/usd/intern/usd_writer_metaball.h
index 9f51a3314a5..216f5a2638f 100644
--- a/source/blender/io/usd/intern/usd_writer_metaball.h
+++ b/source/blender/io/usd/intern/usd_writer_metaball.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2020 Blender Foundation.
* All rights reserved.
*/
-#ifndef __USD_WRITER_METABALL_H__
-#define __USD_WRITER_METABALL_H__
+#pragma once
#include "usd_writer_mesh.h"
@@ -42,5 +41,3 @@ class USDMetaballWriter : public USDGenericMeshWriter {
} // namespace usd
} // namespace io
} // namespace blender
-
-#endif /* __USD_WRITER_METABALL_H__ */
diff --git a/source/blender/io/usd/intern/usd_writer_transform.cc b/source/blender/io/usd/intern/usd_writer_transform.cc
index 643f1a8f4b1..49983115455 100644
--- a/source/blender/io/usd/intern/usd_writer_transform.cc
+++ b/source/blender/io/usd/intern/usd_writer_transform.cc
@@ -58,6 +58,9 @@ bool USDTransformWriter::check_is_animated(const HierarchyContext &context) cons
* depsgraph whether this object instance has a time source. */
return true;
}
+ if (check_has_physics(context)) {
+ return true;
+ }
return BKE_object_moves_in_time(context.object, context.animation_check_include_parent);
}
diff --git a/source/blender/io/usd/intern/usd_writer_transform.h b/source/blender/io/usd/intern/usd_writer_transform.h
index 8b4741f1177..39a1f20e7e8 100644
--- a/source/blender/io/usd/intern/usd_writer_transform.h
+++ b/source/blender/io/usd/intern/usd_writer_transform.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
-#ifndef __USD_WRITER_TRANSFORM_H__
-#define __USD_WRITER_TRANSFORM_H__
+#pragma once
#include "usd_writer_abstract.h"
@@ -42,5 +41,3 @@ class USDTransformWriter : public USDAbstractWriter {
} // namespace usd
} // namespace io
} // namespace blender
-
-#endif /* __USD_WRITER_TRANSFORM_H__ */
diff --git a/source/blender/io/usd/tests/usd_stage_creation_test.cc b/source/blender/io/usd/tests/usd_stage_creation_test.cc
new file mode 100644
index 00000000000..e6bd0bab6ce
--- /dev/null
+++ b/source/blender/io/usd/tests/usd_stage_creation_test.cc
@@ -0,0 +1,70 @@
+/*
+ * 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) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+#include "testing/testing.h"
+#include <pxr/usd/usd/stage.h>
+
+#include <string>
+
+#include "BLI_path_util.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_appdir.h"
+
+extern "C" {
+/* Workaround to make it possible to pass a path at runtime to USD. See creator.c. */
+void usd_initialise_plugin_path(const char *datafiles_usd_path);
+}
+
+namespace blender::io::usd {
+
+class USDStageCreationTest : public testing::Test {
+};
+
+TEST_F(USDStageCreationTest, JSONFileLoadingTest)
+{
+ const std::string &release_dir = blender::tests::flags_test_release_dir();
+ if (release_dir.empty()) {
+ FAIL();
+ }
+
+ char usd_datafiles_dir[FILE_MAX];
+ BLI_path_join(usd_datafiles_dir, FILE_MAX, release_dir.c_str(), "datafiles", "usd", nullptr);
+
+ usd_initialise_plugin_path(usd_datafiles_dir);
+
+ /* Simply the ability to create a USD Stage for a specific filename means that the extension
+ * has been recognized by the USD library, and that a USD plugin has been loaded to write such
+ * files. Practically, this is a test to see whether the USD JSON files can be found and
+ * loaded. */
+ std::string filename = "usd-stage-creation-test.usdc";
+ pxr::UsdStageRefPtr usd_stage = pxr::UsdStage::CreateNew(filename);
+ if (usd_stage != nullptr) {
+ /* Even though we don't call `usd_stage->SaveFile()`, a file is still created on the
+ * file-system when we call CreateNew(). It's immediately closed, though,
+ * so we can safely call `unlink()` here. */
+ unlink(filename.c_str());
+ }
+ else {
+ FAIL() << "unable to find suitable USD plugin to write " << filename
+ << "; re-run with the environment variable PXR_PATH_DEBUG non-empty to see which paths "
+ "are considered.";
+ }
+}
+
+} // namespace blender::io::usd
diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h
index eee98521289..f2826cd1d7c 100644
--- a/source/blender/io/usd/usd.h
+++ b/source/blender/io/usd/usd.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __USD_H__
-#define __USD_H__
+#pragma once
#include "DEG_depsgraph.h"
@@ -59,5 +58,3 @@ int USD_get_version(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __USD_H__ */
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 60cedfe3c8a..feda4ba43eb 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -22,8 +22,7 @@
* \brief ID and Library types, which are fundamental for sdna.
*/
-#ifndef __DNA_ID_H__
-#define __DNA_ID_H__
+#pragma once
#include "DNA_defs.h"
#include "DNA_listBase.h"
@@ -206,7 +205,10 @@ typedef struct IDOverrideLibraryProperty {
/** Runtime, tags are common to both IDOverrideProperty and IDOverridePropertyOperation. */
short tag;
- char _pad0[6];
+ char _pad[2];
+
+ /** The property type matching the rna_path. */
+ unsigned int rna_prop_type;
} IDOverrideLibraryProperty;
/* IDOverrideProperty->tag and IDOverridePropertyOperation->tag. */
@@ -215,8 +217,18 @@ enum {
IDOVERRIDE_LIBRARY_TAG_UNUSED = 1 << 0,
};
-/* We do not need a full struct for that currently, just a GHash. */
-typedef struct GHash IDOverrideLibraryRuntime;
+#
+#
+typedef struct IDOverrideLibraryRuntime {
+ struct GHash *rna_path_to_override_properties;
+ uint tag;
+} IDOverrideLibraryRuntime;
+
+/* IDOverrideLibraryRuntime->tag. */
+enum {
+ /** This override needs to be reloaded. */
+ IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD = 1 << 0,
+};
/* Main container for all overriding data info of a data-block. */
typedef struct IDOverrideLibrary {
@@ -468,7 +480,8 @@ typedef enum ID_Type {
/* Note that this is a fairly high-level check, should be used at user interaction level, not in
* BKE_library_override typically (especially due to the check on LIB_TAG_EXTERN). */
#define ID_IS_OVERRIDABLE_LIBRARY(_id) \
- (ID_IS_LINKED(_id) && !ID_MISSING(_id) && (((const ID *)(_id))->tag & LIB_TAG_EXTERN) != 0)
+ (ID_IS_LINKED(_id) && !ID_MISSING(_id) && (((const ID *)(_id))->tag & LIB_TAG_EXTERN) != 0 && \
+ (BKE_idtype_get_info_from_id((const ID *)(_id))->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0)
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id) \
(((const ID *)(_id))->override_library != NULL && \
@@ -806,5 +819,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index 98e858dbf41..6e590001aff 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -25,11 +25,11 @@
* or sequenced in the non-linear-editor (NLA).
*/
-#ifndef __DNA_ACTION_TYPES_H__
-#define __DNA_ACTION_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_listBase.h"
+#include "DNA_session_uuid_types.h"
#include "DNA_userdef_types.h" /* ThemeWireColor */
#include "DNA_vec_types.h"
#include "DNA_view2d_types.h"
@@ -188,6 +188,8 @@ struct DualQuat;
struct Mat4;
typedef struct bPoseChannel_Runtime {
+ SessionUUID session_uuid;
+
/* Cached dual quaternion for deformation. */
struct DualQuat deform_dual_quat;
@@ -953,5 +955,3 @@ typedef struct bActionChannel {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_ACTION_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 6a024ec9e7e..858daaac47c 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_ANIM_TYPES_H__
-#define __DNA_ANIM_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_action_types.h"
@@ -1141,5 +1140,3 @@ typedef struct IdAdtTemplate {
#ifdef __cplusplus
};
#endif
-
-#endif /* __DNA_ANIM_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index 635c155dec6..2e029d041ec 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_ARMATURE_TYPES_H__
-#define __DNA_ARMATURE_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -281,5 +280,3 @@ typedef enum eBone_BBoneHandleType {
} eBone_BBoneHandleType;
#define MAXBONENAME 64
-
-#endif
diff --git a/source/blender/makesdna/DNA_boid_types.h b/source/blender/makesdna/DNA_boid_types.h
index de93c734bb4..88b2c1e31b8 100644
--- a/source/blender/makesdna/DNA_boid_types.h
+++ b/source/blender/makesdna/DNA_boid_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_BOID_TYPES_H__
-#define __DNA_BOID_TYPES_H__
+#pragma once
#include "DNA_listBase.h"
@@ -223,5 +222,3 @@ typedef struct BoidSettings {
//#define BOID_RULE_LAND (1 << 3) /* goal */
//#define BOID_RULE_WITH_BOIDS (1 << 4) /* avoid collision */
//#define BOID_RULE_WITH_DEFLECTORS (1 << 5) /* avoid collision */
-
-#endif
diff --git a/source/blender/makesdna/DNA_brush_defaults.h b/source/blender/makesdna/DNA_brush_defaults.h
index 2ec4f4ee991..b0a35ac783e 100644
--- a/source/blender/makesdna/DNA_brush_defaults.h
+++ b/source/blender/makesdna/DNA_brush_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_BRUSH_DEFAULTS_H__
-#define __DNA_BRUSH_DEFAULTS_H__
+#pragma once
#include "DNA_texture_defaults.h"
@@ -116,5 +115,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_BRUSH_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 4056faf359f..c79ae68678f 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_BRUSH_TYPES_H__
-#define __DNA_BRUSH_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_curve_types.h"
@@ -67,7 +66,9 @@ typedef struct BrushGpencilSettings {
short draw_smoothlvl;
/** Number of times to subdivide new strokes. */
short draw_subdivide;
- char _pad[4];
+ /** Layers used for fill. */
+ short fill_layer_mode;
+ char _pad[2];
/** Factor for transparency. */
float fill_threshold;
@@ -118,7 +119,8 @@ typedef struct BrushGpencilSettings {
int sculpt_mode_flag;
/** Preset type (used to reset brushes - internal). */
short preset_type;
- char _pad3[2];
+ /** Brush preselected mode (Active/Material/Vertexcolor). */
+ short brush_draw_mode;
/** Randomness for Hue. */
float random_hue;
@@ -190,7 +192,7 @@ typedef enum eGPDbrush_Flag {
/* brush use pressure */
GP_BRUSH_USE_PRESSURE = (1 << 0),
/* brush use pressure for alpha factor */
- GP_BRUSH_USE_STENGTH_PRESSURE = (1 << 1),
+ GP_BRUSH_USE_STRENGTH_PRESSURE = (1 << 1),
/* brush use pressure for alpha factor */
GP_BRUSH_USE_JITTER_PRESSURE = (1 << 2),
/* fill hide transparent */
@@ -251,6 +253,16 @@ typedef enum eGP_FillDrawModes {
GP_FILL_DMODE_CONTROL = 2,
} eGP_FillDrawModes;
+/* BrushGpencilSettings->fill_layer_mode */
+typedef enum eGP_FillLayerModes {
+ GP_FILL_GPLMODE_VISIBLE = 0,
+ GP_FILL_GPLMODE_ACTIVE = 1,
+ GP_FILL_GPLMODE_ALL_ABOVE = 2,
+ GP_FILL_GPLMODE_ALL_BELOW = 3,
+ GP_FILL_GPLMODE_ABOVE = 4,
+ GP_FILL_GPLMODE_BELOW = 5,
+} eGP_FillLayerModes;
+
/* BrushGpencilSettings->gp_eraser_mode */
typedef enum eGP_BrushEraserMode {
GP_BRUSH_ERASER_SOFT = 0,
@@ -258,6 +270,13 @@ typedef enum eGP_BrushEraserMode {
GP_BRUSH_ERASER_STROKE = 2,
} eGP_BrushEraserMode;
+/* BrushGpencilSettings->brush_draw_mode */
+typedef enum eGP_BrushMode {
+ GP_BRUSH_MODE_ACTIVE = 0,
+ GP_BRUSH_MODE_MATERIAL = 1,
+ GP_BRUSH_MODE_VERTEXCOLOR = 2,
+} eGP_BrushMode;
+
/* BrushGpencilSettings default brush icons */
typedef enum eGP_BrushIcons {
GP_BRUSH_ICON_PENCIL = 1,
@@ -331,6 +350,11 @@ typedef enum eBrushClothForceFalloffType {
BRUSH_CLOTH_FORCE_FALLOFF_PLANE = 1,
} eBrushClothForceFalloffType;
+typedef enum eBrushClothSimulationAreaType {
+ BRUSH_CLOTH_SIMULATION_AREA_LOCAL = 0,
+ BRUSH_CLOTH_SIMULATION_AREA_GLOBAL = 1,
+} eBrushClothSimulationAreaType;
+
typedef enum eBrushPoseDeformType {
BRUSH_POSE_DEFORM_ROTATE_TWIST = 0,
BRUSH_POSE_DEFORM_SCALE_TRASLATE = 1,
@@ -343,6 +367,18 @@ typedef enum eBrushPoseOriginType {
BRUSH_POSE_ORIGIN_FACE_SETS_FK = 2,
} eBrushPoseOriginType;
+typedef enum eBrushSmearDeformType {
+ BRUSH_SMEAR_DEFORM_DRAG = 0,
+ BRUSH_SMEAR_DEFORM_PINCH = 1,
+ BRUSH_SMEAR_DEFORM_EXPAND = 2,
+} eBrushSmearDeformType;
+
+typedef enum eBrushSlideDeformType {
+ BRUSH_SLIDE_DEFORM_DRAG = 0,
+ BRUSH_SLIDE_DEFORM_PINCH = 1,
+ BRUSH_SLIDE_DEFORM_EXPAND = 2,
+} eBrushSlideDeformType;
+
/* Gpencilsettings.Vertex_mode */
typedef enum eGp_Vertex_Mode {
/* Affect to Stroke only. */
@@ -382,6 +418,19 @@ typedef enum eAutomasking_flag {
BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS = (1 << 3),
} eAutomasking_flag;
+typedef enum ePaintBrush_flag {
+ BRUSH_PAINT_HARDNESS_PRESSURE = (1 << 0),
+ BRUSH_PAINT_HARDNESS_PRESSURE_INVERT = (1 << 1),
+ BRUSH_PAINT_FLOW_PRESSURE = (1 << 2),
+ BRUSH_PAINT_FLOW_PRESSURE_INVERT = (1 << 3),
+ BRUSH_PAINT_WET_MIX_PRESSURE = (1 << 4),
+ BRUSH_PAINT_WET_MIX_PRESSURE_INVERT = (1 << 5),
+ BRUSH_PAINT_WET_PERSISTENCE_PRESSURE = (1 << 6),
+ BRUSH_PAINT_WET_PERSISTENCE_PRESSURE_INVERT = (1 << 7),
+ BRUSH_PAINT_DENSITY_PRESSURE = (1 << 8),
+ BRUSH_PAINT_DENSITY_PRESSURE_INVERT = (1 << 9),
+} ePaintBrush_flag;
+
typedef struct Brush {
ID id;
@@ -448,6 +497,7 @@ typedef struct Brush {
float wet_persistence;
/** Density */
float density;
+ int paint_flags;
/** Tip Shape */
/* Factor that controls the shape of the brush tip by rounding the corners of a square. */
@@ -474,7 +524,7 @@ typedef struct Brush {
/** Source for fill tool color gradient application. */
char gradient_fill_mode;
- char _pad0[1];
+ char _pad0[5];
/** Projection shape (sphere, circle). */
char falloff_shape;
@@ -539,6 +589,7 @@ typedef struct Brush {
/* cloth */
int cloth_deform_type;
int cloth_force_falloff_type;
+ int cloth_simulation_area_type;
float cloth_mass;
float cloth_damping;
@@ -546,6 +597,8 @@ typedef struct Brush {
float cloth_sim_limit;
float cloth_sim_falloff;
+ float cloth_constraint_softbody_strength;
+
/* smooth */
int smooth_deform_type;
float surface_smooth_shape_preservation;
@@ -555,6 +608,12 @@ typedef struct Brush {
/* multiplane scrape */
float multiplane_scrape_angle;
+ /* smear */
+ int smear_deform_type;
+
+ /* slide/relax */
+ int slide_deform_type;
+
/* overlay */
int texture_overlay_alpha;
int mask_overlay_alpha;
@@ -684,6 +743,9 @@ typedef enum eBrushFlags2 {
BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW = (1 << 1),
BRUSH_POSE_IK_ANCHORED = (1 << 2),
BRUSH_USE_CONNECTED_ONLY = (1 << 3),
+ BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY = (1 << 4),
+ BRUSH_POSE_USE_LOCK_ROTATION = (1 << 5),
+ BRUSH_CLOTH_USE_COLLISION = (1 << 6),
} eBrushFlags2;
typedef enum {
@@ -883,5 +945,3 @@ enum {
#define MAX_BRUSH_PIXEL_RADIUS 500
#define GP_MAX_BRUSH_PIXEL_RADIUS 1000
-
-#endif /* __DNA_BRUSH_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_cachefile_defaults.h b/source/blender/makesdna/DNA_cachefile_defaults.h
index 4c4ff53ed90..d37994bb488 100644
--- a/source/blender/makesdna/DNA_cachefile_defaults.h
+++ b/source/blender/makesdna/DNA_cachefile_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_CACHEFILE_DEFAULTS_H__
-#define __DNA_CACHEFILE_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -45,5 +44,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_CACHEFILE_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_cachefile_types.h b/source/blender/makesdna/DNA_cachefile_types.h
index 1175c7f0dc0..04c99c6c4b1 100644
--- a/source/blender/makesdna/DNA_cachefile_types.h
+++ b/source/blender/makesdna/DNA_cachefile_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_CACHEFILE_TYPES_H__
-#define __DNA_CACHEFILE_TYPES_H__
+#pragma once
#include "DNA_ID.h"
@@ -53,6 +52,13 @@ typedef struct AlembicObjectPath {
char path[4096];
} AlembicObjectPath;
+/* CacheFile::velocity_unit
+ * Determines what temporal unit is used to interpret velocity vectors for motion blur effects. */
+enum {
+ CACHEFILE_VELOCITY_UNIT_FRAME,
+ CACHEFILE_VELOCITY_UNIT_SECOND,
+};
+
typedef struct CacheFile {
ID id;
struct AnimData *adt;
@@ -78,7 +84,11 @@ typedef struct CacheFile {
short flag;
short draw_flag; /* UNUSED */
- char _pad[4];
+ char _pad[3];
+
+ char velocity_unit;
+ /* Name of the velocity property in the Alembic file. */
+ char velocity_name[64];
/* Runtime */
struct AbcArchiveHandle *handle;
@@ -89,5 +99,3 @@ typedef struct CacheFile {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_CACHEFILE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_camera_defaults.h b/source/blender/makesdna/DNA_camera_defaults.h
index 7a28f673ee4..55fbb59a161 100644
--- a/source/blender/makesdna/DNA_camera_defaults.h
+++ b/source/blender/makesdna/DNA_camera_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_CAMERA_DEFAULTS_H__
-#define __DNA_CAMERA_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -63,5 +62,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_CAMERA_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h
index b12d25d74e0..73a55edf05f 100644
--- a/source/blender/makesdna/DNA_camera_types.h
+++ b/source/blender/makesdna/DNA_camera_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_CAMERA_TYPES_H__
-#define __DNA_CAMERA_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -226,5 +225,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 9d9ee711339..bc6991b3249 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_CLOTH_TYPES_H__
-#define __DNA_CLOTH_TYPES_H__
+#pragma once
#include "DNA_defs.h"
@@ -210,5 +209,3 @@ typedef struct ClothCollSettings {
/** Impulse clamp for self collisions. */
float self_clamp;
} ClothCollSettings;
-
-#endif
diff --git a/source/blender/makesdna/DNA_collection_types.h b/source/blender/makesdna/DNA_collection_types.h
index 13eb8a762d9..6cf02137fa6 100644
--- a/source/blender/makesdna/DNA_collection_types.h
+++ b/source/blender/makesdna/DNA_collection_types.h
@@ -23,8 +23,7 @@
* \brief Object groups, one object can be in many groups at once.
*/
-#ifndef __DNA_COLLECTION_TYPES_H__
-#define __DNA_COLLECTION_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -93,5 +92,3 @@ enum {
* Using a generic tag like LIB_TAG_DOIT for this is just impossible, we need our very own. */
COLLECTION_TAG_RELATION_REBUILD = (1 << 0),
};
-
-#endif /* __DNA_COLLECTION_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h
index 66adc547cf2..5577a17c0df 100644
--- a/source/blender/makesdna/DNA_color_types.h
+++ b/source/blender/makesdna/DNA_color_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_COLOR_TYPES_H__
-#define __DNA_COLOR_TYPES_H__
+#pragma once
#include "DNA_defs.h"
#include "DNA_vec_types.h"
@@ -215,5 +214,3 @@ typedef struct ColorManagedColorspaceSettings {
enum {
COLORMANAGE_VIEW_USE_CURVES = (1 << 0),
};
-
-#endif
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 85d9a04a902..cddc78d7640 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -22,8 +22,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_CONSTRAINT_TYPES_H__
-#define __DNA_CONSTRAINT_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -1168,5 +1167,3 @@ typedef enum eStretchTo_Flags {
#define CONSTRAINT_RB_CONETWIST 4
#define CONSTRAINT_RB_VEHICLE 11
#define CONSTRAINT_RB_GENERIC6DOF 12
-
-#endif
diff --git a/source/blender/makesdna/DNA_curve_defaults.h b/source/blender/makesdna/DNA_curve_defaults.h
index 0fdfd5713e9..0cb3960dbd7 100644
--- a/source/blender/makesdna/DNA_curve_defaults.h
+++ b/source/blender/makesdna/DNA_curve_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_CURVE_DEFAULTS_H__
-#define __DNA_CURVE_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -55,5 +54,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_CURVE_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index b2902407a15..2ae9ba13177 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_CURVE_TYPES_H__
-#define __DNA_CURVE_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -274,9 +273,12 @@ typedef struct Curve {
int selstart, selend;
/* text data */
- /** Number of characters (strinfo). */
- int len_wchar;
- /** Number of bytes (str - utf8). */
+ /**
+ * Number of characters (unicode code-points)
+ * This is the length of #Curve.strinfo and the result of `BLI_strlen_utf8(cu->str)`.
+ */
+ int len_char32;
+ /** Number of bytes: `strlen(Curve.str)`. */
int len;
char *str;
struct EditFont *editfont;
@@ -544,5 +546,3 @@ enum {
/* indicates point has been seen during surface duplication */
#define SURF_SEEN 4
-
-#endif
diff --git a/source/blender/makesdna/DNA_curveprofile_types.h b/source/blender/makesdna/DNA_curveprofile_types.h
index ca00f783905..5b425741df2 100644
--- a/source/blender/makesdna/DNA_curveprofile_types.h
+++ b/source/blender/makesdna/DNA_curveprofile_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_CURVEPROFILE_TYPES_H__
-#define __DNA_CURVEPROFILE_TYPES_H__
+#pragma once
#include "DNA_vec_types.h"
@@ -31,7 +30,7 @@
/** Number of table points per control point. */
#define PROF_RESOL 16
/** Dynamic size of widget's high resolution table. Input should be profile->totpoint. */
-#define PROF_N_TABLE(n_pts) min_ii(PROF_TABLE_MAX, (((n_pts - 1)) * PROF_RESOL) + 1)
+#define PROF_TABLE_LEN(n_pts) min_ii(PROF_TABLE_MAX, (((n_pts - 1)) * PROF_RESOL) + 1)
/**
* Each control point that makes up the profile.
@@ -99,5 +98,3 @@ typedef enum eCurveProfilePresets {
PROF_PRESET_CROWN = 3, /* Second molding example. */
PROF_PRESET_STEPS = 4, /* Dynamic number of steps defined by segments_len. */
} eCurveProfilePresets;
-
-#endif /* __DNA_CURVEPROFILE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index c24bbccae1e..2990fa85c27 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -23,8 +23,7 @@
* Used for custom mesh data types (stored per vert/edge/loop/face)
*/
-#ifndef __DNA_CUSTOMDATA_TYPES_H__
-#define __DNA_CUSTOMDATA_TYPES_H__
+#pragma once
#include "DNA_defs.h"
@@ -76,7 +75,7 @@ typedef struct CustomData {
* MUST be >= CD_NUMTYPES, but we cant use a define here.
* Correct size is ensured in CustomData_update_typemap assert().
*/
- int typemap[48];
+ int typemap[50];
char _pad[4];
/** Number of layers, size of layers array. */
int totlayer, maxlayer;
@@ -154,8 +153,10 @@ typedef enum CustomDataType {
CD_HAIRMAPPING = 46,
CD_PROP_COLOR = 47,
+ CD_PROP_FLOAT3 = 48,
+ CD_PROP_FLOAT2 = 49,
- CD_NUMTYPES = 48,
+ CD_NUMTYPES = 50,
} CustomDataType;
/* Bits for CustomDataMask */
@@ -205,9 +206,13 @@ typedef enum CustomDataType {
#define CD_MASK_CUSTOMLOOPNORMAL (1LL << CD_CUSTOMLOOPNORMAL)
#define CD_MASK_SCULPT_FACE_SETS (1LL << CD_SCULPT_FACE_SETS)
#define CD_MASK_PROP_COLOR (1ULL << CD_PROP_COLOR)
+#define CD_MASK_PROP_FLOAT3 (1ULL << CD_PROP_FLOAT3)
+#define CD_MASK_PROP_FLOAT2 (1ULL << CD_PROP_FLOAT2)
/** Data types that may be defined for all mesh elements types. */
-#define CD_MASK_GENERIC_DATA (CD_MASK_PROP_FLOAT | CD_MASK_PROP_INT32 | CD_MASK_PROP_STRING)
+#define CD_MASK_GENERIC_DATA \
+ (CD_MASK_PROP_FLOAT | CD_MASK_PROP_INT32 | CD_MASK_PROP_STRING | CD_MASK_PROP_FLOAT3 | \
+ CD_MASK_PROP_FLOAT2)
/** Multires loop data. */
#define CD_MASK_MULTIRES_GRIDS (CD_MASK_MDISPS | CD_GRID_PAINT_MASK)
@@ -248,5 +253,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_CUSTOMDATA_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_defaults.h b/source/blender/makesdna/DNA_defaults.h
index ca5ac649e33..1549e33b267 100644
--- a/source/blender/makesdna/DNA_defaults.h
+++ b/source/blender/makesdna/DNA_defaults.h
@@ -24,8 +24,7 @@
* \see dna_defaults.c for details on how to use this system.
*/
-#ifndef __DNA_DEFAULTS_H__
-#define __DNA_DEFAULTS_H__
+#pragma once
#include "BLI_utildefines.h"
@@ -52,5 +51,3 @@ char *_DNA_struct_default_alloc_impl(const char *data_src, size_t size, const ch
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_defs.h b/source/blender/makesdna/DNA_defs.h
index 092dd9d3bcc..01ee954d0d2 100644
--- a/source/blender/makesdna/DNA_defs.h
+++ b/source/blender/makesdna/DNA_defs.h
@@ -20,8 +20,7 @@
* Group generic defines for all DNA headers may use in this file.
*/
-#ifndef __DNA_DEFS_H__
-#define __DNA_DEFS_H__
+#pragma once
/* makesdna ignores */
#ifdef DNA_DEPRECATED_ALLOW
@@ -61,5 +60,3 @@
/* non-id name variables should use this length */
#define MAX_NAME 64
-
-#endif /* __DNA_DEFS_H__ */
diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h
index c97e68a6a6b..94f54a0d200 100644
--- a/source/blender/makesdna/DNA_dynamicpaint_types.h
+++ b/source/blender/makesdna/DNA_dynamicpaint_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_DYNAMICPAINT_TYPES_H__
-#define __DNA_DYNAMICPAINT_TYPES_H__
+#pragma once
#include "DNA_listBase.h"
struct PaintSurfaceData;
@@ -262,5 +261,3 @@ typedef struct DynamicPaintBrushSettings {
float wave_factor, wave_clamp;
float max_velocity, smudge_strength;
} DynamicPaintBrushSettings;
-
-#endif
diff --git a/source/blender/makesdna/DNA_effect_types.h b/source/blender/makesdna/DNA_effect_types.h
index c34b146064e..c25e9d0dded 100644
--- a/source/blender/makesdna/DNA_effect_types.h
+++ b/source/blender/makesdna/DNA_effect_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_EFFECT_TYPES_H__
-#define __DNA_EFFECT_TYPES_H__
+#pragma once
/* don't forget, new effects also in writefile.c for dna!!! */
@@ -130,5 +129,3 @@ typedef struct WaveEff {
float timeoffs, lifetime;
} WaveEff;
-
-#endif
diff --git a/source/blender/makesdna/DNA_fileglobal_types.h b/source/blender/makesdna/DNA_fileglobal_types.h
index 66f185282a9..bb660fb8eaa 100644
--- a/source/blender/makesdna/DNA_fileglobal_types.h
+++ b/source/blender/makesdna/DNA_fileglobal_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_FILEGLOBAL_TYPES_H__
-#define __DNA_FILEGLOBAL_TYPES_H__
+#pragma once
/**
* FileGlobal stores a part of the current user-interface settings at
@@ -54,5 +53,3 @@ typedef struct FileGlobal {
/* example: if in 2.43 the meshes lose mesh data, minversion is 2.43 then too */
/* or: in 2.42, subversion 1, same as above, minversion then is 2.42, min subversion 1 */
/* (defines for version are in the BKE_blender_version.h file, for historic reasons) */
-
-#endif
diff --git a/source/blender/makesdna/DNA_fluid_types.h b/source/blender/makesdna/DNA_fluid_types.h
index b54ff7ccc17..3bbfb1dd0c4 100644
--- a/source/blender/makesdna/DNA_fluid_types.h
+++ b/source/blender/makesdna/DNA_fluid_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_FLUID_TYPES_H__
-#define __DNA_FLUID_TYPES_H__
+#pragma once
#include "DNA_listBase.h"
@@ -471,9 +470,10 @@ typedef struct FluidDomainSettings {
int res_max[3]; /* Cell max. */
int res[3]; /* Data resolution (res_max-res_min). */
int total_cells;
- float dx; /* 1.0f / res. */
- float scale; /* Largest domain size. */
- int boundary_width; /* Usually this is just 1. */
+ float dx; /* 1.0f / res. */
+ float scale; /* Largest domain size. */
+ int boundary_width; /* Usually this is just 1. */
+ float gravity_final[3]; /* Scene or domain gravity multiplied with gravity weight. */
/* -- User-accesible fields (from here on). -- */
@@ -481,7 +481,6 @@ typedef struct FluidDomainSettings {
int adapt_margin;
int adapt_res;
float adapt_threshold;
- char _pad1[4]; /* Unused. */
/* Fluid domain options */
int maxres; /* Longest axis on the BB gets this resolution assigned. */
@@ -524,8 +523,9 @@ typedef struct FluidDomainSettings {
float particle_band_width;
float fractions_threshold;
float flip_ratio;
+ int sys_particle_maximum;
short simulation_method;
- char _pad4[6];
+ char _pad4[2];
/* Diffusion options. */
float surface_tension;
@@ -783,5 +783,3 @@ typedef struct FluidEffectorSettings {
short guide_mode;
char _pad2[2];
} FluidEffectorSettings;
-
-#endif
diff --git a/source/blender/makesdna/DNA_freestyle_types.h b/source/blender/makesdna/DNA_freestyle_types.h
index 8b3d8090c89..884e11f3a8e 100644
--- a/source/blender/makesdna/DNA_freestyle_types.h
+++ b/source/blender/makesdna/DNA_freestyle_types.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __DNA_FREESTYLE_TYPES_H__
-#define __DNA_FREESTYLE_TYPES_H__
+#pragma once
/** \file
* \ingroup DNA
@@ -155,5 +154,3 @@ typedef struct FreestyleConfig {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_FREESTYLE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_genfile.h b/source/blender/makesdna/DNA_genfile.h
index db65da6fa75..1cdaba81ffa 100644
--- a/source/blender/makesdna/DNA_genfile.h
+++ b/source/blender/makesdna/DNA_genfile.h
@@ -22,13 +22,16 @@
* \brief blenloader genfile private function prototypes
*/
-#ifndef __DNA_GENFILE_H__
-#define __DNA_GENFILE_H__
+#pragma once
#include "intern/dna_utils.h"
struct SDNA;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* DNAstr contains the prebuilt SDNA structure defining the layouts of the types
* used by this version of Blender. It is defined in a file dna.c, which is
@@ -134,4 +137,6 @@ bool DNA_struct_alias_elem_find(const struct SDNA *sdna,
const char *name);
void DNA_sdna_alias_data_ensure_structs_map(struct SDNA *sdna);
-#endif /* __DNA_GENFILE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index 5d35db1a960..3049c0f8bab 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_GPENCIL_MODIFIER_TYPES_H__
-#define __DNA_GPENCIL_MODIFIER_TYPES_H__
+#pragma once
#include "DNA_defs.h"
#include "DNA_listBase.h"
@@ -800,5 +799,3 @@ typedef enum eTextureGpencil_Mode {
FILL = 1,
STROKE_AND_FILL = 2,
} eTextureGpencil_Mode;
-
-#endif /* __DNA_GPENCIL_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index b6e2910a1b0..222b716a502 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_GPENCIL_TYPES_H__
-#define __DNA_GPENCIL_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_brush_types.h"
@@ -756,5 +755,3 @@ typedef enum eGP_DrawMode {
#define GPENCIL_ANY_VERTEX_MASK(flag) \
((flag & (GP_VERTEX_MASK_SELECTMODE_POINT | GP_VERTEX_MASK_SELECTMODE_STROKE | \
GP_VERTEX_MASK_SELECTMODE_SEGMENT)))
-
-#endif /* __DNA_GPENCIL_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_gpu_types.h b/source/blender/makesdna/DNA_gpu_types.h
index 7d56baf86a4..b1ace1bda49 100644
--- a/source/blender/makesdna/DNA_gpu_types.h
+++ b/source/blender/makesdna/DNA_gpu_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_GPU_TYPES_H__
-#define __DNA_GPU_TYPES_H__
+#pragma once
/* Keep for 'Camera' versioning. */
/** Properties for dof effect. */
@@ -37,5 +36,3 @@ typedef struct GPUDOFSettings {
int num_blades;
int high_quality;
} GPUDOFSettings;
-
-#endif /* __DNA_GPU_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_hair_defaults.h b/source/blender/makesdna/DNA_hair_defaults.h
index de7a830885d..095e4fdf583 100644
--- a/source/blender/makesdna/DNA_hair_defaults.h
+++ b/source/blender/makesdna/DNA_hair_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_HAIR_DEFAULTS_H__
-#define __DNA_HAIR_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -36,5 +35,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_HAIR_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_hair_types.h b/source/blender/makesdna/DNA_hair_types.h
index 98fae91dbe1..d120e61cfef 100644
--- a/source/blender/makesdna/DNA_hair_types.h
+++ b/source/blender/makesdna/DNA_hair_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_HAIR_TYPES_H__
-#define __DNA_HAIR_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_customdata_types.h"
@@ -74,5 +73,3 @@ enum {
/* Only one material supported currently. */
#define HAIR_MATERIAL_NR 1
-
-#endif /* __DNA_HAIR_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_image_defaults.h b/source/blender/makesdna/DNA_image_defaults.h
index e115f9e2b16..ce1296d681f 100644
--- a/source/blender/makesdna/DNA_image_defaults.h
+++ b/source/blender/makesdna/DNA_image_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_IMAGE_DEFAULTS_H__
-#define __DNA_IMAGE_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -42,5 +41,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_IMAGE_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 0ffb6c8a76a..749bc55fcb9 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_IMAGE_TYPES_H__
-#define __DNA_IMAGE_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_color_types.h" /* for color management */
@@ -117,13 +116,13 @@ typedef struct ImageTile {
#define IMA_NEED_FRAME_RECALC (1 << 3)
#define IMA_SHOW_STEREO (1 << 4)
-enum {
- TEXTARGET_TEXTURE_2D = 0,
- TEXTARGET_TEXTURE_CUBE_MAP = 1,
- TEXTARGET_TEXTURE_2D_ARRAY = 2,
- TEXTARGET_TEXTURE_TILE_MAPPING = 3,
- TEXTARGET_COUNT = 4,
-};
+/* Used to get the correct gpu texture from an Image datablock. */
+typedef enum eGPUTextureTarget {
+ TEXTARGET_2D = 0,
+ TEXTARGET_2D_ARRAY,
+ TEXTARGET_TILE_MAPPING,
+ TEXTARGET_COUNT,
+} eGPUTextureTarget;
typedef struct Image {
ID id;
@@ -133,8 +132,8 @@ typedef struct Image {
/** Not written in file. */
struct MovieCache *cache;
- /** Not written in file 4 = TEXTARGET_COUNT, 2 = stereo eyes. */
- struct GPUTexture *gputexture[4][2];
+ /** Not written in file 3 = TEXTARGET_COUNT, 2 = stereo eyes. */
+ struct GPUTexture *gputexture[3][2];
/* sources from: */
ListBase anims;
@@ -265,5 +264,3 @@ enum {
IMA_ALPHA_CHANNEL_PACKED = 2,
IMA_ALPHA_IGNORE = 3,
};
-
-#endif
diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h
index 0f1028f5770..dfd06702b72 100644
--- a/source/blender/makesdna/DNA_ipo_types.h
+++ b/source/blender/makesdna/DNA_ipo_types.h
@@ -26,8 +26,7 @@
* All defines, etc. are only still maintained to provide backwards compatibility for old files.
*/
-#ifndef __DNA_IPO_TYPES_H__
-#define __DNA_IPO_TYPES_H__
+#pragma once
#include "DNA_curve_types.h"
#include "DNA_listBase.h"
@@ -517,5 +516,3 @@ typedef struct Ipo {
/* driver->flag */
/* invalid flag: currently only used for buggy pydriver expressions */
#define IPO_DRIVER_FLAG_INVALID (1 << 0)
-
-#endif
diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h
index a1cc6f89314..56a164e4f2c 100644
--- a/source/blender/makesdna/DNA_key_types.h
+++ b/source/blender/makesdna/DNA_key_types.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*/
-#ifndef __DNA_KEY_TYPES_H__
-#define __DNA_KEY_TYPES_H__
+#pragma once
/** \file
* \ingroup DNA
@@ -159,5 +158,3 @@ enum {
#define KEYELEM_ELEM_LEN_BEZTRIPLE 4
#define KEYELEM_FLOAT_LEN_BEZTRIPLE (KEYELEM_ELEM_LEN_BEZTRIPLE * KEYELEM_ELEM_SIZE_CURVE)
-
-#endif /* __DNA_KEY_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_lattice_defaults.h b/source/blender/makesdna/DNA_lattice_defaults.h
index 052aaba51d7..505b853b0ee 100644
--- a/source/blender/makesdna/DNA_lattice_defaults.h
+++ b/source/blender/makesdna/DNA_lattice_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_LATTICE_DEFAULTS_H__
-#define __DNA_LATTICE_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -40,5 +39,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_LATTICE_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_lattice_types.h b/source/blender/makesdna/DNA_lattice_types.h
index 336726fb28d..797df3bd738 100644
--- a/source/blender/makesdna/DNA_lattice_types.h
+++ b/source/blender/makesdna/DNA_lattice_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_LATTICE_TYPES_H__
-#define __DNA_LATTICE_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -83,5 +82,3 @@ typedef struct Lattice {
#define LT_DS_EXPAND 4
#define LT_ACTBP_NONE -1
-
-#endif
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 6348dc5f03d..3c2d479bea4 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_LAYER_TYPES_H__
-#define __DNA_LAYER_TYPES_H__
+#pragma once
#include "DNA_freestyle_types.h"
#include "DNA_listBase.h"
@@ -115,7 +114,6 @@ typedef struct ViewLayer {
ListBase object_bases;
/** Default allocated now. */
struct SceneStats *stats;
- char footer_str[128];
struct Base *basact;
/** A view layer has one top level layer collection, because a scene has only one top level
@@ -217,5 +215,3 @@ typedef struct SceneCollection {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_LAYER_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_light_defaults.h b/source/blender/makesdna/DNA_light_defaults.h
index dceaaf7c278..6ac52c1b356 100644
--- a/source/blender/makesdna/DNA_light_defaults.h
+++ b/source/blender/makesdna/DNA_light_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_LIGHT_DEFAULTS_H__
-#define __DNA_LIGHT_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -72,5 +71,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_LIGHT_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_light_types.h b/source/blender/makesdna/DNA_light_types.h
index 7a7b5d923e3..1616cf949bd 100644
--- a/source/blender/makesdna/DNA_light_types.h
+++ b/source/blender/makesdna/DNA_light_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_LIGHT_TYPES_H__
-#define __DNA_LIGHT_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -155,5 +154,3 @@ typedef struct Light {
/* #define LA_AREA_BOX 3 */ /* UNUSED */
#define LA_AREA_DISK 4
#define LA_AREA_ELLIPSE 5
-
-#endif /* __DNA_LIGHT_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_lightprobe_defaults.h b/source/blender/makesdna/DNA_lightprobe_defaults.h
index 7c7732d17e4..4de94b81b97 100644
--- a/source/blender/makesdna/DNA_lightprobe_defaults.h
+++ b/source/blender/makesdna/DNA_lightprobe_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_LIGHTPROBE_DEFAULTS_H__
-#define __DNA_LIGHTPROBE_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -47,5 +46,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_LIGHTPROBE_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_lightprobe_types.h b/source/blender/makesdna/DNA_lightprobe_types.h
index 5ddfedfed2d..3830919bfd3 100644
--- a/source/blender/makesdna/DNA_lightprobe_types.h
+++ b/source/blender/makesdna/DNA_lightprobe_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_LIGHTPROBE_TYPES_H__
-#define __DNA_LIGHTPROBE_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -150,7 +149,7 @@ BLI_STATIC_ASSERT_ALIGN(LightGridCache, 16)
typedef struct LightCacheTexture {
struct GPUTexture *tex;
- /* Copy of GPU datas to create GPUTextures on file read. */
+ /** Copy of GPU datas to create GPUTextures on file read. */
char *data;
int tex_size[3];
char data_type;
@@ -204,6 +203,10 @@ enum {
LIGHTCACHE_UPDATE_GRID = (1 << 5),
LIGHTCACHE_UPDATE_WORLD = (1 << 6),
LIGHTCACHE_UPDATE_AUTO = (1 << 7),
+ /** Invalid means we tried to alloc it but failed. */
+ LIGHTCACHE_INVALID = (1 << 8),
+ /** The data present in the cache is valid but unusable on this GPU. */
+ LIGHTCACHE_NOT_USABLE = (1 << 9),
};
/* EEVEE_LightCacheTexture->data_type */
@@ -216,5 +219,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_LIGHTPROBE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_linestyle_defaults.h b/source/blender/makesdna/DNA_linestyle_defaults.h
index 2f9203050d1..47405b4a15f 100644
--- a/source/blender/makesdna/DNA_linestyle_defaults.h
+++ b/source/blender/makesdna/DNA_linestyle_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_LINESTYLE_DEFAULTS_H__
-#define __DNA_LINESTYLE_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -57,5 +56,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_LINESTYLE_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_linestyle_types.h b/source/blender/makesdna/DNA_linestyle_types.h
index eca5ab5e8ec..867f0995ae9 100644
--- a/source/blender/makesdna/DNA_linestyle_types.h
+++ b/source/blender/makesdna/DNA_linestyle_types.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __DNA_LINESTYLE_TYPES_H__
-#define __DNA_LINESTYLE_TYPES_H__
+#pragma once
/** \file
* \ingroup DNA
@@ -576,5 +575,3 @@ typedef struct FreestyleLineStyle {
ListBase thickness_modifiers;
ListBase geometry_modifiers;
} FreestyleLineStyle;
-
-#endif
diff --git a/source/blender/makesdna/DNA_listBase.h b/source/blender/makesdna/DNA_listBase.h
index 7d247c99387..0c4054004ea 100644
--- a/source/blender/makesdna/DNA_listBase.h
+++ b/source/blender/makesdna/DNA_listBase.h
@@ -25,8 +25,7 @@
* with Link.
*/
-#ifndef __DNA_LISTBASE_H__
-#define __DNA_LISTBASE_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -53,5 +52,3 @@ typedef struct ListBase {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h
index 9617b3fdf27..5f232036f2a 100644
--- a/source/blender/makesdna/DNA_mask_types.h
+++ b/source/blender/makesdna/DNA_mask_types.h
@@ -24,8 +24,7 @@
* for image masking in the compositor and sequencer.
*/
-#ifndef __DNA_MASK_TYPES_H__
-#define __DNA_MASK_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_curve_types.h"
@@ -264,5 +263,3 @@ enum {
enum {
MASK_ANIMF_EXPAND = (1 << 4),
};
-
-#endif /* __DNA_MASK_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_material_defaults.h b/source/blender/makesdna/DNA_material_defaults.h
index cdcb1dd45f7..3f4496ce735 100644
--- a/source/blender/makesdna/DNA_material_defaults.h
+++ b/source/blender/makesdna/DNA_material_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_MATERIAL_DEFAULTS_H__
-#define __DNA_MATERIAL_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -51,5 +50,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_MATERIAL_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 6a4ec65318b..3d050805f12 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_MATERIAL_TYPES_H__
-#define __DNA_MATERIAL_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -355,4 +354,3 @@ enum {
GP_MATERIAL_FOLLOW_OBJ = 1,
GP_MATERIAL_FOLLOW_FIXED = 2,
};
-#endif
diff --git a/source/blender/makesdna/DNA_mesh_defaults.h b/source/blender/makesdna/DNA_mesh_defaults.h
index abcdf8bf57b..8326db66049 100644
--- a/source/blender/makesdna/DNA_mesh_defaults.h
+++ b/source/blender/makesdna/DNA_mesh_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_MESH_DEFAULTS_H__
-#define __DNA_MESH_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -43,5 +42,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_MESH_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index 9435cb3bd78..3816cee0cf8 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_MESH_TYPES_H__
-#define __DNA_MESH_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_customdata_types.h"
@@ -320,5 +319,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index cc2ba3fb999..57750b15dea 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_MESHDATA_TYPES_H__
-#define __DNA_MESHDATA_TYPES_H__
+#pragma once
#include "DNA_customdata_types.h"
#include "DNA_listBase.h"
@@ -570,5 +569,3 @@ typedef struct Multires {
/* End multi-res structs. */
/** \} */
-
-#endif /* __DNA_MESHDATA_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_meta_defaults.h b/source/blender/makesdna/DNA_meta_defaults.h
index 723f178ed58..1bf2caf556d 100644
--- a/source/blender/makesdna/DNA_meta_defaults.h
+++ b/source/blender/makesdna/DNA_meta_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_META_DEFAULTS_H__
-#define __DNA_META_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -40,5 +39,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_META_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h
index df4558dac77..de7427bc4dd 100644
--- a/source/blender/makesdna/DNA_meta_types.h
+++ b/source/blender/makesdna/DNA_meta_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_META_TYPES_H__
-#define __DNA_META_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -139,5 +138,3 @@ typedef struct MetaBall {
#define MB_NEGATIVE 2
#define MB_HIDE 8
#define MB_SCALE_RAD 16
-
-#endif
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 60ad0eae576..b01b3f42e6a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_MODIFIER_TYPES_H__
-#define __DNA_MODIFIER_TYPES_H__
+#pragma once
#include "DNA_defs.h"
#include "DNA_listBase.h"
@@ -155,6 +154,7 @@ typedef enum {
/* DEPRECATED, ONLY USED FOR DO-VERSIONS */
eSubsurfModifierFlag_SubsurfUv_DEPRECATED = (1 << 3),
eSubsurfModifierFlag_UseCrease = (1 << 4),
+ eSubsurfModifierFlag_UseCustomNormals = (1 << 5),
} SubsurfModifierFlag;
typedef enum {
@@ -409,7 +409,9 @@ typedef struct BevelModifierData {
short miter_outer;
/** The method to use for creating >2-way intersections */
short vmesh_method;
- char _pad0[2];
+ /** Whether to affect vertices or edges. */
+ char affect_type;
+ char _pad;
/** Controls profile shape (0->1, .5 is round). */
float profile;
/** if the MOD_BEVEL_ANGLE is set,
@@ -428,7 +430,9 @@ typedef struct BevelModifierData {
/* BevelModifierData->flags and BevelModifierData->lim_flags */
enum {
- MOD_BEVEL_VERT = (1 << 1),
+#ifdef DNA_DEPRECATED_ALLOW
+ MOD_BEVEL_VERT_DEPRECATED = (1 << 1),
+#endif
MOD_BEVEL_INVERT_VGROUP = (1 << 2),
MOD_BEVEL_ANGLE = (1 << 3),
MOD_BEVEL_WEIGHT = (1 << 4),
@@ -489,6 +493,12 @@ enum {
MOD_BEVEL_VMESH_CUTOFF = 1,
};
+/* BevelModifier->affect_type */
+enum {
+ MOD_BEVEL_AFFECT_VERTICES = 0,
+ MOD_BEVEL_AFFECT_EDGES = 1,
+};
+
typedef struct FluidModifierData {
ModifierData modifier;
@@ -1016,6 +1026,7 @@ typedef enum {
/* DEPRECATED, only used for versioning. */
eMultiresModifierFlag_PlainUv_DEPRECATED = (1 << 1),
eMultiresModifierFlag_UseCrease = (1 << 2),
+ eMultiresModifierFlag_UseCustomNormals = (1 << 3),
} MultiresModifierFlag;
/* DEPRECATED, only used for versioning. */
@@ -1265,7 +1276,11 @@ typedef struct OceanModifierData {
struct Ocean *ocean;
struct OceanCache *oceancache;
+ /** Render resolution. */
int resolution;
+ /** Viewport resolution for the non-render case. */
+ int viewport_resolution;
+
int spatial_size;
float wind_velocity;
@@ -1282,8 +1297,6 @@ typedef struct OceanModifierData {
float foam_coverage;
float time;
- char _pad1[4];
-
/* Spectrum being used. */
int spectrum;
@@ -2040,6 +2053,10 @@ enum {
MOD_NORMALEDIT_MIX_MUL = 3,
};
+typedef struct MeshCacheVertexVelocity {
+ float vel[3];
+} MeshCacheVertexVelocity;
+
typedef struct MeshSeqCacheModifierData {
ModifierData modifier;
@@ -2048,11 +2065,31 @@ typedef struct MeshSeqCacheModifierData {
char object_path[1024];
char read_flag;
- char _pad[7];
+ char _pad[3];
+
+ float velocity_scale;
/* Runtime. */
struct CacheReader *reader;
char reader_object_path[1024];
+
+ /* Vertex velocities read from the cache. The velocities are not automatically read during
+ * modifier execution, and therefore have to manually be read when needed. This is only used
+ * through the RNA for now. */
+ struct MeshCacheVertexVelocity *vertex_velocities;
+
+ /* The number of vertices of the Alembic mesh, set when the modifier is executed. */
+ int num_vertices;
+
+ /* Time (in frames or seconds) between two velocity samples. Automatically computed to
+ * scale the velocity vectors at render time for generating proper motion blur data. */
+ float velocity_delta;
+
+ /* Caches the scene time (in seconds) used to lookup data in the Alembic archive when the
+ * modifier was last executed. Used to access Alembic samples through the RNA. */
+ float last_lookup_time;
+
+ int _pad1;
} MeshSeqCacheModifierData;
/* MeshSeqCacheModifierData.read_flag */
@@ -2146,11 +2183,9 @@ typedef struct SimulationModifierData {
ModifierData modifier;
struct Simulation *simulation;
- char data_path[64];
+ char *data_path;
} SimulationModifierData;
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h
index d750a7f3148..2b1fd546450 100644
--- a/source/blender/makesdna/DNA_movieclip_types.h
+++ b/source/blender/makesdna/DNA_movieclip_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_MOVIECLIP_TYPES_H__
-#define __DNA_MOVIECLIP_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_color_types.h" /* for color management */
@@ -64,8 +63,8 @@ typedef struct MovieClipProxy {
typedef struct MovieClip_RuntimeGPUTexture {
void *next, *prev;
MovieClipUser user;
- /** Not written in file 4 = TEXTARGET_COUNT. */
- struct GPUTexture *gputexture[4];
+ /** Not written in file 3 = TEXTARGET_COUNT. */
+ struct GPUTexture *gputexture[3];
} MovieClip_RuntimeGPUTexture;
typedef struct MovieClip_Runtime {
@@ -208,5 +207,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/makesdna/DNA_nla_types.h b/source/blender/makesdna/DNA_nla_types.h
index 6bf4a92514e..1cf93464f6a 100644
--- a/source/blender/makesdna/DNA_nla_types.h
+++ b/source/blender/makesdna/DNA_nla_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_NLA_TYPES_H__
-#define __DNA_NLA_TYPES_H__
+#pragma once
#include "DNA_listBase.h"
@@ -106,5 +105,3 @@ typedef enum eActStrip_Flag {
ACTSTRIP_REVERSE = (1 << 7),
ACTSTRIP_AUTO_BLENDS = (1 << 11),
} eActStrip_Flag;
-
-#endif
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 993aad92564..1d76ebdff2c 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_NODE_TYPES_H__
-#define __DNA_NODE_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_listBase.h"
@@ -845,14 +844,15 @@ typedef struct NodeTexSky {
float turbidity;
float ground_albedo;
float sun_size;
+ float sun_intensity;
float sun_elevation;
float sun_rotation;
- int altitude;
+ float altitude;
float air_density;
float dust_density;
float ozone_density;
char sun_disc;
- char _pad[3];
+ char _pad[7];
} NodeTexSky;
typedef struct NodeTexImage {
@@ -1438,5 +1438,3 @@ typedef enum NodeSimInputTimeType {
NODE_SIM_INPUT_SIMULATION_TIME = 0,
NODE_SIM_INPUT_SCENE_TIME = 1,
} NodeSimInputTimeType;
-
-#endif
diff --git a/source/blender/makesdna/DNA_object_defaults.h b/source/blender/makesdna/DNA_object_defaults.h
index 554d68f2d4a..1bca572b963 100644
--- a/source/blender/makesdna/DNA_object_defaults.h
+++ b/source/blender/makesdna/DNA_object_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_OBJECT_DEFAULTS_H__
-#define __DNA_OBJECT_DEFAULTS_H__
+#pragma once
#include "DNA_vec_defaults.h"
@@ -72,5 +71,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_OBJECT_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_object_enums.h b/source/blender/makesdna/DNA_object_enums.h
index f3e69161c85..dbbd72c2075 100644
--- a/source/blender/makesdna/DNA_object_enums.h
+++ b/source/blender/makesdna/DNA_object_enums.h
@@ -20,8 +20,7 @@
* Enums typedef's for use in public headers.
*/
-#ifndef __DNA_OBJECT_ENUMS_H__
-#define __DNA_OBJECT_ENUMS_H__
+#pragma once
/** #Object.mode */
typedef enum eObjectMode {
@@ -69,5 +68,3 @@ typedef enum eDrawType {
(OB_MODE_EDIT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_SCULPT | OB_MODE_POSE | \
OB_MODE_PAINT_GPENCIL | OB_MODE_EDIT_GPENCIL | OB_MODE_SCULPT_GPENCIL | \
OB_MODE_WEIGHT_GPENCIL | OB_MODE_VERTEX_GPENCIL)
-
-#endif /* __DNA_OBJECT_ENUMS_H__ */
diff --git a/source/blender/makesdna/DNA_object_fluidsim_types.h b/source/blender/makesdna/DNA_object_fluidsim_types.h
index 1140a837e23..b8848ccc458 100644
--- a/source/blender/makesdna/DNA_object_fluidsim_types.h
+++ b/source/blender/makesdna/DNA_object_fluidsim_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_OBJECT_FLUIDSIM_TYPES_H__
-#define __DNA_OBJECT_FLUIDSIM_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -179,5 +178,3 @@ typedef struct FluidsimSettings {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_OBJECT_FLUIDSIM_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_object_force_types.h b/source/blender/makesdna/DNA_object_force_types.h
index 78f645deaa2..3b0640544ae 100644
--- a/source/blender/makesdna/DNA_object_force_types.h
+++ b/source/blender/makesdna/DNA_object_force_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_OBJECT_FORCE_TYPES_H__
-#define __DNA_OBJECT_FORCE_TYPES_H__
+#pragma once
#include "DNA_defs.h"
#include "DNA_listBase.h"
@@ -409,5 +408,3 @@ typedef struct SoftBody {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_OBJECT_FORCE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 47e6db835c9..6568281a8d4 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -22,8 +22,7 @@
* \brief Object is a sort of wrapper for general info.
*/
-#ifndef __DNA_OBJECT_TYPES_H__
-#define __DNA_OBJECT_TYPES_H__
+#pragma once
#include "DNA_object_enums.h"
@@ -495,19 +494,19 @@ enum {
ID_VO))
#define OB_DATA_SUPPORT_ID_CASE \
-ID_ME: \
-case ID_CU: \
-case ID_MB: \
-case ID_LA: \
-case ID_SPK: \
-case ID_LP: \
-case ID_CA: \
-case ID_LT: \
-case ID_GD: \
-case ID_AR: \
-case ID_HA: \
-case ID_PT: \
-case ID_VO
+ ID_ME: \
+ case ID_CU: \
+ case ID_MB: \
+ case ID_LA: \
+ case ID_SPK: \
+ case ID_LP: \
+ case ID_CA: \
+ case ID_LT: \
+ case ID_GD: \
+ case ID_AR: \
+ case ID_HA: \
+ case ID_PT: \
+ case ID_VO
/* partype: first 4 bits: type */
enum {
@@ -564,7 +563,7 @@ enum {
/* for solid+wire display */
OB_DRAWWIRE = 1 << 5,
/* for overdraw s*/
- OB_DRAWXRAY = 1 << 6,
+ OB_DRAW_IN_FRONT = 1 << 6,
/* enable transparent draw */
OB_DRAWTRANSP = 1 << 7,
OB_DRAW_ALL_EDGES = 1 << 8, /* only for meshes currently */
@@ -715,5 +714,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h
index d8a7599e4cb..46c8b1570e3 100644
--- a/source/blender/makesdna/DNA_outliner_types.h
+++ b/source/blender/makesdna/DNA_outliner_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_OUTLINER_TYPES_H__
-#define __DNA_OUTLINER_TYPES_H__
+#pragma once
#include "DNA_defs.h"
@@ -127,5 +126,3 @@ enum {
TSE_KEYMAP_ITEM, \
TSE_ID_BASE, \
TSE_GP_LAYER))
-
-#endif
diff --git a/source/blender/makesdna/DNA_packedFile_types.h b/source/blender/makesdna/DNA_packedFile_types.h
index 8196e3098eb..b74368f767b 100644
--- a/source/blender/makesdna/DNA_packedFile_types.h
+++ b/source/blender/makesdna/DNA_packedFile_types.h
@@ -21,13 +21,10 @@
* \ingroup DNA
*/
-#ifndef __DNA_PACKEDFILE_TYPES_H__
-#define __DNA_PACKEDFILE_TYPES_H__
+#pragma once
typedef struct PackedFile {
int size;
int seek;
void *data;
} PackedFile;
-
-#endif /* PACKEDFILE_TYPES_H */
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 5bd11ab85a5..00f888dde5b 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_PARTICLE_TYPES_H__
-#define __DNA_PARTICLE_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_boid_types.h"
@@ -691,5 +690,3 @@ typedef enum eParticleTextureInfluence {
PAMAP_CHILD = (PAMAP_CLUMP | PAMAP_KINK_FREQ | PAMAP_KINK_AMP | PAMAP_ROUGH | PAMAP_LENGTH |
PAMAP_TWIST),
} eParticleTextureInfluence;
-
-#endif
diff --git a/source/blender/makesdna/DNA_pointcache_types.h b/source/blender/makesdna/DNA_pointcache_types.h
index 3c7fc9031de..678be7d8297 100644
--- a/source/blender/makesdna/DNA_pointcache_types.h
+++ b/source/blender/makesdna/DNA_pointcache_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_POINTCACHE_TYPES_H__
-#define __DNA_POINTCACHE_TYPES_H__
+#pragma once
#include "DNA_listBase.h"
@@ -167,5 +166,3 @@ typedef struct PointCache {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_POINTCACHE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_pointcloud_defaults.h b/source/blender/makesdna/DNA_pointcloud_defaults.h
index 89df2d3c4be..b5c9396b1dd 100644
--- a/source/blender/makesdna/DNA_pointcloud_defaults.h
+++ b/source/blender/makesdna/DNA_pointcloud_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_POINTCLOUD_DEFAULTS_H__
-#define __DNA_POINTCLOUD_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -36,5 +35,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_POINTCLOUD_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_pointcloud_types.h b/source/blender/makesdna/DNA_pointcloud_types.h
index 7f42b75fdd1..d3b687c2c68 100644
--- a/source/blender/makesdna/DNA_pointcloud_types.h
+++ b/source/blender/makesdna/DNA_pointcloud_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_POINTCLOUD_TYPES_H__
-#define __DNA_POINTCLOUD_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_customdata_types.h"
@@ -56,5 +55,3 @@ enum {
/* Only one material supported currently. */
#define POINTCLOUD_MATERIAL_NR 1
-
-#endif /* __DNA_POINTCLOUD_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h
index 7ad50dc04de..02a4a158d8c 100644
--- a/source/blender/makesdna/DNA_rigidbody_types.h
+++ b/source/blender/makesdna/DNA_rigidbody_types.h
@@ -22,8 +22,7 @@
* \brief Types and defines for representing Rigid Body entities
*/
-#ifndef __DNA_RIGIDBODY_TYPES_H__
-#define __DNA_RIGIDBODY_TYPES_H__
+#pragma once
#include "DNA_listBase.h"
#include "DNA_object_force_types.h"
@@ -214,7 +213,7 @@ typedef enum eRigidBody_Shape {
RB_SHAPE_TRIMESH = 6,
/* concave mesh approximated using primitives */
- // RB_SHAPE_COMPOUND,
+ RB_SHAPE_COMPOUND = 7,
} eRigidBody_Shape;
typedef enum eRigidBody_MeshSource {
@@ -369,5 +368,3 @@ typedef enum eRigidBodyCon_Flag {
} eRigidBodyCon_Flag;
/* ******************************** */
-
-#endif /* __DNA_RIGIDBODY_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_scene_defaults.h b/source/blender/makesdna/DNA_scene_defaults.h
index 7f01e58f2af..ec64eea0aae 100644
--- a/source/blender/makesdna/DNA_scene_defaults.h
+++ b/source/blender/makesdna/DNA_scene_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SCENE_DEFAULTS_H__
-#define __DNA_SCENE_DEFAULTS_H__
+#pragma once
#include "DNA_view3d_defaults.h"
@@ -366,4 +365,3 @@
/* clang-format off */
-#endif /* __DNA_SCENE_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index dd62ddb640f..93e690d0aba 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SCENE_TYPES_H__
-#define __DNA_SCENE_TYPES_H__
+#pragma once
#include "DNA_defs.h"
@@ -2241,6 +2240,8 @@ enum {
#define UVCALC_USESUBSURF (1 << 3)
/** adjust UV's while transforming to avoid distortion */
#define UVCALC_TRANSFORM_CORRECT (1 << 4)
+/** Keep equal values merged while correcting custom-data. */
+#define UVCALC_TRANSFORM_CORRECT_KEEP_CONNECTED (1 << 5)
/* ToolSettings.uv_flag */
#define UV_SYNC_SELECTION 1
@@ -2412,5 +2413,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_SCENE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index f9fcbdab55d..d5b828c898d 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SCREEN_TYPES_H__
-#define __DNA_SCREEN_TYPES_H__
+#pragma once
#include "DNA_defs.h"
#include "DNA_listBase.h"
@@ -69,6 +68,8 @@ typedef struct bScreen {
/** User-setting for which editors get redrawn during anim playback. */
short redraws_flag;
+ char statusbar_info[256];
+
/** Temp screen in a temp window, don't save (like user prefs). */
char temp;
/** Temp screen for image render display or fileselect. */
@@ -167,9 +168,8 @@ typedef struct Panel {
/** Panel size excluding children. */
int blocksizex, blocksizey;
short labelofs;
- char _pad[2];
+ char _pad[4];
short flag, runtime_flag;
- short control;
short snap;
/** Panels are aligned according to increasing sort-order. */
int sortorder;
@@ -539,8 +539,8 @@ enum {
PNL_CLOSEDX = (1 << 1),
PNL_CLOSEDY = (1 << 2),
PNL_CLOSED = (PNL_CLOSEDX | PNL_CLOSEDY),
- /*PNL_TABBED = (1 << 3), */ /*UNUSED*/
- PNL_OVERLAP = (1 << 4),
+ /* PNL_TABBED = (1 << 3), */ /*UNUSED*/
+ /* PNL_OVERLAP = (1 << 4), */ /*UNUSED*/
PNL_PIN = (1 << 5),
PNL_POPOVER = (1 << 6),
/** The panel has been drag-drop reordered and the instanced panel list needs to be rebuilt. */
@@ -704,5 +704,3 @@ enum {
/* Only editor overlays (currently gizmos only!) should be redrawn. */
RGN_DRAW_EDITOR_OVERLAYS = 32,
};
-
-#endif /* __DNA_SCREEN_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_sdna_types.h b/source/blender/makesdna/DNA_sdna_types.h
index efa7a308f88..cfb65860b8e 100644
--- a/source/blender/makesdna/DNA_sdna_types.h
+++ b/source/blender/makesdna/DNA_sdna_types.h
@@ -20,8 +20,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SDNA_TYPES_H__
-#define __DNA_SDNA_TYPES_H__
+#pragma once
struct MemArena;
@@ -101,5 +100,3 @@ typedef struct BHead8 {
int64_t old;
int SDNAnr, nr;
} BHead8;
-
-#endif
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 9fee839f979..850b906af39 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -28,12 +28,12 @@
* - Meta Strip (SEQ_TYPE_META): Support for nesting Sequences.
*/
-#ifndef __DNA_SEQUENCE_TYPES_H__
-#define __DNA_SEQUENCE_TYPES_H__
+#pragma once
#include "DNA_color_types.h"
#include "DNA_defs.h"
#include "DNA_listBase.h"
+#include "DNA_session_uuid_types.h"
#include "DNA_vec_types.h"
#include "DNA_vfont_types.h"
@@ -119,6 +119,10 @@ typedef struct Strip {
ColorManagedColorspaceSettings colorspace_settings;
} Strip;
+typedef struct SequenceRuntime {
+ SessionUUID session_uuid;
+} SequenceRuntime;
+
/**
* The sequence structure is the basic struct used by any strip.
* each of the strips uses a different sequence structure.
@@ -237,8 +241,7 @@ typedef struct Sequence {
int cache_flag;
int _pad2[3];
- struct Sequence *orig_sequence;
- void *_pad3;
+ SequenceRuntime runtime;
} Sequence;
typedef struct MetaStack {
@@ -692,5 +695,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif /* __DNA_SEQUENCE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_session_uuid_types.h b/source/blender/makesdna/DNA_session_uuid_types.h
new file mode 100644
index 00000000000..eaaae101277
--- /dev/null
+++ b/source/blender/makesdna/DNA_session_uuid_types.h
@@ -0,0 +1,43 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup DNA
+ */
+
+#pragma once
+
+#include "BLI_sys_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Is a structure because of the following considerations:
+ *
+ * - It is not possible to use custom types in DNA members: makesdna does not recognize them.
+ * - It allows to add more bits, more than standard fixed-size types can store. For example, if
+ * we ever need to go 128 bits, it is as simple as adding extra 64bit field.
+ */
+typedef struct SessionUUID {
+ /* Never access directly, as it might cause a headache when more bits are needed: if the field
+ * is used directly it will not be easy to find all places where partial access is used. */
+ uint64_t uuid_;
+} SessionUUID;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/makesdna/DNA_shader_fx_types.h b/source/blender/makesdna/DNA_shader_fx_types.h
index f19181bf07d..56caac51b94 100644
--- a/source/blender/makesdna/DNA_shader_fx_types.h
+++ b/source/blender/makesdna/DNA_shader_fx_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SHADER_FX_TYPES_H__
-#define __DNA_SHADER_FX_TYPES_H__
+#pragma once
#include "DNA_defs.h"
#include "DNA_listBase.h"
@@ -250,4 +249,3 @@ typedef struct WaveShaderFxData {
char _pad[4];
ShaderFxData_Runtime runtime;
} WaveShaderFxData;
-#endif /* __DNA_SHADER_FX_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_simulation_defaults.h b/source/blender/makesdna/DNA_simulation_defaults.h
index b4cecd861a9..48d35d5e81f 100644
--- a/source/blender/makesdna/DNA_simulation_defaults.h
+++ b/source/blender/makesdna/DNA_simulation_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SIMULATION_DEFAULTS_H__
-#define __DNA_SIMULATION_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -36,5 +35,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_SIMULATION_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_simulation_types.h b/source/blender/makesdna/DNA_simulation_types.h
index 93ba9c425f0..8cc2db99332 100644
--- a/source/blender/makesdna/DNA_simulation_types.h
+++ b/source/blender/makesdna/DNA_simulation_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SIMULATION_TYPES_H__
-#define __DNA_SIMULATION_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_customdata_types.h"
@@ -30,50 +29,67 @@ typedef struct Simulation {
struct bNodeTree *nodetree;
- int flag;
- int _pad;
+ uint32_t flag;
+
+ /** This is the frame in scene time, that the states correspond to. */
+ float current_frame;
+
+ /** Time since the start of the simulation in simulation time (which might differ from scene
+ * time). */
+ float current_simulation_time;
+ char _pad[4];
/** List containing SimulationState objects. */
struct ListBase states;
+
+ /** List containing SimulationDependency objects. */
+ struct ListBase dependencies;
} Simulation;
typedef struct SimulationState {
struct SimulationState *next;
struct SimulationState *prev;
- /** This is only initialized on cow copies of the simulation. It points to the state on the
- * original data block. That is where the cache is stored. */
- struct SimulationState *orig_state;
-
- /** eSimulationStateType */
- int type;
- int _pad;
-
- char name[64];
+ char *type;
+ char *name;
} SimulationState;
typedef struct ParticleSimulationState {
SimulationState head;
- /** Contains the state of the particles at time current_frame. */
- float current_frame;
- int tot_particles;
+ /** Contains the state of the particles at time Simulation->current_frame. */
+ int32_t tot_particles;
+ int32_t next_particle_id;
struct CustomData attributes;
-
- /** Caches the state of the particles over time. The cache only exists on the original data
- * block, not on cow copies. */
- struct PointCache *point_cache;
- struct ListBase ptcaches;
} ParticleSimulationState;
+typedef struct ParticleMeshEmitterSimulationState {
+ SimulationState head;
+
+ float last_birth_time;
+ char _pad[4];
+} ParticleMeshEmitterSimulationState;
+
+/** Stores a reference to data that the simulation depends on. This is partially derived from the
+ * simulation node tree. */
+typedef struct SimulationDependency {
+ struct SimulationDependency *next;
+ struct SimulationDependency *prev;
+ struct ID *id;
+ int32_t handle;
+ uint32_t flag;
+} SimulationDependency;
+
/* Simulation.flag */
enum {
SIM_DS_EXPAND = (1 << 0),
};
-/* SimulationCache.type */
-typedef enum eSimulationStateType {
- SIM_STATE_TYPE_PARTICLES = 0,
-} eSimulationStateType;
+/* SimulationDependency.flag */
+enum {
+ SIM_DEPENDS_ON_TRANSFORM = (1 << 0),
+ SIM_DEPENDS_ON_GEOMETRY = (1 << 1),
+};
-#endif /* __DNA_SIMULATION_TYPES_H__ */
+#define SIM_TYPE_NAME_PARTICLE_SIMULATION "Particle Simulation"
+#define SIM_TYPE_NAME_PARTICLE_MESH_EMITTER "Particle Mesh Emitter"
diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h
index 35ff3a658ba..1d24e655f45 100644
--- a/source/blender/makesdna/DNA_sound_types.h
+++ b/source/blender/makesdna/DNA_sound_types.h
@@ -20,8 +20,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SOUND_TYPES_H__
-#define __DNA_SOUND_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -117,5 +116,3 @@ enum {
SOUND_TAGS_WAVEFORM_NO_RELOAD = 1 << 0,
SOUND_TAGS_WAVEFORM_LOADING = (1 << 6),
};
-
-#endif /* __DNA_SOUND_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 1cb42b333c7..7d77e8478ae 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -22,8 +22,7 @@
* Structs for each of space type in the user interface.
*/
-#ifndef __DNA_SPACE_TYPES_H__
-#define __DNA_SPACE_TYPES_H__
+#pragma once
#include "DNA_color_types.h" /* for Histogram */
#include "DNA_defs.h"
@@ -1148,8 +1147,9 @@ typedef enum eSpaceImage_Flag {
SI_FLAG_UNUSED_17 = (1 << 17), /* cleared */
SI_FLAG_UNUSED_18 = (1 << 18), /* cleared */
- /* this means that the image is drawn until it reaches the view edge,
- * in the image view, it's unrelated to the 'tile' mode for texface
+ /**
+ * This means that the image is drawn until it reaches the view edge,
+ * in the image view, it's unrelated to UDIM tiles.
*/
SI_DRAW_TILE = (1 << 19),
SI_SMOOTH_UV = (1 << 20),
@@ -1734,5 +1734,3 @@ typedef enum eSpace_Type {
#define IMG_SIZE_FALLBACK 256
/** \} */
-
-#endif /* __DNA_SPACE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_speaker_defaults.h b/source/blender/makesdna/DNA_speaker_defaults.h
index d252a447701..a14e4d687d3 100644
--- a/source/blender/makesdna/DNA_speaker_defaults.h
+++ b/source/blender/makesdna/DNA_speaker_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SPEAKER_DEFAULTS_H__
-#define __DNA_SPEAKER_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -47,5 +46,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_SPEAKER_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_speaker_types.h b/source/blender/makesdna/DNA_speaker_types.h
index 9100b37d85e..82693689d68 100644
--- a/source/blender/makesdna/DNA_speaker_types.h
+++ b/source/blender/makesdna/DNA_speaker_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_SPEAKER_TYPES_H__
-#define __DNA_SPEAKER_TYPES_H__
+#pragma once
#include "DNA_ID.h"
@@ -58,5 +57,3 @@ typedef struct Speaker {
#define SPK_DS_EXPAND (1 << 0)
#define SPK_MUTED (1 << 1)
// #define SPK_RELATIVE (1 << 2) /* UNUSED */
-
-#endif /* __DNA_SPEAKER_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_text_types.h b/source/blender/makesdna/DNA_text_types.h
index 27663ffcbdd..2dcb19d19b8 100644
--- a/source/blender/makesdna/DNA_text_types.h
+++ b/source/blender/makesdna/DNA_text_types.h
@@ -23,8 +23,7 @@
* and arbitrary text data to store in blend files.
*/
-#ifndef __DNA_TEXT_TYPES_H__
-#define __DNA_TEXT_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_listBase.h"
@@ -85,5 +84,3 @@ enum {
/** Use space instead of tabs. */
TXT_TABSTOSPACES = 1 << 10,
};
-
-#endif /* __DNA_TEXT_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_texture_defaults.h b/source/blender/makesdna/DNA_texture_defaults.h
index d5097c5ea21..1e790709fd1 100644
--- a/source/blender/makesdna/DNA_texture_defaults.h
+++ b/source/blender/makesdna/DNA_texture_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_TEXTURE_DEFAULTS_H__
-#define __DNA_TEXTURE_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -151,5 +150,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_TEXTURE_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index 907fe29263f..63e5f134c19 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_TEXTURE_TYPES_H__
-#define __DNA_TEXTURE_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -529,5 +528,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h
index 32a00cc25d1..4cd9034a83b 100644
--- a/source/blender/makesdna/DNA_tracking_types.h
+++ b/source/blender/makesdna/DNA_tracking_types.h
@@ -23,8 +23,7 @@
* Structs used for camera tracking and the movie-clip editor.
*/
-#ifndef __DNA_TRACKING_TYPES_H__
-#define __DNA_TRACKING_TYPES_H__
+#pragma once
#include "DNA_defs.h"
#include "DNA_listBase.h"
@@ -617,5 +616,3 @@ enum {
PLANE_TRACK_LOCKED = (1 << 2),
PLANE_TRACK_AUTOKEY = (1 << 3),
};
-
-#endif /* __DNA_TRACKING_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index d751ad9ac47..c2ed6c97d3d 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_USERDEF_TYPES_H__
-#define __DNA_USERDEF_TYPES_H__
+#pragma once
#include "DNA_listBase.h"
#include "DNA_texture_types.h" /* ColorBand */
@@ -622,8 +621,9 @@ typedef struct UserDef_Experimental {
char use_new_particle_system;
char use_new_hair_type;
char use_cycles_debug;
+ char use_sculpt_vertex_colors;
/** `makesdna` does not allow empty structs. */
- char _pad0[4];
+ char _pad[3];
} UserDef_Experimental;
#define USER_EXPERIMENTAL_TEST(userdef, member) \
@@ -660,9 +660,9 @@ typedef struct UserDef {
char anim_player[1024];
int anim_player_preset;
- /** Minimum spacing between gridlines in View2D grids. */
+ /** Minimum spacing between grid-lines in View2D grids. */
short v2d_min_gridsize;
- /** #eTimecodeStyles, style of timecode display. */
+ /** #eTimecodeStyles, style of time-code display. */
short timecode_style;
short versions;
@@ -693,7 +693,7 @@ typedef struct UserDef {
float ui_scale;
/** Setting for UI line width. */
int ui_line_width;
- /** Runtime, full DPI divided by pixelsize. */
+ /** Runtime, full DPI divided by `pixelsize`. */
int dpi;
/** Runtime, multiplier to scale UI elements based on DPI. */
float dpi_fac;
@@ -703,7 +703,7 @@ typedef struct UserDef {
/** Deprecated, for forward compatibility. */
int virtual_pixel;
- /** Console scrollback limit. */
+ /** Console scroll-back limit. */
int scrollback;
/** Node insert offset (aka auto-offset) margin, but might be useful for later stuff as well. */
char node_margin;
@@ -732,7 +732,7 @@ typedef struct UserDef {
char _pad1[2];
int undomemory;
float gpu_viewport_quality DNA_DEPRECATED;
- short gp_manhattendist, gp_euclideandist, gp_eraser;
+ short gp_manhattandist, gp_euclideandist, gp_eraser;
/** #eGP_UserdefSettings. */
short gp_settings;
char _pad13[4];
@@ -879,7 +879,9 @@ typedef struct UserDef {
char _pad5[2];
float collection_instance_empty_size;
- char _pad10[4];
+ char _pad10[3];
+
+ char statusbar_flag; /* eUserpref_StatusBar_Flag */
struct WalkNavigation walk_navigation;
@@ -1078,6 +1080,14 @@ typedef enum eUserpref_APP_Flag {
USER_APP_LOCK_UI_LAYOUT = (1 << 0),
} eUserpref_APP_Flag;
+/** #UserDef.statusbar_flag */
+typedef enum eUserpref_StatusBar_Flag {
+ STATUSBAR_SHOW_MEMORY = (1 << 0),
+ STATUSBAR_SHOW_VRAM = (1 << 1),
+ STATUSBAR_SHOW_STATS = (1 << 2),
+ STATUSBAR_SHOW_VERSION = (1 << 3),
+} eUserpref_StatusBar_Flag;
+
/**
* Auto-Keying mode.
* #UserDef.autokey_mode
@@ -1160,6 +1170,8 @@ typedef enum eDupli_ID_Flags {
USER_DUP_OBJECT = (1 << 24),
/* USER_DUP_COLLECTION = (1 << 25), */ /* UNUSED, keep because we may implement. */
+ /* Duplicate (and hence make local) linked data. */
+ USER_DUP_LINKED_ID = (1 << 30),
} eDupli_ID_Flags;
/**
@@ -1326,5 +1338,3 @@ enum {
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/makesdna/DNA_vec_defaults.h b/source/blender/makesdna/DNA_vec_defaults.h
index 7242f5ab114..3b980db7838 100644
--- a/source/blender/makesdna/DNA_vec_defaults.h
+++ b/source/blender/makesdna/DNA_vec_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_VEC_DEFAULTS_H__
-#define __DNA_VEC_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -51,5 +50,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_VEC_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_vec_types.h b/source/blender/makesdna/DNA_vec_types.h
index 72a6056e239..b8cbf85b683 100644
--- a/source/blender/makesdna/DNA_vec_types.h
+++ b/source/blender/makesdna/DNA_vec_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_VEC_TYPES_H__
-#define __DNA_VEC_TYPES_H__
+#pragma once
/* types */
@@ -91,5 +90,3 @@ typedef struct DualQuat {
float scale[4][4];
float scale_weight;
} DualQuat;
-
-#endif
diff --git a/source/blender/makesdna/DNA_vfont_types.h b/source/blender/makesdna/DNA_vfont_types.h
index 086fb2bc905..4e2a6eba1f5 100644
--- a/source/blender/makesdna/DNA_vfont_types.h
+++ b/source/blender/makesdna/DNA_vfont_types.h
@@ -24,8 +24,7 @@
* (unrelated to text used to render the GUI).
*/
-#ifndef __DNA_VFONT_TYPES_H__
-#define __DNA_VFONT_TYPES_H__
+#pragma once
#include "DNA_ID.h"
@@ -60,5 +59,3 @@ typedef struct VFont {
#define FO_CURS_IS_MOTION(mode) (ELEM(mode, FO_CURSUP, FO_CURSDOWN, FO_PAGEUP, FO_PAGEDOWN))
#define FO_BUILTIN_NAME "<builtin>"
-
-#endif /* __DNA_VFONT_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_view2d_types.h b/source/blender/makesdna/DNA_view2d_types.h
index 8734a73c07a..63038b6be2d 100644
--- a/source/blender/makesdna/DNA_view2d_types.h
+++ b/source/blender/makesdna/DNA_view2d_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_VIEW2D_TYPES_H__
-#define __DNA_VIEW2D_TYPES_H__
+#pragma once
#include "DNA_vec_types.h"
@@ -137,7 +136,7 @@ enum {
/* apply pixel offsets on y-axis when setting view matrices */
V2D_PIXELOFS_Y = (1 << 3),
/* view settings need to be set still... */
- V2D_IS_INITIALISED = (1 << 10),
+ V2D_IS_INIT = (1 << 10),
};
/* scroller flags for View2D (v2d->scroll) */
@@ -181,5 +180,3 @@ enum {
V2D_ALIGN_NO_POS_Y = (1 << 2),
V2D_ALIGN_NO_NEG_Y = (1 << 3),
};
-
-#endif
diff --git a/source/blender/makesdna/DNA_view3d_defaults.h b/source/blender/makesdna/DNA_view3d_defaults.h
index 10eadf368ef..62e3d14bd0c 100644
--- a/source/blender/makesdna/DNA_view3d_defaults.h
+++ b/source/blender/makesdna/DNA_view3d_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_VIEW3D_DEFAULTS_H__
-#define __DNA_VIEW3D_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -114,5 +113,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_VIEW3D_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_view3d_enums.h b/source/blender/makesdna/DNA_view3d_enums.h
index f8c772422bb..fdeebf20808 100644
--- a/source/blender/makesdna/DNA_view3d_enums.h
+++ b/source/blender/makesdna/DNA_view3d_enums.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_VIEW3D_ENUMS_H__
-#define __DNA_VIEW3D_ENUMS_H__
+#pragma once
/** Settings for offscreen rendering */
typedef enum eV3DOffscreenDrawFlag {
@@ -52,5 +51,3 @@ typedef enum eV3DShadingBackgroundType {
V3D_SHADING_BACKGROUND_WORLD = 1,
V3D_SHADING_BACKGROUND_VIEWPORT = 2,
} eV3DShadingBackgroundType;
-
-#endif
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index ef174f5858f..7bfdc14d25c 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_VIEW3D_TYPES_H__
-#define __DNA_VIEW3D_TYPES_H__
+#pragma once
struct BoundBox;
struct Object;
@@ -191,6 +190,7 @@ typedef struct View3DShading {
int render_pass;
struct IDProperty *prop;
+ void *_pad2;
} View3DShading;
/** 3D Viewport Overlay settings. */
@@ -629,5 +629,3 @@ enum {
/** #BKE_screen_view3d_zoom_to_fac() values above */
#define RV3D_CAMZOOM_MIN_FACTOR 0.1657359312880714853f
#define RV3D_CAMZOOM_MAX_FACTOR 44.9852813742385702928f
-
-#endif
diff --git a/source/blender/makesdna/DNA_volume_defaults.h b/source/blender/makesdna/DNA_volume_defaults.h
index 3a0373851da..8239f263c6c 100644
--- a/source/blender/makesdna/DNA_volume_defaults.h
+++ b/source/blender/makesdna/DNA_volume_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_VOLUME_DEFAULTS_H__
-#define __DNA_VOLUME_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -55,5 +54,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_VOLUME_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_volume_types.h b/source/blender/makesdna/DNA_volume_types.h
index b3615e87a50..30ac67281e2 100644
--- a/source/blender/makesdna/DNA_volume_types.h
+++ b/source/blender/makesdna/DNA_volume_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_VOLUME_TYPES_H__
-#define __DNA_VOLUME_TYPES_H__
+#pragma once
#include "DNA_ID.h"
@@ -122,5 +121,3 @@ typedef enum VolumeRenderSpace {
/* Only one material supported currently. */
#define VOLUME_MATERIAL_NR 1
-
-#endif /* __DNA_VOLUME_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index a07b8f81d96..dd11fed021d 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_WINDOWMANAGER_TYPES_H__
-#define __DNA_WINDOWMANAGER_TYPES_H__
+#pragma once
#include "DNA_listBase.h"
#include "DNA_screen_types.h"
@@ -198,8 +197,8 @@ typedef struct wmWindowManager {
/* wmWindowManager.initialized */
enum {
- WM_WINDOW_IS_INITIALIZED = (1 << 0),
- WM_KEYCONFIG_IS_INITIALIZED = (1 << 1),
+ WM_WINDOW_IS_INIT = (1 << 0),
+ WM_KEYCONFIG_IS_INIT = (1 << 1),
};
/* wmWindowManager.outliner_sync_select_dirty */
@@ -557,5 +556,3 @@ enum {
* (the regiontype is maintained to prevent errors) */
OP_IS_MODAL_CURSOR_REGION = (1 << 3),
};
-
-#endif /* __DNA_WINDOWMANAGER_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h
index d2461657480..170366881c6 100644
--- a/source/blender/makesdna/DNA_workspace_types.h
+++ b/source/blender/makesdna/DNA_workspace_types.h
@@ -20,8 +20,7 @@
* Use API in BKE_workspace.h to edit these.
*/
-#ifndef __DNA_WORKSPACE_TYPES_H__
-#define __DNA_WORKSPACE_TYPES_H__
+#pragma once
#include "DNA_scene_types.h"
@@ -184,5 +183,3 @@ typedef struct WorkSpaceInstanceHook {
typedef enum eWorkSpaceFlags {
WORKSPACE_USE_FILTER_BY_ORIGIN = (1 << 1),
} eWorkSpaceFlags;
-
-#endif /* __DNA_WORKSPACE_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_world_defaults.h b/source/blender/makesdna/DNA_world_defaults.h
index c4d934381b4..52c9551a63e 100644
--- a/source/blender/makesdna/DNA_world_defaults.h
+++ b/source/blender/makesdna/DNA_world_defaults.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_WORLD_DEFAULTS_H__
-#define __DNA_WORLD_DEFAULTS_H__
+#pragma once
/* Struct members on own line. */
/* clang-format off */
@@ -45,5 +44,3 @@
/** \} */
/* clang-format on */
-
-#endif /* __DNA_WORLD_DEFAULTS_H__ */
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index f9198194a89..b1ecf4abf85 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -21,8 +21,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_WORLD_TYPES_H__
-#define __DNA_WORLD_TYPES_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_defs.h"
@@ -51,12 +50,10 @@ typedef struct World {
float horr, horg, horb;
/**
- * Exposure= mult factor. unused now, but maybe back later. Kept in to be upward compat.
- * New is exp/range control. linfac & logfac are constants... don't belong in
- * file, but allocating 8 bytes for temp mem isn't useful either.
+ * Exposure is a multiplication factor. Unused now, but maybe back later.
+ * Kept in to be upward compatible.
*/
float exposure, exp, range;
- float linfac, logfac;
/**
* Some world modes
@@ -113,5 +110,3 @@ enum {
* otherwise anim-editors will not read correctly
*/
#define WO_DS_SHOW_TEXS (1 << 2)
-
-#endif
diff --git a/source/blender/makesdna/DNA_xr_types.h b/source/blender/makesdna/DNA_xr_types.h
index a026f7554cb..caa5232788a 100644
--- a/source/blender/makesdna/DNA_xr_types.h
+++ b/source/blender/makesdna/DNA_xr_types.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_XR_TYPES_H__
-#define __DNA_XR_TYPES_H__
+#pragma once
#include "DNA_view3d_types.h"
@@ -54,5 +53,3 @@ typedef enum eXRSessionBasePoseType {
XR_BASE_POSE_OBJECT = 1,
XR_BASE_POSE_CUSTOM = 2,
} eXRSessionBasePoseType;
-
-#endif /* __DNA_XR_TYPES_H__ */
diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt
index 0f2761e311e..9808740e030 100644
--- a/source/blender/makesdna/intern/CMakeLists.txt
+++ b/source/blender/makesdna/intern/CMakeLists.txt
@@ -35,11 +35,13 @@ blender_include_dirs(
set(SRC
dna_utils.c
makesdna.c
+ ../../blenlib/intern/BLI_assert.c
../../blenlib/intern/BLI_ghash.c
../../blenlib/intern/BLI_ghash_utils.c
../../blenlib/intern/BLI_memarena.c
../../blenlib/intern/BLI_mempool.c
../../blenlib/intern/hash_mm2a.c # needed by 'BLI_ghash_utils.c', not used directly.
+ ../../../../intern/guardedalloc/intern/leak_detector.cc
../../../../intern/guardedalloc/intern/mallocn.c
../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c
../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -125,6 +127,7 @@ set(INC_SYS
)
set(SRC
+ ../../blenlib/intern/BLI_assert.c
../../blenlib/intern/BLI_ghash.c
../../blenlib/intern/BLI_ghash_utils.c
../../blenlib/intern/BLI_linklist.c
diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h
index f2cf72843bd..a73fc747f84 100644
--- a/source/blender/makesdna/intern/dna_rename_defs.h
+++ b/source/blender/makesdna/intern/dna_rename_defs.h
@@ -67,6 +67,7 @@ DNA_STRUCT_RENAME_ELEM(Bone, scaleOut, scale_out_x)
DNA_STRUCT_RENAME_ELEM(BrushGpencilSettings, gradient_f, hardeness)
DNA_STRUCT_RENAME_ELEM(BrushGpencilSettings, gradient_s, aspect_ratio)
DNA_STRUCT_RENAME_ELEM(Camera, YF_dofdist, dof_distance)
+DNA_STRUCT_RENAME_ELEM(Curve, len_wchar, len_char32)
DNA_STRUCT_RENAME_ELEM(Camera, clipend, clip_end)
DNA_STRUCT_RENAME_ELEM(Camera, clipsta, clip_start)
DNA_STRUCT_RENAME_ELEM(Collection, dupli_ofs, instance_offset)
@@ -90,6 +91,7 @@ DNA_STRUCT_RENAME_ELEM(ParticleSettings, dupliweights, instance_weights)
DNA_STRUCT_RENAME_ELEM(Text, name, filepath)
DNA_STRUCT_RENAME_ELEM(ThemeSpace, scrubbing_background, time_scrub_background)
DNA_STRUCT_RENAME_ELEM(ThemeSpace, show_back_grad, background_type)
+DNA_STRUCT_RENAME_ELEM(UserDef, gp_manhattendist, gp_manhattandist)
DNA_STRUCT_RENAME_ELEM(VFont, name, filepath)
DNA_STRUCT_RENAME_ELEM(View3D, far, clip_end)
DNA_STRUCT_RENAME_ELEM(View3D, near, clip_start)
diff --git a/source/blender/makesdna/intern/dna_utils.c b/source/blender/makesdna/intern/dna_utils.c
index 6708365a4c8..3cf5c52a4c6 100644
--- a/source/blender/makesdna/intern/dna_utils.c
+++ b/source/blender/makesdna/intern/dna_utils.c
@@ -232,6 +232,23 @@ void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_struct_map, GHash
for (int i = 0; i < ARRAY_SIZE(data); i++) {
BLI_ghash_insert(struct_map, (void *)data[i][elem_key], (void *)data[i][elem_val]);
}
+
+ if (version_dir == DNA_RENAME_STATIC_FROM_ALIAS) {
+ const char *renames[][2] = {
+ /* Disable 'int8_t' until we support 'signed char', since changing negative
+ * values to a different type isn't supported and will change the value. */
+ /* {"int8_t", "char"}, */
+ {"uint8_t", "uchar"},
+ {"int16_t", "short"},
+ {"uint16_t", "ushort"},
+ {"int32_t", "int"},
+ {"uint32_t", "int"},
+ };
+ for (int i = 0; i < ARRAY_SIZE(renames); i++) {
+ BLI_ghash_insert(struct_map, (void *)renames[i][0], (void *)renames[i][1]);
+ }
+ }
+
*r_struct_map = struct_map;
/* We know the direction of this, for local use. */
diff --git a/source/blender/makesdna/intern/dna_utils.h b/source/blender/makesdna/intern/dna_utils.h
index 123dd30a2b9..264310ef0fb 100644
--- a/source/blender/makesdna/intern/dna_utils.h
+++ b/source/blender/makesdna/intern/dna_utils.h
@@ -18,8 +18,7 @@
* \ingroup DNA
*/
-#ifndef __DNA_UTILS_H__
-#define __DNA_UTILS_H__
+#pragma once
struct GHash;
struct MemArena;
@@ -54,5 +53,3 @@ void DNA_alias_maps(enum eDNA_RenameDir version_dir,
const char *DNA_struct_rename_legacy_hack_alias_from_static(const char *name);
const char *DNA_struct_rename_legacy_hack_static_from_alias(const char *name);
-
-#endif /* __DNA_UTILS_H__ */
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 182296c0ba2..628b9bdff75 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -54,6 +54,7 @@
#include "BLI_ghash.h"
#include "BLI_memarena.h"
#include "BLI_sys_types.h" /* for intptr_t support */
+#include "BLI_system.h" /* for 'BLI_system_backtrace' stub. */
#include "BLI_utildefines.h"
#include "dna_utils.h"
@@ -98,6 +99,7 @@ static const char *includefiles[] = {
"DNA_sdna_types.h",
"DNA_fileglobal_types.h",
"DNA_sequence_types.h",
+ "DNA_session_uuid_types.h",
"DNA_effect_types.h",
"DNA_outliner_types.h",
"DNA_sound_types.h",
@@ -1530,12 +1532,21 @@ int main(int argc, char **argv)
#endif /* if 0 */
-/* even though DNA supports, 'long' shouldn't be used since it can be either 32 or 64bit,
- * use int or int64_t instead.
+/**
+ * Disable types:
+ *
+ * - 'long': even though DNA supports, 'long' shouldn't be used since it can be either 32 or 64bit,
+ * use int, int32_t or int64_t instead.
+ * - 'int8_t': as DNA doesn't yet support 'signed char' types,
+ * all char types are assumed to be unsigned.
+ * We should be able to support this, it's just not something which has been added yet.
+ *
* Only valid use would be as a runtime variable if an API expected a long,
- * but so far we dont have this happening. */
+ * but so far we don't have this happening.
+ */
#ifdef __GNUC__
# pragma GCC poison long
+# pragma GCC poison int8_t
#endif
#include "DNA_ID.h"
@@ -1592,6 +1603,7 @@ int main(int argc, char **argv)
#include "DNA_screen_types.h"
#include "DNA_sdna_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_session_uuid_types.h"
#include "DNA_shader_fx_types.h"
#include "DNA_simulation_types.h"
#include "DNA_sound_types.h"
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 53bb8899855..6acd9d16f80 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -1484,16 +1484,24 @@ void RNA_struct_override_apply(struct Main *bmain,
struct PointerRNA *ptr_storage,
struct IDOverrideLibrary *override);
-struct IDOverrideLibraryProperty *RNA_property_override_property_find(PointerRNA *ptr,
+struct IDOverrideLibraryProperty *RNA_property_override_property_find(struct Main *bmain,
+ PointerRNA *ptr,
PropertyRNA *prop,
struct ID **r_owner_id);
-struct IDOverrideLibraryProperty *RNA_property_override_property_get(PointerRNA *ptr,
+struct IDOverrideLibraryProperty *RNA_property_override_property_get(struct Main *bmain,
+ PointerRNA *ptr,
PropertyRNA *prop,
bool *r_created);
struct IDOverrideLibraryPropertyOperation *RNA_property_override_property_operation_find(
- PointerRNA *ptr, PropertyRNA *prop, const int index, const bool strict, bool *r_strict);
+ struct Main *bmain,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ const int index,
+ const bool strict,
+ bool *r_strict);
struct IDOverrideLibraryPropertyOperation *RNA_property_override_property_operation_get(
+ struct Main *bmain,
PointerRNA *ptr,
PropertyRNA *prop,
const short operation,
@@ -1502,7 +1510,8 @@ struct IDOverrideLibraryPropertyOperation *RNA_property_override_property_operat
bool *r_strict,
bool *r_created);
-eRNAOverrideStatus RNA_property_override_library_status(PointerRNA *ptr,
+eRNAOverrideStatus RNA_property_override_library_status(struct Main *bmainm,
+ PointerRNA *ptr,
PropertyRNA *prop,
const int index);
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 1bcf7f434f2..ee1a3fdd539 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __RNA_DEFINE_H__
-#define __RNA_DEFINE_H__
+#pragma once
/** \file
* \ingroup RNA
@@ -531,5 +530,3 @@ extern const float rna_default_scale_3d[3];
#ifdef __cplusplus
}
#endif
-
-#endif /* __RNA_DEFINE_H__ */
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 0c462ba6766..fb9b62e729a 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __RNA_ENUM_TYPES_H__
-#define __RNA_ENUM_TYPES_H__
+#pragma once
/** \file
* \ingroup RNA
@@ -323,5 +322,3 @@ const EnumPropertyItem *RNA_enum_node_tree_types_itemf_impl(struct bContext *C,
#ifdef __cplusplus
}
#endif
-
-#endif /* __RNA_ENUM_TYPES_H__ */
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 980e3eadd34..0b43a5a6653 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -69,6 +69,7 @@ set(DEFSRC
rna_packedfile.c
rna_palette.c
rna_particle.c
+ rna_pointcloud.c
rna_pose.c
rna_render.c
rna_rigidbody.c
@@ -82,7 +83,6 @@ set(DEFSRC
rna_sound.c
rna_space.c
rna_speaker.c
- rna_pointcloud.c
rna_test.c
rna_text.c
rna_texture.c
@@ -151,6 +151,16 @@ endif()
unset(GENSRC_CFLAGS)
+# NOTE: Disable clang-tidy because generated files are stored outside of the source,
+# so the clang-tidy can not find our .clang-tidy and fall-backs to own set of rules
+# which are too noisy for Blender.
+#
+# In the future clang-tidy would either need to be inlined checks and passed via the
+# command line (instead of using .clang-tidy file). Or, maybe, there is a way to
+# pass configuration file to the clang-tidy command.
+unset(CMAKE_C_CLANG_TIDY)
+unset(CMAKE_CXX_CLANG_TIDY)
+
set(SRC_RNA_INC
../RNA_access.h
../RNA_define.h
@@ -165,6 +175,7 @@ set(SRC
${DEFSRC}
${APISRC}
../../../../intern/clog/clog.c
+ ../../../../intern/guardedalloc/intern/leak_detector.cc
../../../../intern/guardedalloc/intern/mallocn.c
../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c
../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -350,7 +361,7 @@ blender_include_dirs(
../../imbuf
../../makesdna
../../nodes/
- ../../physics
+ ../../simulation
../../windowmanager
../../editors/include
../../render/extern/include
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 59087df16dd..bebb3a49c04 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -29,6 +29,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_system.h" /* for 'BLI_system_backtrace' stub. */
#include "BLI_utildefines.h"
#include "RNA_define.h"
@@ -96,8 +97,9 @@ static void rna_generate_static_parameter_prototypes(FILE *f,
/* helpers */
#define WRITE_COMMA \
{ \
- if (!first) \
+ if (!first) { \
fprintf(f, ", "); \
+ } \
first = 0; \
} \
(void)0
@@ -118,10 +120,12 @@ static int replace_if_different(const char *tmpfile, const char *dep_files[])
FILE *file_test = fopen(orgfile, "rb"); \
if (file_test) { \
fclose(file_test); \
- if (fp_org) \
+ if (fp_org) { \
fclose(fp_org); \
- if (fp_new) \
+ } \
+ if (fp_new) { \
fclose(fp_new); \
+ } \
if (remove(orgfile) != 0) { \
CLOG_ERROR(&LOG, "remove error (%s): \"%s\"", strerror(errno), orgfile); \
return -1; \
@@ -1080,21 +1084,26 @@ static char *rna_def_property_set_func(
if (prop->flag & PROP_ID_SELF_CHECK) {
rna_print_id_get(f, dp);
- fprintf(f, " if (id == value.data) return;\n\n");
+ fprintf(f, " if (id == value.data) {\n");
+ fprintf(f, " return;\n");
+ fprintf(f, " }\n");
}
if (prop->flag & PROP_ID_REFCOUNT) {
- fprintf(f, "\n if (data->%s)\n", dp->dnaname);
+ fprintf(f, "\n if (data->%s) {\n", dp->dnaname);
fprintf(f, " id_us_min((ID *)data->%s);\n", dp->dnaname);
- fprintf(f, " if (value.data)\n");
- fprintf(f, " id_us_plus((ID *)value.data);\n\n");
+ fprintf(f, " }\n");
+ fprintf(f, " if (value.data) {\n");
+ fprintf(f, " id_us_plus((ID *)value.data);\n");
+ fprintf(f, " }\n");
}
else {
PointerPropertyRNA *pprop = (PointerPropertyRNA *)dp->prop;
StructRNA *type = (pprop->type) ? rna_find_struct((const char *)pprop->type) : NULL;
if (type && (type->flag & STRUCT_ID)) {
- fprintf(f, " if (value.data)\n");
- fprintf(f, " id_lib_extern((ID *)value.data);\n\n");
+ fprintf(f, " if (value.data) {\n");
+ fprintf(f, " id_lib_extern((ID *)value.data);\n");
+ fprintf(f, " }\n");
}
}
@@ -1141,14 +1150,14 @@ static char *rna_def_property_set_func(
if (dp->dnaarraylength == 1) {
if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
fprintf(f,
- " if (%svalues[i]) data->%s |= (",
+ " if (%svalues[i]) { data->%s |= (",
(dp->booleannegative) ? "!" : "",
dp->dnaname);
rna_int_print(f, dp->booleanbit);
- fprintf(f, " << i);\n");
- fprintf(f, " else data->%s &= ~(", dp->dnaname);
+ fprintf(f, " << i); }\n");
+ fprintf(f, " else { data->%s &= ~(", dp->dnaname);
rna_int_print(f, dp->booleanbit);
- fprintf(f, " << i);\n");
+ fprintf(f, " << i); }\n");
}
else {
fprintf(
@@ -1159,14 +1168,14 @@ static char *rna_def_property_set_func(
else {
if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
fprintf(f,
- " if (%svalues[i]) data->%s[i] |= ",
+ " if (%svalues[i]) { data->%s[i] |= ",
(dp->booleannegative) ? "!" : "",
dp->dnaname);
rna_int_print(f, dp->booleanbit);
- fprintf(f, ";\n");
- fprintf(f, " else data->%s[i] &= ~", dp->dnaname);
+ fprintf(f, "; }\n");
+ fprintf(f, " else { data->%s[i] &= ~", dp->dnaname);
rna_int_print(f, dp->booleanbit);
- fprintf(f, ";\n");
+ fprintf(f, "; }\n");
}
else if (rna_color_quantize(prop, dp)) {
fprintf(
@@ -1215,13 +1224,15 @@ static char *rna_def_property_set_func(
else {
rna_print_data_get(f, dp);
if (prop->type == PROP_BOOLEAN && dp->booleanbit) {
- fprintf(
- f, " if (%svalue) data->%s |= ", (dp->booleannegative) ? "!" : "", dp->dnaname);
+ fprintf(f,
+ " if (%svalue) { data->%s |= ",
+ (dp->booleannegative) ? "!" : "",
+ dp->dnaname);
rna_int_print(f, dp->booleanbit);
- fprintf(f, ";\n");
- fprintf(f, " else data->%s &= ~", dp->dnaname);
+ fprintf(f, "; }\n");
+ fprintf(f, " else { data->%s &= ~", dp->dnaname);
rna_int_print(f, dp->booleanbit);
- fprintf(f, ";\n");
+ fprintf(f, "; }\n");
}
else if (prop->type == PROP_ENUM && dp->enumbitflags) {
fprintf(f, " data->%s &= ~", dp->dnaname);
@@ -1278,7 +1289,7 @@ static char *rna_def_property_length_func(
else {
rna_print_data_get(f, dp);
if (!(prop->flag & PROP_NEVER_NULL)) {
- fprintf(f, " if (data->%s == NULL) return 0;\n", dp->dnaname);
+ fprintf(f, " if (data->%s == NULL) { return 0; }\n", dp->dnaname);
}
fprintf(f, " return strlen(data->%s);\n", dp->dnaname);
}
@@ -1393,8 +1404,9 @@ static char *rna_def_property_begin_func(
getfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
- fprintf(f, "\n if (iter->valid)\n");
- fprintf(f, " iter->ptr = %s(iter);\n", getfunc);
+ fprintf(f, "\n if (iter->valid) {\n");
+ fprintf(f, " iter->ptr = %s(iter);", getfunc);
+ fprintf(f, "\n }\n");
fprintf(f, "}\n\n");
@@ -1479,14 +1491,15 @@ static char *rna_def_property_lookup_int_func(FILE *f,
fprintf(f, " found = (index == -1 && iter.valid);\n");
fprintf(f, " }\n");
fprintf(f, " else {\n");
- fprintf(f, " while (index-- > 0 && internal->link)\n");
+ fprintf(f, " while (index-- > 0 && internal->link) {\n");
fprintf(f, " internal->link = internal->link->next;\n");
+ fprintf(f, " }\n");
fprintf(f, " found = (index == -1 && internal->link);\n");
fprintf(f, " }\n");
}
fprintf(f,
- " if (found) *r_ptr = %s_%s_get(&iter);\n",
+ " if (found) { *r_ptr = %s_%s_get(&iter); }\n",
srna->identifier,
rna_safe_id(prop->identifier));
fprintf(f, " }\n\n");
@@ -1672,8 +1685,9 @@ static char *rna_def_property_next_func(FILE *f,
getfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
- fprintf(f, "\n if (iter->valid)\n");
- fprintf(f, " iter->ptr = %s(iter);\n", getfunc);
+ fprintf(f, "\n if (iter->valid) {\n");
+ fprintf(f, " iter->ptr = %s(iter);", getfunc);
+ fprintf(f, "\n }\n");
fprintf(f, "}\n\n");
@@ -5131,7 +5145,10 @@ static void mem_error_cb(const char *errorStr)
int main(int argc, char **argv)
{
- int totblock, return_status = 0;
+ int return_status = 0;
+
+ MEM_init_memleak_detection();
+ MEM_set_error_callback(mem_error_cb);
CLG_init();
@@ -5153,12 +5170,5 @@ int main(int argc, char **argv)
CLG_exit();
- totblock = MEM_get_memory_blocks_in_use();
- if (totblock != 0) {
- fprintf(stderr, "Error Totblock: %d\n", totblock);
- MEM_set_error_callback(mem_error_cb);
- MEM_printmemlist();
- }
-
return return_status;
}
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 46001f27fef..e9ca0d577ce 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -96,6 +96,7 @@ const EnumPropertyItem rna_enum_id_type_items[] = {
# include "BKE_font.h"
# include "BKE_global.h" /* XXX, remove me */
# include "BKE_idprop.h"
+# include "BKE_idtype.h"
# include "BKE_lib_override.h"
# include "BKE_lib_query.h"
# include "BKE_lib_remap.h"
@@ -518,7 +519,7 @@ static ID *rna_ID_copy(ID *id, Main *bmain)
static ID *rna_ID_override_create(ID *id, Main *bmain, bool remap_local_usages)
{
- if (!BKE_lib_override_library_is_enabled() || !ID_IS_OVERRIDABLE_LIBRARY(id)) {
+ if (!ID_IS_OVERRIDABLE_LIBRARY(id)) {
return NULL;
}
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 79cf993e0cc..793552c5c34 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -558,9 +558,15 @@ static PropertyRNA *arraytypemap[IDP_NUMTYPES] = {
(PropertyRNA *)&rna_PropertyGroupItem_double_array,
};
-static void *rna_idproperty_check_ex(PropertyRNA **prop,
- PointerRNA *ptr,
- const bool return_rnaprop)
+/* This function initializes a PropertyRNAOrID with all required info, from a given PropertyRNA
+ * and PointerRNA data. It deals properly with the three cases (static RNA, runtime RNA, and
+ * IDProperty).
+ * WARNING: given `ptr` PointerRNA is assumed to be a valid data one here, calling code is
+ * responsible to ensure that.
+ */
+void rna_property_rna_or_id_get(PropertyRNA *prop,
+ PointerRNA *ptr,
+ PropertyRNAOrID *r_prop_rna_or_id)
{
/* This is quite a hack, but avoids some complexity in the API. we
* pass IDProperty structs as PropertyRNA pointers to the outside.
@@ -568,36 +574,64 @@ static void *rna_idproperty_check_ex(PropertyRNA **prop,
* distinguish it from IDProperty structs. If it is an ID property,
* we look up an IDP PropertyRNA based on the type, and set the data
* pointer to the IDProperty. */
+ memset(r_prop_rna_or_id, 0, sizeof(*r_prop_rna_or_id));
- if ((*prop)->magic == RNA_MAGIC) {
- if ((*prop)->flag & PROP_IDPROPERTY) {
- IDProperty *idprop = rna_idproperty_find(ptr, (*prop)->identifier);
+ r_prop_rna_or_id->ptr = *ptr;
+ r_prop_rna_or_id->rawprop = prop;
+
+ if (prop->magic == RNA_MAGIC) {
+ r_prop_rna_or_id->rnaprop = prop;
+ r_prop_rna_or_id->identifier = prop->identifier;
- if (idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
+ r_prop_rna_or_id->is_array = prop->getlength || prop->totarraylength;
+ if (r_prop_rna_or_id->is_array) {
+ int arraylen[RNA_MAX_ARRAY_DIMENSION];
+ r_prop_rna_or_id->array_len = (prop->getlength && ptr->data) ?
+ (uint)prop->getlength(ptr, arraylen) :
+ prop->totarraylength;
+ }
+
+ if (prop->flag & PROP_IDPROPERTY) {
+ IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier);
+
+ if (idprop != NULL && !rna_idproperty_verify_valid(ptr, prop, idprop)) {
IDProperty *group = RNA_struct_idprops(ptr, 0);
IDP_FreeFromGroup(group, idprop);
- return NULL;
+ idprop = NULL;
}
- return idprop;
+ r_prop_rna_or_id->idprop = idprop;
+ r_prop_rna_or_id->is_set = idprop != NULL && (idprop->flag & IDP_FLAG_GHOST) == 0;
}
else {
- return return_rnaprop ? *prop : NULL;
+ /* Full static RNA properties are always set. */
+ r_prop_rna_or_id->is_set = true;
}
}
+ else {
+ IDProperty *idprop = (IDProperty *)prop;
+ /* Given prop may come from the custom properties of another data, ensure we get the one from
+ * given data ptr. */
+ IDProperty *idprop_evaluated = rna_idproperty_find(ptr, idprop->name);
+ if (idprop_evaluated != NULL && idprop->type != idprop_evaluated->type) {
+ idprop_evaluated = NULL;
+ }
- {
- IDProperty *idprop = (IDProperty *)(*prop);
+ r_prop_rna_or_id->idprop = idprop_evaluated;
+ r_prop_rna_or_id->is_idprop = true;
+ /* Full IDProperties are always set, if it exists. */
+ r_prop_rna_or_id->is_set = (idprop_evaluated != NULL);
+ r_prop_rna_or_id->identifier = idprop->name;
if (idprop->type == IDP_ARRAY) {
- *prop = arraytypemap[(int)(idprop->subtype)];
+ r_prop_rna_or_id->rnaprop = arraytypemap[(int)(idprop->subtype)];
+ r_prop_rna_or_id->is_array = true;
+ r_prop_rna_or_id->array_len = idprop_evaluated != NULL ? (uint)idprop_evaluated->len : 0;
}
else {
- *prop = typemap[(int)(idprop->type)];
+ r_prop_rna_or_id->rnaprop = typemap[(int)(idprop->type)];
}
-
- return idprop;
}
}
@@ -605,14 +639,26 @@ static void *rna_idproperty_check_ex(PropertyRNA **prop,
* or NULL (in case IDProp could not be found, or prop is a real RNA property). */
IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
{
- return rna_idproperty_check_ex(prop, ptr, false);
+ PropertyRNAOrID prop_rna_or_id;
+
+ rna_property_rna_or_id_get(*prop, ptr, &prop_rna_or_id);
+
+ *prop = prop_rna_or_id.rnaprop;
+ return prop_rna_or_id.idprop;
}
/* This function always return the valid, real data pointer, be it a regular RNA property one,
* or an IDProperty one. */
PropertyRNA *rna_ensure_property_realdata(PropertyRNA **prop, PointerRNA *ptr)
{
- return rna_idproperty_check_ex(prop, ptr, true);
+ PropertyRNAOrID prop_rna_or_id;
+
+ rna_property_rna_or_id_get(*prop, ptr, &prop_rna_or_id);
+
+ *prop = prop_rna_or_id.rnaprop;
+ return (prop_rna_or_id.is_idprop || prop_rna_or_id.idprop != NULL) ?
+ (PropertyRNA *)prop_rna_or_id.idprop :
+ prop_rna_or_id.rnaprop;
}
PropertyRNA *rna_ensure_property(PropertyRNA *prop)
@@ -2102,9 +2148,7 @@ bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char *
return false;
}
if (ID_IS_OVERRIDE_LIBRARY(id)) {
- /* We need the real data property in case of IDProperty here... */
- PropertyRNA *real_prop = rna_ensure_property_realdata(&prop, ptr);
- if (real_prop == NULL || !RNA_property_overridable_get(ptr, real_prop)) {
+ if (!RNA_property_overridable_get(ptr, prop)) {
if (!(*r_info)[0]) {
*r_info = N_("Can't edit this property from an override data-block");
}
diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c
index 8cd8f80b7c8..0a739dcfc5a 100644
--- a/source/blender/makesrna/intern/rna_access_compare_override.c
+++ b/source/blender/makesrna/intern/rna_access_compare_override.c
@@ -61,7 +61,7 @@ bool RNA_property_overridable_get(PointerRNA *ptr, PropertyRNA *prop)
/* Special handling for insertions of constraints or modifiers... */
/* TODO Note We may want to add a more generic system to RNA
* (like a special property in struct of items)
- * if we get more override-able collections,
+ * if we get more overrideable collections,
* for now we can live with those special-cases handling I think. */
if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
bConstraint *con = ptr->data;
@@ -177,16 +177,13 @@ bool RNA_property_copy(
}
static int rna_property_override_diff(Main *bmain,
- PointerRNA *ptr_a,
- PointerRNA *ptr_b,
- PropertyRNA *prop,
- PropertyRNA *prop_a,
- PropertyRNA *prop_b,
+ PropertyRNAOrID *prop_a,
+ PropertyRNAOrID *prop_b,
const char *rna_path,
const size_t rna_path_len,
eRNACompareMode mode,
IDOverrideLibrary *override,
- const int flags,
+ const eRNAOverrideMatch flags,
eRNAOverrideMatchResult *r_report_flags);
bool RNA_property_equals(
@@ -194,8 +191,12 @@ bool RNA_property_equals(
{
BLI_assert(ELEM(mode, RNA_EQ_STRICT, RNA_EQ_UNSET_MATCH_ANY, RNA_EQ_UNSET_MATCH_NONE));
- return (rna_property_override_diff(
- bmain, ptr_a, ptr_b, prop, NULL, NULL, NULL, 0, mode, NULL, 0, NULL) == 0);
+ PropertyRNAOrID prop_a, prop_b;
+
+ rna_property_rna_or_id_get(prop, ptr_a, &prop_a);
+ rna_property_rna_or_id_get(prop, ptr_b, &prop_b);
+
+ return (rna_property_override_diff(bmain, &prop_a, &prop_b, NULL, 0, mode, NULL, 0, NULL) == 0);
}
bool RNA_struct_equals(Main *bmain, PointerRNA *ptr_a, PointerRNA *ptr_b, eRNACompareMode mode)
@@ -247,59 +248,42 @@ bool RNA_struct_equals(Main *bmain, PointerRNA *ptr_a, PointerRNA *ptr_b, eRNACo
* but we cannot determine an order (greater than/lesser than), we return 1.
*/
static int rna_property_override_diff(Main *bmain,
- PointerRNA *ptr_a,
- PointerRNA *ptr_b,
- PropertyRNA *prop,
- PropertyRNA *prop_a,
- PropertyRNA *prop_b,
+ PropertyRNAOrID *prop_a,
+ PropertyRNAOrID *prop_b,
const char *rna_path,
const size_t rna_path_len,
eRNACompareMode mode,
IDOverrideLibrary *override,
- const int flags,
+ const eRNAOverrideMatch flags,
eRNAOverrideMatchResult *r_report_flags)
{
- if (prop != NULL) {
- BLI_assert(prop_a == NULL && prop_b == NULL);
- prop_a = prop;
- prop_b = prop;
- }
+ BLI_assert(!ELEM(NULL, prop_a, prop_b));
- if (ELEM(NULL, prop_a, prop_b)) {
- return (prop_a == prop_b) ? 0 : 1;
- }
-
- if (!RNA_property_comparable(ptr_a, prop_a) || !RNA_property_comparable(ptr_b, prop_b)) {
+ if (prop_a->rnaprop->flag_override & PROPOVERRIDE_NO_COMPARISON ||
+ prop_b->rnaprop->flag_override & PROPOVERRIDE_NO_COMPARISON) {
return 0;
}
if (mode == RNA_EQ_UNSET_MATCH_ANY) {
- /* uninitialized properties are assumed to match anything */
- if (!RNA_property_is_set(ptr_a, prop_a) || !RNA_property_is_set(ptr_b, prop_b)) {
+ /* Unset properties are assumed to match anything. */
+ if (!prop_a->is_set || !prop_b->is_set) {
return 0;
}
}
else if (mode == RNA_EQ_UNSET_MATCH_NONE) {
- /* unset properties never match set properties */
- if (RNA_property_is_set(ptr_a, prop_a) != RNA_property_is_set(ptr_b, prop_b)) {
+ /* Unset properties never match set properties. */
+ if (prop_a->is_set != prop_b->is_set) {
return 1;
}
}
- if (prop != NULL) {
- /* Ensure we get real property data, be it an actual RNA property,
- * or an IDProperty in disguise. */
- prop_a = rna_ensure_property_realdata(&prop_a, ptr_a);
- prop_b = rna_ensure_property_realdata(&prop_b, ptr_b);
-
- if (ELEM(NULL, prop_a, prop_b)) {
- return (prop_a == prop_b) ? 0 : 1;
- }
+ if (prop_a->is_idprop && ELEM(NULL, prop_a->idprop, prop_b->idprop)) {
+ return (prop_a->idprop == prop_b->idprop) ? 0 : 1;
}
/* Check if we are working with arrays. */
- const bool is_array_a = RNA_property_array_check(prop_a);
- const bool is_array_b = RNA_property_array_check(prop_b);
+ const bool is_array_a = prop_a->is_array;
+ const bool is_array_b = prop_b->is_array;
if (is_array_a != is_array_b) {
/* Should probably never happen actually... */
@@ -308,8 +292,8 @@ static int rna_property_override_diff(Main *bmain,
}
/* Get the length of the array to work with. */
- const int len_a = RNA_property_array_length(ptr_a, prop_a);
- const int len_b = RNA_property_array_length(ptr_b, prop_b);
+ const uint len_a = prop_a->array_len;
+ const uint len_b = prop_b->array_len;
if (len_a != len_b) {
/* Do not handle override in that case,
@@ -324,47 +308,44 @@ static int rna_property_override_diff(Main *bmain,
RNAPropOverrideDiff override_diff = NULL;
/* Special case for IDProps, we use default callback then. */
- if (prop_a->magic != RNA_MAGIC) {
+ if (prop_a->is_idprop) {
override_diff = rna_property_override_diff_default;
- if (prop_b->magic == RNA_MAGIC && prop_b->override_diff != override_diff) {
+ if (!prop_b->is_idprop && prop_b->rnaprop->override_diff != override_diff) {
override_diff = NULL;
}
}
- else if (prop_b->magic != RNA_MAGIC) {
+ else if (prop_b->is_idprop) {
override_diff = rna_property_override_diff_default;
- if (prop_a->override_diff != override_diff) {
+ if (prop_a->rnaprop->override_diff != override_diff) {
override_diff = NULL;
}
}
- else if (prop_a->override_diff == prop_b->override_diff) {
- override_diff = prop_a->override_diff;
+ else if (prop_a->rnaprop->override_diff == prop_b->rnaprop->override_diff) {
+ override_diff = prop_a->rnaprop->override_diff;
+ if (override_diff == NULL) {
+ override_diff = rna_property_override_diff_default;
+ }
}
if (override_diff == NULL) {
#ifndef NDEBUG
printf("'%s' gives unmatching or NULL RNA diff callbacks, should not happen (%d vs. %d).\n",
- rna_path ?
- rna_path :
- (prop_a->magic != RNA_MAGIC ? ((IDProperty *)prop_a)->name : prop_a->identifier),
- prop_a->magic == RNA_MAGIC,
- prop_b->magic == RNA_MAGIC);
+ rna_path ? rna_path : prop_a->identifier,
+ !prop_a->is_idprop,
+ !prop_b->is_idprop);
#endif
BLI_assert(0);
return 1;
}
bool override_changed = false;
- int diff_flags = flags;
- if (!RNA_property_overridable_get(ptr_a, prop_a)) {
+ eRNAOverrideMatch diff_flags = flags;
+ if (!RNA_property_overridable_get(&prop_a->ptr, prop_a->rawprop)) {
diff_flags &= ~RNA_OVERRIDE_COMPARE_CREATE;
}
const int diff = override_diff(bmain,
- ptr_a,
- ptr_b,
prop_a,
prop_b,
- len_a,
- len_b,
mode,
override,
rna_path,
@@ -426,10 +407,13 @@ static bool rna_property_override_operation_store(Main *bmain,
}
else if (prop_local->override_store == prop_reference->override_store) {
override_store = prop_local->override_store;
+ if (override_store == NULL) {
+ override_store = rna_property_override_store_default;
+ }
}
if (ptr_storage != NULL && prop_storage->magic == RNA_MAGIC &&
- prop_storage->override_store != override_store) {
+ !ELEM(prop_storage->override_store, NULL, override_store)) {
override_store = NULL;
}
@@ -512,10 +496,13 @@ static bool rna_property_override_operation_apply(Main *bmain,
}
else if (prop_dst->override_apply == prop_src->override_apply) {
override_apply = prop_dst->override_apply;
+ if (override_apply == NULL) {
+ override_apply = rna_property_override_apply_default;
+ }
}
if (ptr_storage && prop_storage->magic == RNA_MAGIC &&
- prop_storage->override_apply != override_apply) {
+ !ELEM(prop_storage->override_apply, NULL, override_apply)) {
override_apply = NULL;
}
@@ -612,38 +599,29 @@ bool RNA_struct_override_matches(Main *bmain,
for (RNA_property_collection_begin(ptr_local, iterprop, &iter); iter.valid;
RNA_property_collection_next(&iter)) {
- PropertyRNA *prop_local = iter.ptr.data;
- PropertyRNA *prop_reference = iter.ptr.data;
-
- /* Ensure we get real property data, be it an actual RNA property,
- * or an IDProperty in disguise. */
- prop_local = rna_ensure_property_realdata(&prop_local, ptr_local);
- prop_reference = rna_ensure_property_realdata(&prop_reference, ptr_reference);
-
- /* IDProps (custom properties) are even more of a PITA here, we cannot use
- * `rna_ensure_property_realdata()` to deal with them, we have to use the path generated from
- * `prop_local` (which is valid) to access to the actual reference counterpart... */
- if (prop_local != NULL && prop_local->magic != RNA_MAGIC && prop_local == prop_reference) {
- /* We could also use (lower in this code, after rna_path has been computed):
- * RNA_path_resolve_property(ptr_reference, rna_path, &some_rna_ptr, &prop_reference);
- * But that would be much more costly, and would also fail when ptr_reference
- * is not an ID pointer itself, so we'd need to rebuild it from its owner_id, then check that
- * generated some_rna_ptr and ptr_reference do point to the same data, etc.
- * For now, let's try that simple access, it won't cover all cases but should handle fine
- * most basic custom properties situations. */
- prop_reference = (PropertyRNA *)rna_idproperty_find(ptr_reference,
- ((IDProperty *)prop_local)->name);
- }
+ PropertyRNA *rawprop = iter.ptr.data;
+
+ PropertyRNAOrID prop_local;
+ PropertyRNAOrID prop_reference;
- if (ELEM(NULL, prop_local, prop_reference)) {
+ rna_property_rna_or_id_get(rawprop, ptr_local, &prop_local);
+ rna_property_rna_or_id_get(rawprop, ptr_reference, &prop_reference);
+
+ BLI_assert(prop_local.rnaprop != NULL);
+ BLI_assert(prop_local.rnaprop == prop_reference.rnaprop);
+ BLI_assert(prop_local.is_idprop == prop_reference.is_idprop);
+
+ if ((prop_local.is_idprop && prop_local.idprop == NULL) ||
+ (prop_reference.is_idprop && prop_reference.idprop == NULL)) {
continue;
}
- if (ignore_non_overridable && !RNA_property_overridable_get(ptr_local, prop_local)) {
+ if (ignore_non_overridable && !RNA_property_overridable_get(&prop_local.ptr, rawprop)) {
continue;
}
- if (RNA_property_override_flag(prop_local) & PROPOVERRIDE_IGNORE) {
+ if (!prop_local.is_idprop &&
+ RNA_property_override_flag(prop_local.rnaprop) & PROPOVERRIDE_IGNORE) {
continue;
}
@@ -665,11 +643,11 @@ bool RNA_struct_override_matches(Main *bmain,
if (root_path) {
BLI_assert(strlen(root_path) == root_path_len);
- const char *prop_name = RNA_property_identifier(prop_local);
+ const char *prop_name = prop_local.identifier;
const size_t prop_name_len = strlen(prop_name);
/* Inlined building, much much more efficient. */
- if (prop_local->magic == RNA_MAGIC) {
+ if (!prop_local.is_idprop) {
rna_path_len = root_path_len + 1 + prop_name_len;
if (rna_path_len >= RNA_PATH_BUFFSIZE) {
rna_path = MEM_mallocN(rna_path_len + 1, __func__);
@@ -697,7 +675,7 @@ bool RNA_struct_override_matches(Main *bmain,
}
else {
/* This is rather slow, but is not much called, so not really worth optimizing. */
- rna_path = RNA_path_from_ID_to_property(ptr_local, prop_local);
+ rna_path = RNA_path_from_ID_to_property(ptr_local, rawprop);
if (rna_path != NULL) {
rna_path_len = strlen(rna_path);
}
@@ -726,11 +704,8 @@ bool RNA_struct_override_matches(Main *bmain,
eRNAOverrideMatchResult report_flags = 0;
const int diff = rna_property_override_diff(bmain,
- ptr_local,
- ptr_reference,
- NULL,
- prop_local,
- prop_reference,
+ &prop_local,
+ &prop_reference,
rna_path,
rna_path_len,
RNA_EQ_STRICT,
@@ -764,7 +739,7 @@ bool RNA_struct_override_matches(Main *bmain,
/* We are allowed to restore to reference's values. */
if (ELEM(NULL, op, opop) || opop->operation == IDOVERRIDE_LIBRARY_OP_NOOP) {
/* We should restore that property to its reference value */
- if (RNA_property_editable(ptr_local, prop_local)) {
+ if (RNA_property_editable(ptr_local, rawprop)) {
IDOverrideLibraryPropertyOperation opop_tmp = {
.operation = IDOVERRIDE_LIBRARY_OP_REPLACE,
.subitem_reference_index = -1,
@@ -774,8 +749,8 @@ bool RNA_struct_override_matches(Main *bmain,
ptr_local,
ptr_reference,
NULL,
- prop_local,
- prop_reference,
+ rawprop,
+ rawprop,
NULL,
NULL,
NULL,
@@ -1077,7 +1052,8 @@ void RNA_struct_override_apply(Main *bmain,
#endif
}
-static char *rna_property_override_property_real_id_owner(PointerRNA *ptr,
+static char *rna_property_override_property_real_id_owner(Main *bmain,
+ PointerRNA *ptr,
PropertyRNA *prop,
ID **r_id)
{
@@ -1104,10 +1080,9 @@ static char *rna_property_override_property_real_id_owner(PointerRNA *ptr,
rna_path_prefix = "shape_keys.";
break;
case ID_GR:
- /* Master collection, TODO. */
- break;
case ID_NT:
- /* Root node trees, TODO. */
+ /* Master collections, Root node trees. */
+ owner_id = RNA_find_real_ID_and_path(bmain, id, &rna_path_prefix);
break;
default:
BLI_assert(0);
@@ -1132,13 +1107,15 @@ static char *rna_property_override_property_real_id_owner(PointerRNA *ptr,
return NULL;
}
-IDOverrideLibraryProperty *RNA_property_override_property_find(PointerRNA *ptr,
+IDOverrideLibraryProperty *RNA_property_override_property_find(Main *bmain,
+ PointerRNA *ptr,
PropertyRNA *prop,
ID **r_owner_id)
{
char *rna_path;
- if ((rna_path = rna_property_override_property_real_id_owner(ptr, prop, r_owner_id)) != NULL) {
+ if ((rna_path = rna_property_override_property_real_id_owner(bmain, ptr, prop, r_owner_id)) !=
+ NULL) {
IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(
(*r_owner_id)->override_library, rna_path);
MEM_freeN(rna_path);
@@ -1147,14 +1124,15 @@ IDOverrideLibraryProperty *RNA_property_override_property_find(PointerRNA *ptr,
return NULL;
}
-IDOverrideLibraryProperty *RNA_property_override_property_get(PointerRNA *ptr,
+IDOverrideLibraryProperty *RNA_property_override_property_get(Main *bmain,
+ PointerRNA *ptr,
PropertyRNA *prop,
bool *r_created)
{
ID *id;
char *rna_path;
- if ((rna_path = rna_property_override_property_real_id_owner(ptr, prop, &id)) != NULL) {
+ if ((rna_path = rna_property_override_property_real_id_owner(bmain, ptr, prop, &id)) != NULL) {
IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
id->override_library, rna_path, r_created);
MEM_freeN(rna_path);
@@ -1164,10 +1142,15 @@ IDOverrideLibraryProperty *RNA_property_override_property_get(PointerRNA *ptr,
}
IDOverrideLibraryPropertyOperation *RNA_property_override_property_operation_find(
- PointerRNA *ptr, PropertyRNA *prop, const int index, const bool strict, bool *r_strict)
+ Main *bmain,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ const int index,
+ const bool strict,
+ bool *r_strict)
{
ID *owner_id;
- IDOverrideLibraryProperty *op = RNA_property_override_property_find(ptr, prop, &owner_id);
+ IDOverrideLibraryProperty *op = RNA_property_override_property_find(bmain, ptr, prop, &owner_id);
if (!op) {
return NULL;
@@ -1178,6 +1161,7 @@ IDOverrideLibraryPropertyOperation *RNA_property_override_property_operation_fin
}
IDOverrideLibraryPropertyOperation *RNA_property_override_property_operation_get(
+ Main *bmain,
PointerRNA *ptr,
PropertyRNA *prop,
const short operation,
@@ -1186,7 +1170,7 @@ IDOverrideLibraryPropertyOperation *RNA_property_override_property_operation_get
bool *r_strict,
bool *r_created)
{
- IDOverrideLibraryProperty *op = RNA_property_override_property_get(ptr, prop, NULL);
+ IDOverrideLibraryProperty *op = RNA_property_override_property_get(bmain, ptr, prop, NULL);
if (!op) {
return NULL;
@@ -1196,16 +1180,13 @@ IDOverrideLibraryPropertyOperation *RNA_property_override_property_operation_get
op, operation, NULL, NULL, index, index, strict, r_strict, r_created);
}
-eRNAOverrideStatus RNA_property_override_library_status(PointerRNA *ptr,
+eRNAOverrideStatus RNA_property_override_library_status(Main *bmain,
+ PointerRNA *ptr,
PropertyRNA *prop,
const int index)
{
uint override_status = 0;
- if (!BKE_lib_override_library_is_enabled()) {
- return override_status;
- }
-
if (!ptr || !prop || !ptr->owner_id || !ID_IS_OVERRIDE_LIBRARY(ptr->owner_id)) {
return override_status;
}
@@ -1215,7 +1196,7 @@ eRNAOverrideStatus RNA_property_override_library_status(PointerRNA *ptr,
}
IDOverrideLibraryPropertyOperation *opop = RNA_property_override_property_operation_find(
- ptr, prop, index, false, NULL);
+ bmain, ptr, prop, index, false, NULL);
if (opop != NULL) {
override_status |= RNA_OVERRIDE_STATUS_OVERRIDDEN;
if (opop->flag & IDOVERRIDE_LIBRARY_FLAG_MANDATORY) {
diff --git a/source/blender/makesrna/intern/rna_access_internal.h b/source/blender/makesrna/intern/rna_access_internal.h
index c7995746d08..73407123863 100644
--- a/source/blender/makesrna/intern/rna_access_internal.h
+++ b/source/blender/makesrna/intern/rna_access_internal.h
@@ -18,18 +18,18 @@
* \ingroup RNA
*/
-#ifndef __RNA_ACCESS_INTERNAL_H__
-#define __RNA_ACCESS_INTERNAL_H__
+#pragma once
#include "BLI_utildefines.h"
#include "rna_internal_types.h"
struct IDProperty;
+struct PropertyRNAOrID;
-PropertyRNA *rna_ensure_property(PropertyRNA *prop);
+void rna_property_rna_or_id_get(PropertyRNA *prop,
+ PointerRNA *ptr,
+ PropertyRNAOrID *r_prop_rna_or_id);
void rna_idproperty_touch(struct IDProperty *idprop);
struct IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name);
-
-#endif /* __ACCESS_RNA_INTERNAL_H__ */
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index b139e4609cd..11b563dae52 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -237,12 +237,27 @@ static EnumPropertyItem rna_enum_gpencil_fill_draw_modes_items[] = {
{GP_FILL_DMODE_BOTH,
"BOTH",
0,
- "Default",
+ "All",
"Use both visible strokes and edit lines as fill boundary limits"},
{GP_FILL_DMODE_STROKE, "STROKE", 0, "Strokes", "Use visible strokes as fill boundary limits"},
{GP_FILL_DMODE_CONTROL, "CONTROL", 0, "Edit Lines", "Use edit lines as fill boundary limits"},
{0, NULL, 0, NULL, NULL}};
+static EnumPropertyItem rna_enum_gpencil_fill_layers_modes_items[] = {
+ {GP_FILL_GPLMODE_VISIBLE, "VISIBLE", 0, "Visible", "Visible layers"},
+ {GP_FILL_GPLMODE_ACTIVE, "ACTIVE", 0, "Active", "Only active layer"},
+ {GP_FILL_GPLMODE_ABOVE, "ABOVE", 0, "Layer Above", "Layer above active"},
+ {GP_FILL_GPLMODE_BELOW, "BELOW", 0, "Layer Below", "Layer below active"},
+ {GP_FILL_GPLMODE_ALL_ABOVE, "ALL_ABOVE", 0, "All Above", "All layers above active"},
+ {GP_FILL_GPLMODE_ALL_BELOW, "ALL_BELOW", 0, "All Below", "All layers below active"},
+ {0, NULL, 0, NULL, NULL}};
+
+static EnumPropertyItem rna_enum_gpencil_brush_modes_items[] = {
+ {GP_BRUSH_MODE_ACTIVE, "ACTIVE", 0, "Active", "Use current mode"},
+ {GP_BRUSH_MODE_MATERIAL, "MATERIAL", 0, "Material", "Use always material mode"},
+ {GP_BRUSH_MODE_VERTEXCOLOR, "VERTEXCOLOR", 0, "Vertex Color", "Use always Vertex Color mode"},
+ {0, NULL, 0, NULL, NULL}};
+
static EnumPropertyItem rna_enum_gpencil_brush_paint_icons_items[] = {
{GP_BRUSH_ICON_PENCIL, "PENCIL", ICON_GPBRUSH_PENCIL, "Pencil", ""},
{GP_BRUSH_ICON_PEN, "PEN", ICON_GPBRUSH_PEN, "Pen", ""},
@@ -359,7 +374,7 @@ static bool rna_BrushCapabilities_has_overlay_get(PointerRNA *ptr)
static bool rna_BrushCapabilitiesSculpt_has_persistence_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
- return br->sculpt_tool == SCULPT_TOOL_LAYER;
+ return ELEM(br->sculpt_tool, SCULPT_TOOL_LAYER, SCULPT_TOOL_CLOTH);
}
static bool rna_BrushCapabilitiesSculpt_has_pinch_factor_get(PointerRNA *ptr)
@@ -1519,7 +1534,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
prop = RNA_def_property(srna, "use_strength_pressure", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_STENGTH_PRESSURE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_STRENGTH_PRESSURE);
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
RNA_def_property_ui_text(
prop, "Use Pressure Strength", "Use tablet pressure for color strength");
@@ -1640,6 +1655,18 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mode", "Mode to draw boundary limits");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ prop = RNA_def_property(srna, "fill_layer_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "fill_layer_mode");
+ RNA_def_property_enum_items(prop, rna_enum_gpencil_fill_layers_modes_items);
+ RNA_def_property_ui_text(prop, "Layer Mode", "Layers used as boundaries");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
+ prop = RNA_def_property(srna, "brush_draw_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "brush_draw_mode");
+ RNA_def_property_enum_items(prop, rna_enum_gpencil_brush_modes_items);
+ RNA_def_property_ui_text(prop, "Mode", "Preselected mode when using this brush");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
prop = RNA_def_property(srna, "trim", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_TRIM_STROKE);
RNA_def_property_boolean_default(prop, false);
@@ -1956,6 +1983,16 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem brush_cloth_simulation_area_type_items[] = {
+ {BRUSH_CLOTH_SIMULATION_AREA_LOCAL,
+ "LOCAL",
+ 0,
+ "Local",
+ "Simulates only a specific area arround the brush limited by a fixed radius"},
+ {BRUSH_CLOTH_SIMULATION_AREA_GLOBAL, "GLOBAL", 0, "Global", "Simulates the entire mesh"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
static const EnumPropertyItem brush_smooth_deform_type_items[] = {
{BRUSH_SMOOTH_DEFORM_LAPLACIAN,
"LAPLACIAN",
@@ -1973,7 +2010,7 @@ static void rna_def_brush(BlenderRNA *brna)
static const EnumPropertyItem brush_pose_deform_type_items[] = {
{BRUSH_POSE_DEFORM_ROTATE_TWIST, "ROTATE_TWIST", 0, "Rotate/Twist", ""},
{BRUSH_POSE_DEFORM_SCALE_TRASLATE, "SCALE_TRANSLATE", 0, "Scale/Translate", ""},
- {BRUSH_POSE_DEFORM_SQUASH_STRETCH, "SQUASH_STRETCH", 0, "Squash/Stretch", ""},
+ {BRUSH_POSE_DEFORM_SQUASH_STRETCH, "SQUASH_STRETCH", 0, "Squash & Stretch", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -1997,6 +2034,20 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem brush_smear_deform_type_items[] = {
+ {BRUSH_SMEAR_DEFORM_DRAG, "DRAG", 0, "Drag", ""},
+ {BRUSH_SMEAR_DEFORM_PINCH, "PINCH", 0, "Pinch", ""},
+ {BRUSH_SMEAR_DEFORM_EXPAND, "EXPAND", 0, "Expand", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ static const EnumPropertyItem brush_slide_deform_type_items[] = {
+ {BRUSH_SLIDE_DEFORM_DRAG, "DRAG", 0, "Drag", ""},
+ {BRUSH_SLIDE_DEFORM_PINCH, "PINCH", 0, "Pinch", ""},
+ {BRUSH_SLIDE_DEFORM_EXPAND, "EXPAND", 0, "Expand", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
srna = RNA_def_struct(brna, "Brush", "ID");
RNA_def_struct_ui_text(
srna, "Brush", "Brush data-block for storing brush settings for painting and sculpting");
@@ -2112,11 +2163,29 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Force Falloff", "Shape used in the brush to apply force to the cloth");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "cloth_simulation_area_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_cloth_simulation_area_type_items);
+ RNA_def_property_ui_text(
+ prop,
+ "Simulation Area",
+ "Part of the mesh that is going to be simulated when the stroke is active");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "smooth_deform_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, brush_smooth_deform_type_items);
RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "smear_deform_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_smear_deform_type_items);
+ RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "slide_deform_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_slide_deform_type_items);
+ RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "pose_deform_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, brush_pose_deform_type_items);
RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
@@ -2253,7 +2322,7 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(
prop,
"Wet Persistence",
- "Amount of wet paint that stays in the brush after applyig paint to the surface");
+ "Amount of wet paint that stays in the brush after applying paint to the surface");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_FACTOR);
@@ -2271,6 +2340,84 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Tip Scale X", "Scale of the brush tip in the X axis");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "use_hardness_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_HARDNESS_PRESSURE);
+ RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
+ RNA_def_property_ui_text(prop, "Use Pressure for Hardness", "Use pressure to modulate hardness");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "invert_hardness_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_HARDNESS_PRESSURE_INVERT);
+ RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0);
+ RNA_def_property_ui_text(
+ prop, "Invert Pressure for Hardness", "Invert the modulation of pressure in hardness");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "use_flow_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_FLOW_PRESSURE);
+ RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
+ RNA_def_property_ui_text(prop, "Use Pressure for Flow", "Use pressure to modulate flow");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "invert_flow_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_FLOW_PRESSURE_INVERT);
+ RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0);
+ RNA_def_property_ui_text(
+ prop, "Invert Pressure for Flow", "Invert the modulation of pressure in flow");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "use_wet_mix_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_WET_MIX_PRESSURE);
+ RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
+ RNA_def_property_ui_text(prop, "Use Pressure for Wet Mix", "Use pressure to modulate wet mix");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "invert_wet_mix_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_WET_MIX_PRESSURE_INVERT);
+ RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0);
+ RNA_def_property_ui_text(
+ prop, "Invert Pressure for Wet Mix", "Invert the modulation of pressure in wet mix");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "use_wet_persistence_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_WET_PERSISTENCE_PRESSURE);
+ RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
+ RNA_def_property_ui_text(
+ prop, "Use Pressure for Wet Persistence", "Use pressure to modulate wet persistence");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "invert_wet_persistence_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(
+ prop, NULL, "paint_flags", BRUSH_PAINT_WET_PERSISTENCE_PRESSURE_INVERT);
+ RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0);
+ RNA_def_property_ui_text(prop,
+ "Invert Pressure for Wet Persistence",
+ "Invert the modulation of pressure in wet persistence");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "use_density_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_DENSITY_PRESSURE);
+ RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
+ RNA_def_property_ui_text(prop, "Use Pressure for Density", "Use pressure to modulate density");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "invert_density_pressure", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "paint_flags", BRUSH_PAINT_DENSITY_PRESSURE_INVERT);
+ RNA_def_property_ui_icon(prop, ICON_ARROW_LEFTRIGHT, 0);
+ RNA_def_property_ui_text(
+ prop, "Invert Pressure for Density", "Invert the modulation of pressure in density");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "dash_ratio", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "dash_ratio");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -2454,6 +2601,15 @@ static void rna_def_brush(BlenderRNA *brna)
"Area to apply deformation falloff to the effects of the simulation");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "cloth_constraint_softbody_strength", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "cloth_constraint_softbody_strength");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(
+ prop,
+ "Soft Body Influence",
+ "How much the simulation preserves the original shape, acting as a soft body");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "hardness", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "hardness");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -2665,11 +2821,32 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Keep Anchor Point", "Keep the position of the last segment in the IK chain fixed");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "use_pose_lock_rotation", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_POSE_USE_LOCK_ROTATION);
+ RNA_def_property_ui_text(prop,
+ "Lock Rotation When Scaling",
+ "Do not rotate the segment when using the scale deform mode");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "use_connected_only", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_USE_CONNECTED_ONLY);
RNA_def_property_ui_text(prop, "Connected Only", "Affect only topologically connected elements");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "use_cloth_pin_simulation_boundary", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY);
+ RNA_def_property_ui_text(
+ prop,
+ "Pin Simulation Boundary",
+ "Lock the position of the vertices in the simulation falloff area to avoid artifacts and "
+ "create a softer transitionwith with unnafected areas");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "use_cloth_collision", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_CLOTH_USE_COLLISION);
+ RNA_def_property_ui_text(prop, "Enable Collision", "Collide with objects during the simulation");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "invert_to_scrape_fill", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_INVERT_TO_SCRAPE_FILL);
RNA_def_property_ui_text(prop,
diff --git a/source/blender/makesrna/intern/rna_cachefile.c b/source/blender/makesrna/intern/rna_cachefile.c
index f9275ef1993..c25cea1b4b3 100644
--- a/source/blender/makesrna/intern/rna_cachefile.c
+++ b/source/blender/makesrna/intern/rna_cachefile.c
@@ -174,6 +174,32 @@ static void rna_def_cachefile(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Object Paths", "Paths of the objects inside the Alembic archive");
+ /* ----------------- Alembic Velocity Attribute ----------------- */
+
+ prop = RNA_def_property(srna, "velocity_name", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop,
+ "Velocity Attribute",
+ "Name of the Alembic attribute used for generating motion blur data");
+ RNA_def_property_update(prop, 0, "rna_CacheFile_update");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
+ static const EnumPropertyItem velocity_unit_items[] = {
+ {CACHEFILE_VELOCITY_UNIT_SECOND, "SECOND", 0, "Second", ""},
+ {CACHEFILE_VELOCITY_UNIT_FRAME, "FRAME", 0, "Frame", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ prop = RNA_def_property(srna, "velocity_unit", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "velocity_unit");
+ RNA_def_property_enum_items(prop, velocity_unit_items);
+ RNA_def_property_ui_text(
+ prop,
+ "Velocity Unit",
+ "Define how the velocity vectors are interpreted with regard to time, 'frame' means "
+ "the delta time is 1 frame, 'second' means the delta time is 1 / FPS");
+ RNA_def_property_update(prop, 0, "rna_CacheFile_update");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
RNA_define_lib_overridable(false);
rna_def_cachefile_object_paths(brna, prop);
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 594b77ea1ad..e99bd531c65 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -34,7 +34,7 @@
#include "BKE_cloth.h"
#include "BKE_modifier.h"
-#include "BPH_mass_spring.h"
+#include "SIM_mass_spring.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -482,18 +482,18 @@ static void rna_def_cloth_solver_result(BlenderRNA *brna)
PropertyRNA *prop;
static const EnumPropertyItem status_items[] = {
- {BPH_SOLVER_SUCCESS, "SUCCESS", 0, "Success", "Computation was successful"},
- {BPH_SOLVER_NUMERICAL_ISSUE,
+ {SIM_SOLVER_SUCCESS, "SUCCESS", 0, "Success", "Computation was successful"},
+ {SIM_SOLVER_NUMERICAL_ISSUE,
"NUMERICAL_ISSUE",
0,
"Numerical Issue",
"The provided data did not satisfy the prerequisites"},
- {BPH_SOLVER_NO_CONVERGENCE,
+ {SIM_SOLVER_NO_CONVERGENCE,
"NO_CONVERGENCE",
0,
"No Convergence",
"Iterative procedure did not converge"},
- {BPH_SOLVER_INVALID_INPUT,
+ {SIM_SOLVER_INVALID_INPUT,
"INVALID_INPUT",
0,
"Invalid Input",
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 56ad8e2677b..60b6cc40792 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -702,7 +702,7 @@ static float rna_CurveMapping_evaluateF(struct CurveMapping *cumap,
static void rna_CurveMap_initialize(struct CurveMapping *cumap)
{
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
}
#else
diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c
index c8abf774561..e6dceb5af72 100644
--- a/source/blender/makesrna/intern/rna_context.c
+++ b/source/blender/makesrna/intern/rna_context.c
@@ -41,7 +41,7 @@ const EnumPropertyItem rna_enum_context_mode_items[] = {
{CTX_MODE_EDIT_ARMATURE, "EDIT_ARMATURE", 0, "Armature Edit", ""},
{CTX_MODE_EDIT_METABALL, "EDIT_METABALL", 0, "Metaball Edit", ""},
{CTX_MODE_EDIT_LATTICE, "EDIT_LATTICE", 0, "Lattice Edit", ""},
- {CTX_MODE_POSE, "POSE", 0, "Pose ", ""},
+ {CTX_MODE_POSE, "POSE", 0, "Pose", ""},
{CTX_MODE_SCULPT, "SCULPT", 0, "Sculpt", ""},
{CTX_MODE_PAINT_WEIGHT, "PAINT_WEIGHT", 0, "Weight Paint", ""},
{CTX_MODE_PAINT_VERTEX, "PAINT_VERTEX", 0, "Vertex Paint", ""},
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 771235c85aa..1768d79fe8f 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -570,7 +570,7 @@ static void rna_Curve_body_set(PointerRNA *ptr, const char *value)
Curve *cu = (Curve *)ptr->owner_id;
- cu->len_wchar = len_chars;
+ cu->len_char32 = len_chars;
cu->len = len_bytes;
cu->pos = len_chars;
@@ -1191,9 +1191,9 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_ui_text(
prop,
"Object Font",
- "Use Objects as font characters (give font objects a common name "
+ "Use objects as font characters (give font objects a common name "
"followed by the character they represent, eg. 'family-a', 'family-b', etc, "
- "set this setting to 'family-', and turn on Vertex Duplication)");
+ "set this setting to 'family-', and turn on Vertex Instancing)");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE);
@@ -1206,7 +1206,7 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop = RNA_def_property(srna, "body_format", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "strinfo", "len_wchar");
+ RNA_def_property_collection_sdna(prop, NULL, "strinfo", "len_char32");
RNA_def_property_struct_type(prop, "TextCharacterFormat");
RNA_def_property_ui_text(prop, "Character Info", "Stores the style of each character");
diff --git a/source/blender/makesrna/intern/rna_curve_api.c b/source/blender/makesrna/intern/rna_curve_api.c
index 1207f19b95f..94fdb130026 100644
--- a/source/blender/makesrna/intern/rna_curve_api.c
+++ b/source/blender/makesrna/intern/rna_curve_api.c
@@ -37,7 +37,7 @@
#ifdef RNA_RUNTIME
static void rna_Curve_transform(Curve *cu, float *mat, bool shape_keys)
{
- BKE_curve_transform(cu, (float(*)[4])mat, shape_keys, true);
+ BKE_curve_transform(cu, (const float(*)[4])mat, shape_keys, true);
DEG_id_tag_update(&cu->id, 0);
}
diff --git a/source/blender/makesrna/intern/rna_curveprofile.c b/source/blender/makesrna/intern/rna_curveprofile.c
index ce91fc79085..ee1c659fcd5 100644
--- a/source/blender/makesrna/intern/rna_curveprofile.c
+++ b/source/blender/makesrna/intern/rna_curveprofile.c
@@ -146,7 +146,7 @@ static void rna_CurveProfile_evaluate(struct CurveProfile *profile,
static void rna_CurveProfile_initialize(struct CurveProfile *profile, int segments_len)
{
- BKE_curveprofile_initialize(profile, (short)segments_len);
+ BKE_curveprofile_init(profile, (short)segments_len);
}
static void rna_CurveProfile_update(struct CurveProfile *profile)
diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c
index ca34f69ab1e..da1ed166eb2 100644
--- a/source/blender/makesrna/intern/rna_depsgraph.c
+++ b/source/blender/makesrna/intern/rna_depsgraph.c
@@ -551,7 +551,7 @@ static void rna_def_depsgraph_instance(BlenderRNA *brna)
prop,
"Persistent ID",
"Persistent identifier for inter-frame matching of objects with motion blur");
- RNA_def_property_array(prop, 2 * MAX_DUPLI_RECUR);
+ RNA_def_property_array(prop, MAX_DUPLI_RECUR);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_DepsgraphObjectInstance_persistent_id_get", NULL, NULL);
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 3ae16f8577a..d5449a69cf6 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1635,7 +1635,7 @@ static void rna_def_fmodifier(BlenderRNA *brna)
/* 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);
- RNA_def_property_ui_text(prop, "Active", "F-Curve Modifier is the one being edited ");
+ RNA_def_property_ui_text(prop, "Active", "F-Curve Modifier is the one being edited");
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);
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index ab0cc6def6f..0a58f8af593 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -161,7 +161,7 @@ static void rna_Fluid_flow_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
rna_Fluid_update(bmain, scene, ptr);
}
-static void rna_Fluid_domain_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Fluid_domain_data_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
{
# ifdef WITH_FLUID
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
@@ -172,6 +172,39 @@ static void rna_Fluid_domain_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
rna_Fluid_update(bmain, scene, ptr);
}
+static void rna_Fluid_domain_noise_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+# ifdef WITH_FLUID
+ FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
+ BKE_fluid_modifier_reset(settings->fmd);
+# endif
+
+ rna_Fluid_noisecache_reset(bmain, scene, ptr);
+ rna_Fluid_update(bmain, scene, ptr);
+}
+
+static void rna_Fluid_domain_mesh_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+# ifdef WITH_FLUID
+ FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
+ BKE_fluid_modifier_reset(settings->fmd);
+# endif
+
+ rna_Fluid_meshcache_reset(bmain, scene, ptr);
+ rna_Fluid_update(bmain, scene, ptr);
+}
+
+static void rna_Fluid_domain_particles_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+# ifdef WITH_FLUID
+ FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
+ BKE_fluid_modifier_reset(settings->fmd);
+# endif
+
+ rna_Fluid_particlescache_reset(bmain, scene, ptr);
+ rna_Fluid_update(bmain, scene, ptr);
+}
+
static void rna_Fluid_reset_dependency(Main *bmain, Scene *scene, PointerRNA *ptr)
{
# ifdef WITH_FLUID
@@ -232,7 +265,7 @@ static void rna_Fluid_flip_parts_update(Main *bmain, Scene *scene, PointerRNA *p
if (fmd->domain->type != FLUID_DOMAIN_TYPE_LIQUID) {
rna_Fluid_parts_delete(ptr, PART_FLUID_FLIP);
fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_FLIP;
- rna_Fluid_domain_reset(bmain, scene, ptr);
+ rna_Fluid_domain_data_reset(bmain, scene, ptr);
return;
}
@@ -685,10 +718,10 @@ static int rna_FluidModifier_grid_get_length(PointerRNA *ptr, int length[RNA_MAX
/* high resolution smoke */
int res[3];
- manta_smoke_turbulence_get_res(fds->fluid, res);
+ manta_noise_get_res(fds->fluid, res);
size = res[0] * res[1] * res[2];
- density = manta_smoke_turbulence_get_density(fds->fluid);
+ density = manta_noise_get_density(fds->fluid);
}
else if (fds->fluid) {
/* regular resolution */
@@ -757,7 +790,7 @@ static void rna_FluidModifier_density_grid_get(PointerRNA *ptr, float *values)
BLI_rw_mutex_lock(fds->fluid_mutex, THREAD_LOCK_READ);
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
- density = manta_smoke_turbulence_get_density(fds->fluid);
+ density = manta_noise_get_density(fds->fluid);
}
else {
density = manta_smoke_get_density(fds->fluid);
@@ -804,11 +837,11 @@ static void rna_FluidModifier_color_grid_get(PointerRNA *ptr, float *values)
}
else {
if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
- if (manta_smoke_turbulence_has_colors(fds->fluid)) {
- manta_smoke_turbulence_get_rgba(fds->fluid, values, 0);
+ if (manta_noise_has_colors(fds->fluid)) {
+ manta_noise_get_rgba(fds->fluid, values, 0);
}
else {
- manta_smoke_turbulence_get_rgba_fixed_color(fds->fluid, fds->active_color, values, 0);
+ manta_noise_get_rgba_fixed_color(fds->fluid, fds->active_color, values, 0);
}
}
else {
@@ -834,7 +867,7 @@ static void rna_FluidModifier_flame_grid_get(PointerRNA *ptr, float *values)
BLI_rw_mutex_lock(fds->fluid_mutex, THREAD_LOCK_READ);
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
- flame = manta_smoke_turbulence_get_flame(fds->fluid);
+ flame = manta_noise_get_flame(fds->fluid);
}
else {
flame = manta_smoke_get_flame(fds->fluid);
@@ -884,7 +917,7 @@ static void rna_FluidModifier_temperature_grid_get(PointerRNA *ptr, float *value
BLI_rw_mutex_lock(fds->fluid_mutex, THREAD_LOCK_READ);
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
- flame = manta_smoke_turbulence_get_flame(fds->fluid);
+ flame = manta_noise_get_flame(fds->fluid);
}
else {
flame = manta_smoke_get_flame(fds->fluid);
@@ -991,14 +1024,18 @@ static void rna_Fluid_flowtype_set(struct PointerRNA *ptr, int value)
FluidFlowSettings *settings = (FluidFlowSettings *)ptr->data;
if (value != settings->type) {
+ short prev_value = settings->type;
settings->type = value;
- /* Force flow source to mesh */
+ /* Force flow source to mesh for liquids.
+ * Also use different surface emission. Liquids should by default not emit around surface. */
if (value == FLUID_FLOW_TYPE_LIQUID) {
rna_Fluid_flowsource_set(ptr, FLUID_FLOW_SOURCE_MESH);
settings->surface_distance = 0.0f;
}
- else {
+ /* Use some surface emission when switching to a gas emitter. Gases should by default emit a
+ * bit around surface. */
+ if (prev_value == FLUID_FLOW_TYPE_LIQUID) {
settings->surface_distance = 1.5f;
}
}
@@ -1350,7 +1387,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Adaptive Domain", "Adapt simulation resolution and size to fluid");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_data_reset");
/* fluid domain options */
@@ -1364,7 +1401,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"Resolution used for the fluid domain. Value corresponds to the longest domain side "
"(resolution for other domain sides is calculated automatically)");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_data_reset");
prop = RNA_def_property(srna, "use_collision_border_front", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "border_collisions", FLUID_DOMAIN_BORDER_FRONT);
@@ -1547,7 +1584,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"The noise simulation is scaled up by this factor (compared to the "
"base resolution of the domain)");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_noise_reset");
prop = RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "noise_type");
@@ -1555,7 +1592,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Noise Method", "Noise method which is used during the high-res simulation");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_noise_reset");
prop = RNA_def_property(srna, "use_noise", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", FLUID_DOMAIN_USE_NOISE);
@@ -1569,7 +1606,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "simulation_method");
RNA_def_property_enum_items(prop, simulation_methods);
RNA_def_property_ui_text(prop, "Simulation Method", "Change the underlying simulation method");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_data_reset");
prop = RNA_def_property(srna, "flip_ratio", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0, 1.0);
@@ -1644,12 +1681,21 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_range(prop, 0.001, 1.0);
RNA_def_property_ui_range(prop, 0.01, 1.0, 0.05, -1);
RNA_def_property_ui_text(prop,
- "Obstacle-Fluid Threshold ",
+ "Obstacle-Fluid Threshold",
"Determines how much fluid is allowed in an obstacle cell "
"(higher values will tag a boundary cell as an obstacle easier "
"and reduce the boundary smoothening effect)");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
+ prop = RNA_def_property(srna, "sys_particle_maximum", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "sys_particle_maximum");
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_text(
+ prop,
+ "System Maximum",
+ "Maximum number of fluid particles that are allowed in this simulation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
+
/* diffusion options */
prop = RNA_def_property(srna, "use_diffusion", PROP_BOOLEAN, PROP_NONE);
@@ -1657,7 +1703,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Use Diffusion", "Enable fluid diffusion settings (e.g. viscosity, surface tension)");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
prop = RNA_def_property(srna, "surface_tension", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0, 100.0);
@@ -1724,7 +1770,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"resolution of the domain). For best meshing, it is recommended to "
"adjust the mesh particle radius alongside this value");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_meshcache_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_mesh_reset");
prop = RNA_def_property(srna, "mesh_generator", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mesh_generator");
@@ -1924,7 +1970,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"The particle simulation is scaled up by this factor (compared to the "
"base resolution of the domain)");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_particles_reset");
prop = RNA_def_property(srna, "use_spray_particles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "particle_type", FLUID_DOMAIN_PARTICLE_SPRAY);
@@ -2006,6 +2052,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop,
"Start",
"Frame on which the simulation starts. This is the first frame that will be baked");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "cache_frame_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "cache_frame_end");
@@ -2015,6 +2062,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop,
"End",
"Frame on which the simulation stops. This is the last frame that will be baked");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "cache_frame_offset", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "cache_frame_offset");
@@ -2024,6 +2072,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"Offset",
"Frame offset that is used when loading the simulation from the cache. It is not considered "
"when baking the simulation, only when loading it");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "cache_frame_pause_data", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "cache_frame_pause_data");
@@ -2047,6 +2096,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop, NULL, "rna_Fluid_cachetype_mesh_set", "rna_Fluid_cachetype_mesh_itemf");
RNA_def_property_ui_text(
prop, "File Format", "Select the file format to be used for caching surface data");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_meshcache_reset");
prop = RNA_def_property(srna, "cache_data_format", PROP_ENUM, PROP_NONE);
@@ -2056,6 +2106,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop, NULL, "rna_Fluid_cachetype_data_set", "rna_Fluid_cachetype_volume_itemf");
RNA_def_property_ui_text(
prop, "File Format", "Select the file format to be used for caching volumetric data");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
prop = RNA_def_property(srna, "cache_particle_format", PROP_ENUM, PROP_NONE);
@@ -2065,6 +2116,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop, NULL, "rna_Fluid_cachetype_particle_set", "rna_Fluid_cachetype_particle_itemf");
RNA_def_property_ui_text(
prop, "File Format", "Select the file format to be used for caching particle data");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_particlescache_reset");
prop = RNA_def_property(srna, "cache_noise_format", PROP_ENUM, PROP_NONE);
@@ -2074,6 +2126,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop, NULL, "rna_Fluid_cachetype_noise_set", "rna_Fluid_cachetype_volume_itemf");
RNA_def_property_ui_text(
prop, "File Format", "Select the file format to be used for caching noise data");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_noisecache_reset");
prop = RNA_def_property(srna, "cache_type", PROP_ENUM, PROP_NONE);
@@ -2081,7 +2134,8 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, cache_types);
RNA_def_property_enum_funcs(prop, NULL, "rna_Fluid_cachetype_set", NULL);
RNA_def_property_ui_text(prop, "Type", "Change the cache type of the simulation");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_domain_reset");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_domain_data_reset");
prop = RNA_def_property(srna, "cache_resumable", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", FLUID_DOMAIN_USE_RESUMABLE_CACHE);
@@ -2091,6 +2145,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"Additional data will be saved so that the bake jobs can be resumed after pausing. Because "
"more data will be written to disk it is recommended to avoid enabling this option when "
"baking at high resolutions");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
prop = RNA_def_property(srna, "cache_directory", PROP_STRING, PROP_DIRPATH);
@@ -2158,7 +2213,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"only needed if you plan to analyze the cache (e.g. view grids, velocity vectors, "
"particles) in Mantaflow directly (outside of Blender) after baking the simulation");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_data_reset");
/* time options */
@@ -2343,7 +2398,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "openvdb_cache_compress_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "openvdb_compression");
RNA_def_property_enum_items(prop, prop_compression_items);
- RNA_def_property_ui_text(prop, "Compression", "facession method to be used");
+ RNA_def_property_ui_text(prop, "Compression", "Compression method to be used");
prop = RNA_def_property(srna, "openvdb_data_depth", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "openvdb_data_depth");
@@ -2655,7 +2710,7 @@ static void rna_def_fluid_effector_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_plane_init", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", FLUID_EFFECTOR_USE_PLANE_INIT);
RNA_def_property_ui_text(prop, "Is Planar", "Treat this object as a planar, unclosed mesh");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_reset");
+ RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_data_reset");
prop = RNA_def_property(srna, "velocity_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vel_multi");
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 1c39ad3a1a8..9519e3e1433 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -1817,8 +1817,7 @@ static void rna_def_modifier_gpencilmirror(BlenderRNA *brna)
PropertyRNA *prop;
srna = RNA_def_struct(brna, "MirrorGpencilModifier", "GpencilModifier");
- RNA_def_struct_ui_text(
- srna, "Mirror Modifier", "Change stroke using lattice to deform modifier");
+ RNA_def_struct_ui_text(srna, "Mirror Modifier", "Create mirroring strokes");
RNA_def_struct_sdna(srna, "MirrorGpencilModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_MIRROR);
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 887bded8540..1c43815d3a2 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -67,7 +67,6 @@ static const EnumPropertyItem image_source_items[] = {
# include "BKE_global.h"
-# include "GPU_draw.h"
# include "GPU_texture.h"
# include "IMB_imbuf.h"
@@ -200,7 +199,7 @@ static void rna_Image_gpu_texture_update(Main *UNUSED(bmain),
Image *ima = (Image *)ptr->owner_id;
if (!G.background) {
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
}
WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id);
@@ -398,7 +397,7 @@ static void rna_Image_resolution_set(PointerRNA *ptr, const float *values)
static int rna_Image_bindcode_get(PointerRNA *ptr)
{
Image *ima = (Image *)ptr->data;
- GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D][0];
+ GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0];
return (tex) ? GPU_texture_opengl_bindcode(tex) : 0;
}
@@ -516,7 +515,7 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_MIPMAP_INVALID;
BKE_image_mark_dirty(ima, ibuf);
if (!G.background) {
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
}
WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id);
}
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 41c0e724234..6f876923e52 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -50,8 +50,6 @@
# include "DNA_image_types.h"
# include "DNA_scene_types.h"
-# include "GPU_glew.h"
-
# include "MEM_guardedalloc.h"
static void rna_ImagePackedFile_save(ImagePackedFile *imapf, Main *bmain, ReportList *reports)
@@ -222,23 +220,24 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int frame)
BKE_imageuser_default(&iuser);
iuser.framenr = frame;
- GPUTexture *tex = GPU_texture_from_blender(image, &iuser, NULL, GL_TEXTURE_2D);
+ GPUTexture *tex = BKE_image_get_gpu_texture(image, &iuser, NULL);
if (tex == NULL) {
BKE_reportf(reports, RPT_ERROR, "Failed to load image texture '%s'", image->id.name + 2);
- return (int)GL_INVALID_OPERATION;
+ /* TODO(fclem) this error code makes no sense for vulkan. */
+ return 0x0502; /* GL_INVALID_OPERATION */
}
- return GL_NO_ERROR;
+ return 0; /* GL_NO_ERROR */
}
static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame)
{
- int error = GL_NO_ERROR;
+ int error = 0; /* GL_NO_ERROR */
BKE_image_tag_time(image);
- if (image->gputexture[TEXTARGET_TEXTURE_2D] == NULL) {
+ if (image->gputexture[TEXTARGET_2D][0] == NULL) {
error = rna_Image_gl_load(image, reports, frame);
}
@@ -247,7 +246,7 @@ static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame)
static void rna_Image_gl_free(Image *image)
{
- GPU_free_image(image);
+ BKE_image_free_gputextures(image);
/* remove the nocollect flag, image is available for garbage collection again */
image->flag &= ~IMA_NOCOLLECT;
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 0783addd78b..8045279eef2 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -18,11 +18,12 @@
* \ingroup RNA
*/
-#ifndef __RNA_INTERNAL_H__
-#define __RNA_INTERNAL_H__
+#pragma once
#include "BLI_utildefines.h"
+#include "BLI_compiler_attrs.h"
+
#include "rna_internal_types.h"
#include "UI_resources.h"
@@ -478,9 +479,11 @@ extern StructRNA RNA_PropertyGroupItem;
extern StructRNA RNA_PropertyGroup;
#endif
-struct IDProperty *rna_idproperty_check(struct PropertyRNA **prop, struct PointerRNA *ptr);
+struct IDProperty *rna_idproperty_check(struct PropertyRNA **prop,
+ struct PointerRNA *ptr) ATTR_WARN_UNUSED_RESULT;
struct PropertyRNA *rna_ensure_property_realdata(struct PropertyRNA **prop,
- struct PointerRNA *ptr);
+ struct PointerRNA *ptr) ATTR_WARN_UNUSED_RESULT;
+struct PropertyRNA *rna_ensure_property(struct PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT;
/* Override default callbacks. */
/* Default override callbacks for all types. */
@@ -489,12 +492,8 @@ struct PropertyRNA *rna_ensure_property_realdata(struct PropertyRNA **prop,
* Not obvious though, those are fairly more complicated than basic SDNA access.
*/
int rna_property_override_diff_default(struct Main *bmain,
- struct PointerRNA *ptr_a,
- struct PointerRNA *ptr_b,
- struct PropertyRNA *prop_a,
- struct PropertyRNA *prop_b,
- const int len_a,
- const int len_b,
+ struct PropertyRNAOrID *prop_a,
+ struct PropertyRNAOrID *prop_b,
const int mode,
struct IDOverrideLibrary *override,
const char *rna_path,
@@ -644,5 +643,3 @@ void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
: -FLT_MAX, double \
: -DBL_MAX)
#endif
-
-#endif /* __RNA_INTERNAL_H__ */
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 345d84fc5b1..01c406104d7 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -18,8 +18,7 @@
* \ingroup RNA
*/
-#ifndef __RNA_INTERNAL_TYPES_H__
-#define __RNA_INTERNAL_TYPES_H__
+#pragma once
#include "DNA_listBase.h"
@@ -41,6 +40,8 @@ struct Scene;
struct StructRNA;
struct bContext;
+typedef struct IDProperty IDProperty;
+
/* store local properties here */
#define RNA_IDP_UI "_RNA_UI"
@@ -155,24 +156,55 @@ typedef void (*PropEnumSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *pr
/* Handling override operations, and also comparison. */
+/** Structure storing all needed data to process all three kinds of RNA properties. */
+typedef struct PropertyRNAOrID {
+ PointerRNA ptr;
+
+ /** The PropertyRNA passed as parameter, used to generate that structure's content:
+ * - Static RNA: The RNA property (same as `rnaprop`), never NULL.
+ * - Runtime RNA: The RNA property (same as `rnaprop`), never NULL.
+ * - IDProperty: The IDProperty, never NULL.
+ */
+ PropertyRNA *rawprop;
+ /** The real RNA property of this property, never NULL:
+ * - Static RNA: The rna property, also gives direct access to the data (from any matching
+ * PointerRNA).
+ * - Runtime RNA: The rna property, does not directly gives access to the data.
+ * - IDProperty: The generic PropertyRNA matching its type.
+ */
+ PropertyRNA *rnaprop;
+ /** The IDProperty storing the data of this property, may be NULL:
+ * - Static RNA: Always NULL.
+ * - Runtime RNA: The IDProperty storing the data of that property, may be NULL if never set yet.
+ * - IDProperty: The IDProperty, never NULL.
+ */
+ IDProperty *idprop;
+ /** The name of the property. */
+ const char *identifier;
+
+ /** Whether this property is a 'pure' IDProperty or not. */
+ bool is_idprop;
+ /** For runtime RNA properties, whether it is set, defined, or not.
+ * WARNING: This DOES take into account the `IDP_FLAG_GHOST` flag, i.e. it matches result of
+ * `RNA_property_is_set`. */
+ bool is_set;
+
+ bool is_array;
+ uint array_len;
+} PropertyRNAOrID;
+
/**
- * If \a override is NULL, merely do comparison between prop_a from ptr_a and prop_b from ptr_b,
+ * If \a override is NULL, merely do comparison between prop_a and prop_b,
* following comparison mode given.
* If \a override and \a rna_path are not NULL, it will add a new override operation for
* overridable properties that differ and have not yet been overridden
* (and set accordingly \a r_override_changed if given).
*
- * \note Given PropertyRNA are final (in case of IDProps...).
- * \note In non-array cases, \a len values are 0.
* \note \a override, \a rna_path and \a r_override_changed may be NULL pointers.
*/
typedef int (*RNAPropOverrideDiff)(struct Main *bmain,
- struct PointerRNA *ptr_a,
- struct PointerRNA *ptr_b,
- struct PropertyRNA *prop_a,
- struct PropertyRNA *prop_b,
- const int len_a,
- const int len_b,
+ struct PropertyRNAOrID *prop_a,
+ struct PropertyRNAOrID *prop_b,
const int mode,
struct IDOverrideLibrary *override,
const char *rna_path,
@@ -536,5 +568,3 @@ struct BlenderRNA {
};
#define CONTAINER_RNA_ID(cont) (*(const char **)(((ContainerRNA *)(cont)) + 1))
-
-#endif /* __RNA_INTERNAL_TYPES_H__ */
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index b99457056fe..e7a898b97ae 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -458,7 +458,7 @@ static void rna_def_layer_objects(BlenderRNA *brna, PropertyRNA *cprop)
NULL);
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
RNA_def_property_ui_text(prop, "Active Object", "Active object for this layer");
- /* Could call: ED_object_base_activate(C, rl->basact);
+ /* Could call: `ED_object_base_activate(C, view_layer->basact);`
* but would be a bad level call and it seems the notifier is enough */
RNA_def_property_update(prop, NC_SCENE | ND_OB_ACTIVE, NULL);
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 1670e08325f..97702b06b6f 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -410,7 +410,7 @@ void RNA_def_main(BlenderRNA *brna)
srna = RNA_def_struct(brna, "BlendData", NULL);
RNA_def_struct_ui_text(srna,
- "Blendfile Data",
+ "Blend-file Data",
"Main data structure representing a .blend file and all its data-blocks");
RNA_def_struct_ui_icon(srna, ICON_BLENDER);
@@ -436,7 +436,7 @@ void RNA_def_main(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_autopack", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Main_use_autopack_get", "rna_Main_use_autopack_set");
RNA_def_property_ui_text(
- prop, "Use Autopack", "Automatically pack all external data into .blend file");
+ prop, "Use Auto-pack", "Automatically pack all external data into .blend file");
prop = RNA_def_int_vector(srna,
"version",
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 506bfdb8c75..bb5ec0d6835 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -3376,7 +3376,7 @@ static void rna_def_mesh(BlenderRNA *brna)
/* readonly editmesh info - use for extrude menu */
prop = RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Mesh_tot_vert_get", NULL, NULL);
- RNA_def_property_ui_text(prop, "Selected Vert Total", "Selected vertex count in editmode");
+ RNA_def_property_ui_text(prop, "Selected Vertex Total", "Selected vertex count in editmode");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "total_edge_sel", PROP_INT, PROP_UNSIGNED);
diff --git a/source/blender/makesrna/intern/rna_mesh_utils.h b/source/blender/makesrna/intern/rna_mesh_utils.h
index 9c5b4f9d5b3..5e11be382ec 100644
--- a/source/blender/makesrna/intern/rna_mesh_utils.h
+++ b/source/blender/makesrna/intern/rna_mesh_utils.h
@@ -18,8 +18,7 @@
* \ingroup RNA
*/
-#ifndef __RNA_MESH_UTILS_H__
-#define __RNA_MESH_UTILS_H__
+#pragma once
/* Macros to help reduce code clutter in rna_mesh.c */
@@ -123,5 +122,3 @@
BKE_mesh_update_customdata_pointers(me, true); \
} \
}
-
-#endif /* __RNA_MESH_UTILS_H__ */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index c92fe5ee508..05e11ffc919 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -302,7 +302,7 @@ const EnumPropertyItem rna_enum_modifier_triangulate_quad_method_items[] = {
{MOD_TRIANGULATE_QUAD_BEAUTY,
"BEAUTY",
0,
- "Beauty ",
+ "Beauty",
"Split the quads in nice triangles, slower method"},
{MOD_TRIANGULATE_QUAD_FIXED,
"FIXED",
@@ -1163,7 +1163,7 @@ static void rna_BevelModifier_update_segments(Main *bmain, Scene *scene, Pointer
BevelModifierData *bmd = (BevelModifierData *)ptr->data;
if (RNA_enum_get(ptr, "profile_type") == MOD_BEVEL_PROFILE_CUSTOM) {
short segments = (short)RNA_int_get(ptr, "segments");
- BKE_curveprofile_initialize(bmd->custom_profile, segments);
+ BKE_curveprofile_init(bmd->custom_profile, segments);
}
rna_Modifier_update(bmain, scene, ptr);
}
@@ -1639,6 +1639,40 @@ static void rna_SimulationModifier_simulation_update(Main *bmain, Scene *scene,
rna_Modifier_dependency_update(bmain, scene, ptr);
}
+static void rna_SimulationModifier_data_path_get(PointerRNA *ptr, char *value)
+{
+ SimulationModifierData *smd = ptr->data;
+
+ if (smd->data_path) {
+ strcpy(value, smd->data_path);
+ }
+ else {
+ value[0] = '\0';
+ }
+}
+
+static int rna_SimulationModifier_data_path_length(PointerRNA *ptr)
+{
+ SimulationModifierData *smd = ptr->data;
+ return smd->data_path ? strlen(smd->data_path) : 0;
+}
+
+static void rna_SimulationModifier_data_path_set(PointerRNA *ptr, const char *value)
+{
+ SimulationModifierData *smd = ptr->data;
+
+ if (smd->data_path) {
+ MEM_freeN(smd->data_path);
+ }
+
+ if (value[0]) {
+ smd->data_path = BLI_strdup(value);
+ }
+ else {
+ smd->data_path = NULL;
+ }
+}
+
/**
* Special set callback that just changes the first bit of the expansion flag.
* This way the expansion state of all the sub-panels is not changed by RNA.
@@ -1654,6 +1688,62 @@ static void rna_Modifier_show_expanded_set(PointerRNA *ptr, bool value)
}
}
+/**
+ * Only check the first bit of the expansion flag for the main panel's expansion,
+ * maintaining compatibility with older versions where there was only one expansion
+ * value.
+ */
+static bool rna_Modifier_show_expanded_get(PointerRNA *ptr)
+{
+ ModifierData *md = ptr->data;
+ return md->ui_expand_flag & (1 << 0);
+}
+
+static int rna_MeshSequenceCacheModifier_has_velocity_get(PointerRNA *ptr)
+{
+# ifdef WITH_ALEMBIC
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)ptr->data;
+ return ABC_has_vec3_array_property_named(mcmd->reader, mcmd->cache_file->velocity_name);
+# else
+ return false;
+ UNUSED_VARS(ptr);
+# endif
+}
+
+static int rna_MeshSequenceCacheModifier_read_velocity_get(PointerRNA *ptr)
+{
+# ifdef WITH_ALEMBIC
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)ptr->data;
+
+ if (mcmd->num_vertices == 0) {
+ return 0;
+ }
+
+ if (mcmd->vertex_velocities) {
+ MEM_freeN(mcmd->vertex_velocities);
+ }
+
+ mcmd->vertex_velocities = MEM_mallocN(sizeof(MeshCacheVertexVelocity) * mcmd->num_vertices,
+ "Mesh Cache Velocities");
+
+ int num_read = ABC_read_velocity_cache(mcmd->reader,
+ mcmd->cache_file->velocity_name,
+ mcmd->last_lookup_time,
+ mcmd->velocity_scale * mcmd->velocity_delta,
+ mcmd->num_vertices,
+ (float *)mcmd->vertex_velocities);
+
+ if (num_read == -1 || num_read != mcmd->num_vertices) {
+ return false;
+ }
+
+ return true;
+# else
+ return false;
+ UNUSED_VARS(ptr);
+# endif
+}
+
#else
/* NOTE: *MUST* return subdivision_type property. */
@@ -1773,6 +1863,12 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna)
prop, "Use Creases", "Use mesh edge crease information to sharpen edges");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "use_custom_normals", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", eSubsurfModifierFlag_UseCustomNormals);
+ RNA_def_property_ui_text(
+ prop, "Use Custom Normals", "Interpolates existing custom normals to resulting mesh");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
RNA_define_lib_overridable(false);
}
@@ -1974,6 +2070,12 @@ static void rna_def_modifier_multires(BlenderRNA *brna)
prop, "Use Creases", "Use mesh edge crease information to sharpen edges");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "use_custom_normals", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", eMultiresModifierFlag_UseCustomNormals);
+ RNA_def_property_ui_text(
+ prop, "Use Custom Normals", "Interpolates existing custom normals to resulting mesh");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
RNA_define_lib_overridable(false);
}
@@ -3200,12 +3302,12 @@ static void rna_def_modifier_correctivesmooth(BlenderRNA *brna)
"ORCO",
0,
"Original Coords",
- "Use base mesh vert coords as the rest position"},
+ "Use base mesh vertex coords as the rest position"},
{MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND,
"BIND",
0,
"Bind Coords",
- "Use bind vert coords for rest position"},
+ "Use bind vertex coords for rest position"},
{0, NULL, 0, NULL, NULL},
};
@@ -4002,8 +4104,8 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
};
static const EnumPropertyItem prop_affect_items[] = {
- {0, "EDGES", 0, "Edges", "Affect only edges"},
- {MOD_BEVEL_VERT, "VERTICES", 0, "Vertices", "Affect only vertices"},
+ {MOD_BEVEL_AFFECT_VERTICES, "VERTICES", 0, "Vertices", "Affect only vertices"},
+ {MOD_BEVEL_AFFECT_EDGES, "EDGES", 0, "Edges", "Affect only edges"},
{0, NULL, 0, NULL, NULL},
};
@@ -4036,7 +4138,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_BevelModifier_update_segments");
prop = RNA_def_property(srna, "affect", PROP_ENUM, PROP_NONE); /* as an enum */
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "flags");
+ RNA_def_property_enum_sdna(prop, NULL, "affect_type");
RNA_def_property_enum_items(prop, prop_affect_items);
RNA_def_property_ui_text(prop, "Affect", "Affect edges or vertices");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -5610,7 +5712,17 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 1, 1024);
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_ui_text(
+ prop, "Render Resolution", "Resolution of the generated surface for rendering and baking");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop = RNA_def_property(srna, "viewport_resolution", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "viewport_resolution");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_ui_range(prop, 1, 32, 1, -1);
+ RNA_def_property_ui_text(
+ prop, "Viewport Resolution", "Viewport 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);
@@ -5644,7 +5756,7 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
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_range(prop, 0.0, 1.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");
@@ -5721,7 +5833,7 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
prop = RNA_def_property(srna, "sharpen_peak_jonswap", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "sharpen_peak_jonswap");
- RNA_def_property_range(prop, 0.0, 10.0);
+ RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_ui_text(prop, "Sharpen peak", "Peak sharpening for 'JONSWAP' and 'TMA' models");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
@@ -5848,7 +5960,7 @@ static void rna_def_modifier_triangulate(BlenderRNA *brna)
static void rna_def_modifier_meshcache(BlenderRNA *brna)
{
static const EnumPropertyItem prop_format_type_items[] = {
- {MOD_MESHCACHE_TYPE_MDD, "MDD", 0, "MDD ", ""},
+ {MOD_MESHCACHE_TYPE_MDD, "MDD", 0, "MDD", ""},
{MOD_MESHCACHE_TYPE_PC2, "PC2", 0, "PC2", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -5869,7 +5981,7 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
};
static const EnumPropertyItem prop_interpolation_type_items[] = {
- {MOD_MESHCACHE_INTERP_NONE, "NONE", 0, "None ", ""},
+ {MOD_MESHCACHE_INTERP_NONE, "NONE", 0, "None", ""},
{MOD_MESHCACHE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""},
/* for cardinal we'd need to read 4x cache's */
// {MOD_MESHCACHE_INTERP_CARDINAL, "CARDINAL", 0, "Cardinal", ""},
@@ -6009,6 +6121,22 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
+static void rna_def_mesh_cache_velocities(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "MeshCacheVertexVelocity", NULL);
+ RNA_def_struct_ui_text(srna, "Mesh Cache Velocity", "Velocity attribute of an Alembic mesh");
+ RNA_def_struct_ui_icon(srna, ICON_VERTEXSEL);
+
+ prop = RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_VELOCITY);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_float_sdna(prop, NULL, "vel");
+ RNA_def_property_ui_text(prop, "Velocity", "");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+}
+
static void rna_def_modifier_meshseqcache(BlenderRNA *brna)
{
StructRNA *srna;
@@ -6051,6 +6179,35 @@ static void rna_def_modifier_meshseqcache(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "velocity_scale");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_text(
+ prop,
+ "Velocity Scale",
+ "Multiplier used to control the magnitude of the velocity vectors for time effects");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* -------------------------- Velocity Vectors -------------------------- */
+
+ prop = RNA_def_property(srna, "vertex_velocities", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "vertex_velocities", "num_vertices");
+ RNA_def_property_struct_type(prop, "MeshCacheVertexVelocity");
+ RNA_def_property_ui_text(
+ prop, "Fluid Mesh Vertices", "Vertices of the fluid mesh generated by simulation");
+
+ rna_def_mesh_cache_velocities(brna);
+
+ prop = RNA_def_property(srna, "has_velocity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Has Velocity Cache", "");
+ RNA_def_property_boolean_funcs(prop, "rna_MeshSequenceCacheModifier_has_velocity_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "read_velocity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Read Velocity Cache", "");
+ RNA_def_property_boolean_funcs(prop, "rna_MeshSequenceCacheModifier_read_velocity_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
RNA_define_lib_overridable(false);
}
@@ -6859,6 +7016,10 @@ static void rna_def_modifier_simulation(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_SimulationModifier_simulation_update");
prop = RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop,
+ "rna_SimulationModifier_data_path_get",
+ "rna_SimulationModifier_data_path_length",
+ "rna_SimulationModifier_data_path_set");
RNA_def_property_ui_text(
prop, "Data Path", "Identifier of the simulation component that should be accessed");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -6921,7 +7082,8 @@ void RNA_def_modifier(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_funcs(prop, NULL, "rna_Modifier_show_expanded_set");
+ RNA_def_property_boolean_funcs(
+ prop, "rna_Modifier_show_expanded_get", "rna_Modifier_show_expanded_set");
RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
RNA_def_property_boolean_sdna(prop, NULL, "ui_expand_flag", 0);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c
index f3c73e75434..b94221ae936 100644
--- a/source/blender/makesrna/intern/rna_movieclip.c
+++ b/source/blender/makesrna/intern/rna_movieclip.c
@@ -218,7 +218,7 @@ static void rna_def_movieclip_proxy(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "100%", "Build proxy resolution 100% of the original undistorted footage dimension");
- /* build timecodes */
+ /* Build time-codes. */
prop = RNA_def_property(srna, "build_record_run", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flag", IMB_TC_RECORD_RUN);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 6312c84cf9f..af07185ab4a 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -38,6 +38,7 @@
#include "BKE_animsys.h"
#include "BKE_image.h"
#include "BKE_node.h"
+#include "BKE_simulation.h"
#include "BKE_texture.h"
#include "RNA_access.h"
@@ -2848,6 +2849,14 @@ static void rna_NodeSocketStandard_value_update(struct bContext *C, PointerRNA *
}
}
+static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C, PointerRNA *ptr)
+{
+ rna_NodeSocketStandard_value_update(C, ptr);
+ bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
+ Main *bmain = CTX_data_main(C);
+ ntreeUpdateTree(bmain, ntree);
+}
+
/* ******** Node Types ******** */
static void rna_NodeInternalSocketTemplate_name_get(PointerRNA *ptr, char *value)
@@ -4421,7 +4430,7 @@ static void def_sh_tex_sky(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "sky_model");
RNA_def_property_enum_items(prop, prop_sky_type);
RNA_def_property_ui_text(prop, "Sky Type", "Which sky model should be used");
- RNA_def_property_update(prop, 0, "rna_Node_update");
+ RNA_def_property_update(prop, 0, "rna_ShaderNode_socket_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");
@@ -4445,46 +4454,51 @@ static void def_sh_tex_sky(StructRNA *srna)
RNA_def_property_ui_text(prop, "Sun Disc", "Include the sun itself in the output");
RNA_def_property_boolean_sdna(prop, NULL, "sun_disc", 1);
RNA_def_property_boolean_default(prop, true);
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, 0, "rna_ShaderNode_socket_update");
prop = RNA_def_property(srna, "sun_size", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_ui_text(prop, "Sun Size", "Size of sun disc (angular diameter)");
+ RNA_def_property_ui_text(prop, "Sun Size", "Size of sun disc");
RNA_def_property_range(prop, 0.0f, M_PI_2);
RNA_def_property_float_default(prop, DEG2RADF(0.545));
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ prop = RNA_def_property(srna, "sun_intensity", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Sun Intensity", "Strength of sun");
+ RNA_def_property_range(prop, 0.0f, 1000.0f);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
prop = RNA_def_property(srna, "sun_elevation", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_ui_text(prop, "Sun Elevation", "Angle between sun and horizon");
+ RNA_def_property_ui_text(prop, "Sun Elevation", "Sun angle from horizon");
RNA_def_property_range(prop, -M_PI_2, M_PI_2);
RNA_def_property_float_default(prop, M_PI_2);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "sun_rotation", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_ui_text(prop, "Sun Rotation", "Rotation of sun around zenith");
- RNA_def_property_range(prop, 0.0f, 2.0f * M_PI);
RNA_def_property_float_default(prop, 0.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
- prop = RNA_def_property(srna, "altitude", PROP_INT, PROP_NONE);
- RNA_def_property_ui_text(prop, "Altitude", "Altitude height from sea level in meters");
- RNA_def_property_range(prop, 0, 60000);
- RNA_def_property_int_default(prop, 0);
+ prop = RNA_def_property(srna, "altitude", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Altitude", "Height from sea level");
+ RNA_def_property_range(prop, 0.0f, 60.0f);
+ RNA_def_property_float_default(prop, 0.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "air_density", PROP_FLOAT, PROP_FACTOR);
- RNA_def_property_ui_text(prop, "Air", "Density of air molecules (Rayleigh scattering)");
+ RNA_def_property_ui_text(prop, "Air", "Density of air molecules");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "dust_density", PROP_FLOAT, PROP_FACTOR);
- RNA_def_property_ui_text(prop, "Dust", "Density of dust and water molecules (Mie scattering)");
+ RNA_def_property_ui_text(prop, "Dust", "Density of dust molecules and water droplets");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "ozone_density", PROP_FLOAT, PROP_FACTOR);
- RNA_def_property_ui_text(prop, "Ozone", "Density of Ozone layer (Ozone absorption)");
+ RNA_def_property_ui_text(prop, "Ozone", "Density of Ozone layer");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@@ -6490,7 +6504,7 @@ static void def_cmp_channel_matte(StructRNA *srna)
static const EnumPropertyItem algorithm_items[] = {
{0, "SINGLE", 0, "Single", "Limit by single channel"},
- {1, "MAX", 0, "Max", "Limit by max of other channels "},
+ {1, "MAX", 0, "Max", "Limit by max of other channels"},
{0, NULL, 0, NULL, NULL},
};
@@ -8361,6 +8375,8 @@ static void rna_def_node_socket(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, "rna_NodeSocket_node_get", NULL, NULL, NULL);
RNA_def_property_struct_type(prop, "Node");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Node", "Node owning this socket");
/* NB: the type property is used by standard sockets.
@@ -8459,6 +8475,12 @@ static void rna_def_node_socket_interface(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Is Output", "True if the socket is an output, otherwise input");
+ prop = RNA_def_property(srna, "hide_value", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_HIDE_VALUE);
+ RNA_def_property_ui_text(
+ prop, "Hide Value", "Hide the socket input value even when the socket is not connected");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
+
/* registration */
prop = RNA_def_property(srna, "bl_socket_idname", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname");
@@ -8855,7 +8877,8 @@ static void rna_def_node_socket_object(BlenderRNA *brna,
RNA_def_property_pointer_sdna(prop, NULL, "value");
RNA_def_property_struct_type(prop, "Object");
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_update(
+ prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
/* socket interface */
@@ -8889,7 +8912,8 @@ static void rna_def_node_socket_image(BlenderRNA *brna,
RNA_def_property_pointer_sdna(prop, NULL, "value");
RNA_def_property_struct_type(prop, "Image");
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_update(
+ prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
/* socket interface */
@@ -9316,6 +9340,8 @@ static void rna_def_node(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "parent");
RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_parent_set", NULL, "rna_Node_parent_poll");
RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_struct_type(prop, "Node");
RNA_def_property_ui_text(prop, "Parent", "Parent this node is attached to");
@@ -9530,29 +9556,39 @@ static void rna_def_node_link(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "fromnode");
RNA_def_property_struct_type(prop, "Node");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "From node", "");
prop = RNA_def_property(srna, "to_node", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tonode");
RNA_def_property_struct_type(prop, "Node");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "To node", "");
prop = RNA_def_property(srna, "from_socket", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "fromsock");
RNA_def_property_struct_type(prop, "NodeSocket");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "From socket", "");
prop = RNA_def_property(srna, "to_socket", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tosock");
RNA_def_property_struct_type(prop, "NodeSocket");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "To socket", "");
prop = RNA_def_property(srna, "is_hidden", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_NodeLink_is_hidden_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Is Hidden", "Link is hidden due to invisible sockets");
}
@@ -9891,7 +9927,7 @@ static void rna_def_composite_nodetree(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_viewer_border", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_VIEWER_BORDER);
RNA_def_property_ui_text(
- prop, "Viewer Border", "Use boundaries for viewer nodes and composite backdrop");
+ prop, "Viewer Region", "Use boundaries for viewer nodes and composite backdrop");
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, "rna_NodeTree_update");
}
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 089410ffd25..08ca3f16b6d 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -174,7 +174,7 @@ static const EnumPropertyItem parent_type_items[] = {
#define INSTANCE_ITEMS_SHARED \
{0, "NONE", 0, "None", ""}, \
- {OB_DUPLIVERTS, "VERTS", 0, "Verts", "Instantiate child objects on all vertices"}, \
+ {OB_DUPLIVERTS, "VERTS", 0, "Vertices", "Instantiate child objects on all vertices"}, \
{ \
OB_DUPLIFACES, "FACES", 0, "Faces", "Instantiate child objects on all faces" \
}
@@ -193,6 +193,12 @@ static EnumPropertyItem instance_items_nogroup[] = {
INSTANCE_ITEMS_SHARED,
{0, NULL, 0, NULL, NULL},
};
+
+static EnumPropertyItem instance_items_pointcloud[] = {
+ {0, "NONE", 0, "None", ""},
+ {OB_DUPLIVERTS, "POINTS", 0, "Points", "Instantiate child objects on all points"},
+ {0, NULL, 0, NULL, NULL},
+};
#endif
#undef INSTANCE_ITEMS_SHARED
#undef INSTANCE_ITEM_COLLECTION
@@ -707,6 +713,9 @@ static const EnumPropertyItem *rna_Object_instance_type_itemf(bContext *UNUSED(C
if (ob->type == OB_EMPTY) {
item = instance_items;
}
+ else if (ob->type == OB_POINTCLOUD) {
+ item = instance_items_pointcloud;
+ }
else {
item = instance_items_nogroup;
}
@@ -1579,7 +1588,8 @@ static void rna_Object_modifier_remove(Object *object,
PointerRNA *md_ptr)
{
ModifierData *md = md_ptr->data;
- if (ED_object_modifier_remove(reports, CTX_data_main(C), object, md) == false) {
+ if (ED_object_modifier_remove(reports, CTX_data_main(C), CTX_data_scene(C), object, md) ==
+ false) {
/* error is already set */
return;
}
@@ -1591,7 +1601,7 @@ static void rna_Object_modifier_remove(Object *object,
static void rna_Object_modifier_clear(Object *object, bContext *C)
{
- ED_object_modifier_clear(CTX_data_main(C), object);
+ ED_object_modifier_clear(CTX_data_main(C), CTX_data_scene(C), object);
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object);
}
@@ -3241,7 +3251,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
prop = RNA_def_property(srna, "show_in_front", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAWXRAY);
+ RNA_def_property_boolean_sdna(prop, NULL, "dtx", OB_DRAW_IN_FRONT);
RNA_def_property_ui_text(prop, "In Front", "Make the object draw in front of others");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_GPencil_update");
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 0b932f3236f..fa837df682a 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -809,7 +809,7 @@ static char *rna_EffectorWeight_path(PointerRNA *ptr)
if (fmd->domain->effector_weights == ew) {
char name_esc[sizeof(md->name) * 2];
BLI_strescape(name_esc, md->name, sizeof(name_esc));
- return BLI_sprintfN("modifiers[\"%s\"].settings.effector_weights", name_esc);
+ return BLI_sprintfN("modifiers[\"%s\"].domain_settings.effector_weights", name_esc);
}
}
@@ -851,7 +851,7 @@ static void rna_CollisionSettings_dependency_update(Main *bmain, Scene *scene, P
ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Collision);
}
else if (!ob->pd->deflect && md) {
- ED_object_modifier_remove(NULL, bmain, ob, md);
+ ED_object_modifier_remove(NULL, bmain, scene, ob, md);
}
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 14d84ddb9c8..3067a5a9453 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -52,7 +52,7 @@
#ifdef RNA_RUNTIME
static const EnumPropertyItem part_from_items[] = {
- {PART_FROM_VERT, "VERT", 0, "Verts", ""},
+ {PART_FROM_VERT, "VERT", 0, "Vertices", ""},
{PART_FROM_FACE, "FACE", 0, "Faces", ""},
{PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""},
{0, NULL, 0, NULL, NULL},
@@ -61,7 +61,7 @@ static const EnumPropertyItem part_from_items[] = {
#ifndef RNA_RUNTIME
static const EnumPropertyItem part_reactor_from_items[] = {
- {PART_FROM_VERT, "VERT", 0, "Verts", ""},
+ {PART_FROM_VERT, "VERT", 0, "Vertices", ""},
{PART_FROM_FACE, "FACE", 0, "Faces", ""},
{PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""},
{0, NULL, 0, NULL, NULL},
@@ -2887,7 +2887,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "userjit");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0, 1000);
- RNA_def_property_ui_text(prop, "P/F", "Emission locations / face (0 = automatic)");
+ RNA_def_property_ui_text(prop, "Particles/Face", "Emission locations per face (0 = automatic)");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(srna, "grid_resolution", PROP_INT, PROP_UNSIGNED);
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index a41abb1a1dd..5b77632be79 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -27,6 +27,8 @@
#include "BLI_path_util.h"
#include "BLI_utildefines.h"
+#include "BPY_extern.h"
+
#include "DEG_depsgraph.h"
#include "BKE_image.h"
@@ -408,6 +410,19 @@ static PointerRNA rna_RenderEngine_camera_override_get(PointerRNA *ptr)
}
}
+static void rna_RenderEngine_engine_frame_set(RenderEngine *engine, int frame, float subframe)
+{
+# ifdef WITH_PYTHON
+ BPy_BEGIN_ALLOW_THREADS;
+# endif
+
+ RE_engine_frame_set(engine, frame, subframe);
+
+# ifdef WITH_PYTHON
+ BPy_END_ALLOW_THREADS;
+# endif
+}
+
static void rna_RenderResult_views_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
RenderResult *rr = (RenderResult *)ptr->data;
@@ -673,7 +688,7 @@ static void rna_def_render_engine(BlenderRNA *brna)
parm = RNA_def_string(func, "info", NULL, 0, "Info", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
- func = RNA_def_function(srna, "frame_set", "RE_engine_frame_set");
+ func = RNA_def_function(srna, "frame_set", "rna_RenderEngine_engine_frame_set");
RNA_def_function_ui_description(func, "Evaluate scene at a different frame (for motion blur)");
parm = RNA_def_int(func, "frame", 0, INT_MIN, INT_MAX, "Frame", "", INT_MIN, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
@@ -830,6 +845,14 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Use Eevee Viewport", "Uses Eevee for viewport shading in LookDev shading mode");
+ prop = RNA_def_property(srna, "bl_use_gpu_context", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_GPU_CONTEXT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_ui_text(
+ prop,
+ "Use GPU Context",
+ "Enable OpenGL context for the render method, for engines that render using OpenGL");
+
prop = RNA_def_property(srna, "bl_use_shading_nodes_custom", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_SHADING_NODES_CUSTOM);
RNA_def_property_boolean_default(prop, true);
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
index 325c4e3caa9..450d148d8a3 100644
--- a/source/blender/makesrna/intern/rna_rigidbody.c
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -75,6 +75,11 @@ const EnumPropertyItem rna_enum_rigidbody_object_shape_items[] = {
"Mesh",
"Mesh consisting of triangles only, allowing for more detailed interactions than convex "
"hulls"},
+ {RB_SHAPE_COMPOUND,
+ "COMPOUND",
+ ICON_MESH_DATA,
+ "Compound Parent",
+ "Combines all of its direct rigid body children into one rigid object."},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 623b5864f5b..9f5440be9f8 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -479,7 +479,7 @@ static StructRNA *rna_Property_refine(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr); /* XXX ptr? */
+ prop = rna_ensure_property(prop);
switch (prop->type) {
case PROP_BOOLEAN:
@@ -504,90 +504,90 @@ static StructRNA *rna_Property_refine(PointerRNA *ptr)
static void rna_Property_identifier_get(PointerRNA *ptr, char *value)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
strcpy(value, ((PropertyRNA *)prop)->identifier);
}
static int rna_Property_identifier_length(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return strlen(prop->identifier);
}
static void rna_Property_name_get(PointerRNA *ptr, char *value)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
strcpy(value, prop->name ? prop->name : "");
}
static int rna_Property_name_length(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return prop->name ? strlen(prop->name) : 0;
}
static void rna_Property_description_get(PointerRNA *ptr, char *value)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
strcpy(value, prop->description ? prop->description : "");
}
static int rna_Property_description_length(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return prop->description ? strlen(prop->description) : 0;
}
static void rna_Property_translation_context_get(PointerRNA *ptr, char *value)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
strcpy(value, prop->translation_context);
}
static int rna_Property_translation_context_length(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return strlen(prop->translation_context);
}
static int rna_Property_type_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return prop->type;
}
static int rna_Property_subtype_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return prop->subtype;
}
static PointerRNA rna_Property_srna_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return rna_pointer_inherit_refine(ptr, &RNA_Struct, prop->srna);
}
static int rna_Property_unit_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return RNA_SUBTYPE_UNIT(prop->subtype);
}
static int rna_Property_icon_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return prop->icon;
}
@@ -698,7 +698,7 @@ static const EnumPropertyItem *rna_Property_tags_itemf(bContext *UNUSED(C),
static int rna_Property_array_length_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return prop->totarraylength;
}
@@ -706,7 +706,7 @@ static void rna_Property_array_dimensions_get(PointerRNA *ptr,
int dimensions[RNA_MAX_ARRAY_DIMENSION])
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
if (prop->arraydimension > 1) {
for (int i = RNA_MAX_ARRAY_DIMENSION; i--;) {
@@ -740,14 +740,14 @@ static bool rna_Property_is_runtime_get(PointerRNA *ptr)
static bool rna_BoolProperty_default_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((BoolPropertyRNA *)prop)->defaultvalue;
}
static int rna_IntProperty_default_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((IntPropertyRNA *)prop)->defaultvalue;
}
/* int/float/bool */
@@ -755,7 +755,7 @@ static int rna_NumberProperty_default_array_get_length(PointerRNA *ptr,
int length[RNA_MAX_ARRAY_DIMENSION])
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
length[0] = prop->totarraylength;
@@ -771,7 +771,7 @@ static bool rna_NumberProperty_is_array_get(PointerRNA *ptr)
static void rna_IntProperty_default_array_get(PointerRNA *ptr, int *values)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
if (prop->totarraylength > 0) {
PointerRNA null_ptr = PointerRNA_NULL;
RNA_property_int_get_default_array(&null_ptr, prop, values);
@@ -781,7 +781,7 @@ static void rna_IntProperty_default_array_get(PointerRNA *ptr, int *values)
static void rna_BoolProperty_default_array_get(PointerRNA *ptr, bool *values)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
if (prop->totarraylength > 0) {
PointerRNA null_ptr = PointerRNA_NULL;
RNA_property_boolean_get_default_array(&null_ptr, prop, values);
@@ -791,7 +791,7 @@ static void rna_BoolProperty_default_array_get(PointerRNA *ptr, bool *values)
static void rna_FloatProperty_default_array_get(PointerRNA *ptr, float *values)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
if (prop->totarraylength > 0) {
PointerRNA null_ptr = PointerRNA_NULL;
RNA_property_float_get_default_array(&null_ptr, prop, values);
@@ -801,103 +801,103 @@ static void rna_FloatProperty_default_array_get(PointerRNA *ptr, float *values)
static int rna_IntProperty_hard_min_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((IntPropertyRNA *)prop)->hardmin;
}
static int rna_IntProperty_hard_max_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((IntPropertyRNA *)prop)->hardmax;
}
static int rna_IntProperty_soft_min_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((IntPropertyRNA *)prop)->softmin;
}
static int rna_IntProperty_soft_max_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((IntPropertyRNA *)prop)->softmax;
}
static int rna_IntProperty_step_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((IntPropertyRNA *)prop)->step;
}
static float rna_FloatProperty_default_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((FloatPropertyRNA *)prop)->defaultvalue;
}
static float rna_FloatProperty_hard_min_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((FloatPropertyRNA *)prop)->hardmin;
}
static float rna_FloatProperty_hard_max_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((FloatPropertyRNA *)prop)->hardmax;
}
static float rna_FloatProperty_soft_min_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((FloatPropertyRNA *)prop)->softmin;
}
static float rna_FloatProperty_soft_max_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((FloatPropertyRNA *)prop)->softmax;
}
static float rna_FloatProperty_step_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((FloatPropertyRNA *)prop)->step;
}
static int rna_FloatProperty_precision_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((FloatPropertyRNA *)prop)->precision;
}
static void rna_StringProperty_default_get(PointerRNA *ptr, char *value)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
strcpy(value, ((StringPropertyRNA *)prop)->defaultvalue);
}
static int rna_StringProperty_default_length(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return strlen(((StringPropertyRNA *)prop)->defaultvalue);
}
static int rna_StringProperty_max_length_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((StringPropertyRNA *)prop)->maxlength;
}
@@ -909,7 +909,7 @@ static const EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C,
PropertyRNA *prop = (PropertyRNA *)ptr->data;
EnumPropertyRNA *eprop;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
eprop = (EnumPropertyRNA *)prop;
/* incompatible default attributes */
@@ -931,7 +931,7 @@ static const EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C,
static int rna_EnumProperty_default_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return ((EnumPropertyRNA *)prop)->defaultvalue;
}
@@ -950,7 +950,7 @@ static void rna_EnumProperty_items_begin(CollectionPropertyIterator *iter, Point
int totitem;
bool free;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
/* eprop = (EnumPropertyRNA *)prop; */
RNA_property_enum_items_ex(
@@ -1016,14 +1016,14 @@ static int rna_EnumPropertyItem_icon_get(PointerRNA *ptr)
static PointerRNA rna_PointerProperty_fixed_type_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((PointerPropertyRNA *)prop)->type);
}
static PointerRNA rna_CollectionProperty_fixed_type_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- rna_idproperty_check(&prop, ptr);
+ prop = rna_ensure_property(prop);
return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((CollectionPropertyRNA *)prop)->item_type);
}
@@ -1250,6 +1250,7 @@ static int rna_property_override_diff_propptr(Main *bmain,
IDOverrideLibrary *override,
const char *rna_path,
size_t rna_path_len,
+ const uint property_type,
const char *rna_itemname_a,
const char *rna_itemname_b,
const int rna_itemindex_a,
@@ -1257,6 +1258,8 @@ static int rna_property_override_diff_propptr(Main *bmain,
const int flags,
bool *r_override_changed)
{
+ BLI_assert(ELEM(property_type, PROP_POINTER, PROP_COLLECTION));
+
const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 &&
rna_path != NULL;
@@ -1300,6 +1303,13 @@ static int rna_property_override_diff_propptr(Main *bmain,
if (op != NULL) {
BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, false);
+ if (created || op->rna_prop_type == 0) {
+ op->rna_prop_type = property_type;
+ }
+ else {
+ BLI_assert(op->rna_prop_type == property_type);
+ }
+
if (created || rna_itemname_a != NULL || rna_itemname_b != NULL ||
rna_itemindex_a != -1 || rna_itemindex_b != -1) {
BKE_lib_override_library_property_operation_get(op,
@@ -1431,12 +1441,8 @@ static int rna_property_override_diff_propptr(Main *bmain,
RNA_property_##_typename##_set((_ptr), (_prop), (_value)))
int rna_property_override_diff_default(Main *bmain,
- PointerRNA *ptr_a,
- PointerRNA *ptr_b,
- PropertyRNA *prop_a,
- PropertyRNA *prop_b,
- const int len_a,
- const int len_b,
+ PropertyRNAOrID *prop_a,
+ PropertyRNAOrID *prop_b,
const int mode,
IDOverrideLibrary *override,
const char *rna_path,
@@ -1444,6 +1450,13 @@ int rna_property_override_diff_default(Main *bmain,
const int flags,
bool *r_override_changed)
{
+ PointerRNA *ptr_a = &prop_a->ptr;
+ PointerRNA *ptr_b = &prop_b->ptr;
+ PropertyRNA *rawprop_a = prop_a->rawprop;
+ PropertyRNA *rawprop_b = prop_b->rawprop;
+ const uint len_a = prop_a->array_len;
+ const uint len_b = prop_b->array_len;
+
BLI_assert(len_a == len_b);
/* Note: at this point, we are sure that when len_a is zero,
@@ -1452,7 +1465,20 @@ int rna_property_override_diff_default(Main *bmain,
const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 &&
rna_path != NULL;
- switch (RNA_property_type(prop_a)) {
+ const bool no_ownership = (prop_a->rnaprop->flag & PROP_PTR_NO_OWNERSHIP) != 0;
+ const bool no_prop_name = (prop_a->rnaprop->flag_override & PROPOVERRIDE_NO_PROP_NAME) != 0;
+
+ /* 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_collection_insertion = (prop_a->rnaprop->flag_override &
+ PROPOVERRIDE_LIBRARY_INSERTION) &&
+ do_create;
+
+ const uint rna_prop_type = RNA_property_type(prop_a->rnaprop);
+ bool created = false;
+ IDOverrideLibraryProperty *op = NULL;
+
+ switch (rna_prop_type) {
case PROP_BOOLEAN: {
if (len_a) {
bool array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
@@ -1463,16 +1489,14 @@ int rna_property_override_diff_default(Main *bmain,
array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(bool) * len_b, "RNA equals") :
array_stack_b;
- RNA_property_boolean_get_array(ptr_a, prop_a, array_a);
- RNA_property_boolean_get_array(ptr_b, prop_b, array_b);
+ RNA_property_boolean_get_array(ptr_a, rawprop_a, array_a);
+ RNA_property_boolean_get_array(ptr_b, rawprop_b, array_b);
const int comp = memcmp(array_a, array_b, sizeof(bool) * len_a);
if (do_create && comp != 0) {
/* XXX TODO this will have to be refined to handle array items */
- bool created = false;
- IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
- override, rna_path, &created);
+ op = BKE_lib_override_library_property_get(override, rna_path, &created);
if (op != NULL && created) {
BKE_lib_override_library_property_operation_get(
@@ -1496,14 +1520,12 @@ int rna_property_override_diff_default(Main *bmain,
return comp;
}
else {
- const bool value_a = RNA_property_boolean_get(ptr_a, prop_a);
- const bool value_b = RNA_property_boolean_get(ptr_b, prop_b);
+ const bool value_a = RNA_property_boolean_get(ptr_a, rawprop_a);
+ const bool value_b = RNA_property_boolean_get(ptr_b, rawprop_b);
const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
if (do_create && comp != 0) {
- bool created = false;
- IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
- override, rna_path, &created);
+ op = BKE_lib_override_library_property_get(override, rna_path, &created);
if (op != NULL && created) { /* If not yet overridden... */
BKE_lib_override_library_property_operation_get(
@@ -1528,16 +1550,14 @@ int rna_property_override_diff_default(Main *bmain,
array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(int) * len_b, "RNA equals") :
array_stack_b;
- RNA_property_int_get_array(ptr_a, prop_a, array_a);
- RNA_property_int_get_array(ptr_b, prop_b, array_b);
+ RNA_property_int_get_array(ptr_a, rawprop_a, array_a);
+ RNA_property_int_get_array(ptr_b, rawprop_b, array_b);
const int comp = memcmp(array_a, array_b, sizeof(int) * len_a);
if (do_create && comp != 0) {
/* XXX TODO this will have to be refined to handle array items */
- bool created = false;
- IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
- override, rna_path, &created);
+ op = BKE_lib_override_library_property_get(override, rna_path, &created);
if (op != NULL && created) {
BKE_lib_override_library_property_operation_get(
@@ -1561,14 +1581,12 @@ int rna_property_override_diff_default(Main *bmain,
return comp;
}
else {
- const int value_a = RNA_property_int_get(ptr_a, prop_a);
- const int value_b = RNA_property_int_get(ptr_b, prop_b);
+ const int value_a = RNA_property_int_get(ptr_a, rawprop_a);
+ const int value_b = RNA_property_int_get(ptr_b, rawprop_b);
const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
if (do_create && comp != 0) {
- bool created = false;
- IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
- override, rna_path, &created);
+ op = BKE_lib_override_library_property_get(override, rna_path, &created);
if (op != NULL && created) { /* If not yet overridden... */
BKE_lib_override_library_property_operation_get(
@@ -1593,16 +1611,14 @@ int rna_property_override_diff_default(Main *bmain,
array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(float) * len_b, "RNA equals") :
array_stack_b;
- RNA_property_float_get_array(ptr_a, prop_a, array_a);
- RNA_property_float_get_array(ptr_b, prop_b, array_b);
+ RNA_property_float_get_array(ptr_a, rawprop_a, array_a);
+ RNA_property_float_get_array(ptr_b, rawprop_b, array_b);
const int comp = memcmp(array_a, array_b, sizeof(float) * len_a);
if (do_create && comp != 0) {
/* XXX TODO this will have to be refined to handle array items */
- bool created = false;
- IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
- override, rna_path, &created);
+ op = BKE_lib_override_library_property_get(override, rna_path, &created);
if (op != NULL && created) {
BKE_lib_override_library_property_operation_get(
@@ -1626,14 +1642,12 @@ int rna_property_override_diff_default(Main *bmain,
return comp;
}
else {
- const float value_a = RNA_property_float_get(ptr_a, prop_a);
- const float value_b = RNA_property_float_get(ptr_b, prop_b);
+ const float value_a = RNA_property_float_get(ptr_a, rawprop_a);
+ const float value_b = RNA_property_float_get(ptr_b, rawprop_b);
const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
if (do_create && comp != 0) {
- bool created = false;
- IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
- override, rna_path, &created);
+ op = BKE_lib_override_library_property_get(override, rna_path, &created);
if (op != NULL && created) { /* If not yet overridden... */
BKE_lib_override_library_property_operation_get(
@@ -1649,14 +1663,12 @@ int rna_property_override_diff_default(Main *bmain,
}
case PROP_ENUM: {
- const int value_a = RNA_property_enum_get(ptr_a, prop_a);
- const int value_b = RNA_property_enum_get(ptr_b, prop_b);
+ const int value_a = RNA_property_enum_get(ptr_a, rawprop_a);
+ const int value_b = RNA_property_enum_get(ptr_b, rawprop_b);
const int comp = value_a != value_b;
if (do_create && comp != 0) {
- bool created = false;
- IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
- override, rna_path, &created);
+ op = BKE_lib_override_library_property_get(override, rna_path, &created);
if (op != NULL && created) { /* If not yet overridden... */
BKE_lib_override_library_property_operation_get(
@@ -1674,9 +1686,9 @@ int rna_property_override_diff_default(Main *bmain,
char fixed_a[4096], fixed_b[4096];
int len_str_a, len_str_b;
char *value_a = RNA_property_string_get_alloc(
- ptr_a, prop_a, fixed_a, sizeof(fixed_a), &len_str_a);
+ ptr_a, rawprop_a, fixed_a, sizeof(fixed_a), &len_str_a);
char *value_b = RNA_property_string_get_alloc(
- ptr_b, prop_b, fixed_b, sizeof(fixed_b), &len_str_b);
+ ptr_b, rawprop_b, fixed_b, sizeof(fixed_b), &len_str_b);
/* TODO we could do a check on length too,
* but then we would not have a 'real' string comparison...
* Maybe behind a eRNAOverrideMatch flag? */
@@ -1688,9 +1700,7 @@ int rna_property_override_diff_default(Main *bmain,
const int comp = strcmp(value_a, value_b);
if (do_create && comp != 0) {
- bool created = false;
- IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
- override, rna_path, &created);
+ op = BKE_lib_override_library_property_get(override, rna_path, &created);
if (op != NULL && created) { /* If not yet overridden... */
BKE_lib_override_library_property_operation_get(
@@ -1712,16 +1722,13 @@ int rna_property_override_diff_default(Main *bmain,
}
case PROP_POINTER: {
- if (STREQ(RNA_property_identifier(prop_a), "rna_type")) {
+ if (STREQ(prop_a->identifier, "rna_type")) {
/* Dummy 'pass' answer, this is a meta-data and must be ignored... */
return 0;
}
else {
- 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;
+ PointerRNA propptr_a = RNA_property_pointer_get(ptr_a, rawprop_a);
+ PointerRNA propptr_b = RNA_property_pointer_get(ptr_b, rawprop_b);
return rna_property_override_diff_propptr(bmain,
&propptr_a,
&propptr_b,
@@ -1731,6 +1738,7 @@ int rna_property_override_diff_default(Main *bmain,
override,
rna_path,
rna_path_len,
+ PROP_POINTER,
NULL,
NULL,
-1,
@@ -1742,14 +1750,6 @@ int rna_property_override_diff_default(Main *bmain,
}
case PROP_COLLECTION: {
- /* 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_override_flag(prop_a) &
- PROPOVERRIDE_LIBRARY_INSERTION) &&
- do_create;
- 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;
bool equals = true;
bool abort = false;
bool is_first_insert = true;
@@ -1757,8 +1757,8 @@ int rna_property_override_diff_default(Main *bmain,
int idx_b = 0;
CollectionPropertyIterator iter_a, iter_b;
- RNA_property_collection_begin(ptr_a, prop_a, &iter_a);
- RNA_property_collection_begin(ptr_b, prop_b, &iter_b);
+ RNA_property_collection_begin(ptr_a, rawprop_a, &iter_a);
+ RNA_property_collection_begin(ptr_b, rawprop_b, &iter_b);
char buff_a[4096];
char buff_prev_a[4096] = {0};
@@ -1773,7 +1773,7 @@ int rna_property_override_diff_default(Main *bmain,
do {
bool is_id = false, is_null = false, is_type_diff = false;
- is_valid_for_insertion = use_insertion;
+ is_valid_for_insertion = use_collection_insertion;
/* If false, it means that the whole data itself is different,
* so no point in going inside of it at all! */
@@ -1846,10 +1846,8 @@ int rna_property_override_diff_default(Main *bmain,
/* Collections do not support replacement of their data (except for collections of ID
* pointers), since they do not support removing, only in *some* cases, insertion. We
* also assume then that _a data is the one where things are inserted. */
- if (is_valid_for_insertion && use_insertion) {
- bool created;
- IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
- override, rna_path, &created);
+ if (is_valid_for_insertion && use_collection_insertion) {
+ op = BKE_lib_override_library_property_get(override, rna_path, &created);
if (is_first_insert) {
/* We need to clean up all possible existing insertion operations,
@@ -1882,6 +1880,7 @@ int rna_property_override_diff_default(Main *bmain,
prev_propname_a,
idx_a - 1);
# endif
+ op = NULL;
}
else if (is_id || is_valid_for_diffing) {
if (equals || do_create) {
@@ -1894,6 +1893,7 @@ int rna_property_override_diff_default(Main *bmain,
override,
rna_path,
rna_path_len,
+ PROP_COLLECTION,
propname_a,
propname_b,
idx_a,
@@ -1930,7 +1930,7 @@ int rna_property_override_diff_default(Main *bmain,
break;
}
- if (!(use_insertion && !(is_id || is_valid_for_diffing))) {
+ if (!(use_collection_insertion && !(is_id || is_valid_for_diffing))) {
break;
}
@@ -1962,6 +1962,15 @@ int rna_property_override_diff_default(Main *bmain,
break;
}
+ if (op != NULL) {
+ if (created || op->rna_prop_type == 0) {
+ op->rna_prop_type = rna_prop_type;
+ }
+ else {
+ BLI_assert(op->rna_prop_type == rna_prop_type);
+ }
+ }
+
return 0;
}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index d141e6f3b19..262c9f87b66 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -924,13 +924,6 @@ static void rna_Scene_volume_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P
DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_VOLUME | ID_RECALC_SEQUENCER_STRIPS);
}
-static const char *rna_Scene_statistics_string_get(Scene *UNUSED(scene),
- Main *UNUSED(bmain),
- ViewLayer *view_layer)
-{
- return ED_info_footer_string(view_layer);
-}
-
static void rna_Scene_framelen_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
scene->r.framelen = (float)scene->r.framapto / (float)scene->r.images;
@@ -2869,7 +2862,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
"3D Cursor",
"Draw stroke at 3D cursor location"},
/* Weird, GP_PROJECT_VIEWALIGN is inverted. */
- {0, "VIEW", ICON_RESTRICT_VIEW_ON, "View", "Stick stroke to the view "},
+ {0, "VIEW", ICON_RESTRICT_VIEW_ON, "View", "Stick stroke to the view"},
{GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_VIEW,
"SURFACE",
ICON_FACESEL,
@@ -3097,6 +3090,15 @@ static void rna_def_tool_settings(BlenderRNA *brna)
"Correct data such as UV's and vertex colors when transforming");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ prop = RNA_def_property(srna, "use_transform_correct_keep_connected", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(
+ prop, NULL, "uvcalc_flag", UVCALC_TRANSFORM_CORRECT_KEEP_CONNECTED);
+ RNA_def_property_ui_text(
+ prop,
+ "Keep Connected",
+ "During the Face Attributes correction, merge attributes connected to the same vertex");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
prop = RNA_def_property(srna, "use_mesh_automerge", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "automerge", AUTO_MERGE);
RNA_def_property_ui_text(
@@ -3456,7 +3458,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_edge_path_live_unwrap", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "edge_mode_live_unwrap", 1);
- RNA_def_property_ui_text(prop, "Live Unwrap", "Changing edges seam re-calculates UV unwrap");
+ RNA_def_property_ui_text(prop, "Live Unwrap", "Changing edges seam recalculates UV unwrap");
prop = RNA_def_property(srna, "normal_vector", PROP_FLOAT, PROP_XYZ);
RNA_def_property_ui_text(prop, "Normal Vector", "Normal Vector used to copy, add or multiply");
@@ -3587,7 +3589,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, brush_size_unit_items);
RNA_def_property_ui_text(
- prop, "Radius Unit", "Measure brush size relative to the view or the scene ");
+ prop, "Radius Unit", "Measure brush size relative to the view or the scene");
}
static void rna_def_curve_paint_settings(BlenderRNA *brna)
@@ -4814,7 +4816,7 @@ void rna_def_freestyle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(
prop,
"View Map Cache",
- "Keep the computed view map and avoid re-calculating it if mesh geometry is unchanged");
+ "Keep the computed view map and avoid recalculating it if mesh geometry is unchanged");
RNA_def_property_update(
prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_use_view_map_cache_update");
@@ -6463,7 +6465,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "simplify_gpencil_shader_fx", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_FX);
- RNA_def_property_ui_text(prop, "ShadersFX", "Display Shader FX");
+ RNA_def_property_ui_text(prop, "Shaders Effects", "Display Shader Effects");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
prop = RNA_def_property(srna, "simplify_gpencil_tint", PROP_BOOLEAN, PROP_NONE);
@@ -7275,9 +7277,6 @@ void RNA_def_scene(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- 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"},
@@ -7669,14 +7668,6 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE, NULL);
RNA_def_property_update(prop, NC_SCENE, "rna_Scene_volume_update");
- /* Statistics */
- func = RNA_def_function(srna, "statistics", "rna_Scene_statistics_string_get");
- RNA_def_function_flag(func, FUNC_USE_MAIN);
- parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "Active layer");
- 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 e9c59fc5011..06c73fbb19c 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -98,13 +98,13 @@ static void rna_Scene_frame_set(Scene *scene, Main *bmain, int frame, float subf
}
}
-static void rna_Scene_uvedit_aspect(Scene *scene, Object *ob, float *aspect)
+static void rna_Scene_uvedit_aspect(Scene *UNUSED(scene), Object *ob, float *aspect)
{
if ((ob->type == OB_MESH) && (ob->mode == OB_MODE_EDIT)) {
BMEditMesh *em;
em = BKE_editmesh_from_object(ob);
if (EDBM_uv_check(em)) {
- ED_uvedit_get_aspect(scene, ob, em->bm, aspect, aspect + 1);
+ ED_uvedit_get_aspect(ob, aspect, aspect + 1);
return;
}
}
@@ -138,8 +138,7 @@ static void rna_SceneRender_get_frame_path(
}
static void rna_Scene_ray_cast(Scene *scene,
- Main *bmain,
- ViewLayer *view_layer,
+ Depsgraph *depsgraph,
float origin[3],
float direction[3],
float ray_dist,
@@ -151,8 +150,6 @@ static void rna_Scene_ray_cast(Scene *scene,
float r_obmat[16])
{
normalize_v3(direction);
-
- Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true);
SnapObjectContext *sctx = ED_transform_snap_object_context_create(scene, 0);
bool ret = ED_transform_snap_object_project_ray_ex(sctx,
@@ -292,9 +289,9 @@ void RNA_api_scene(StructRNA *srna)
/* 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");
+
+ parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "The current dependency graph");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
/* ray start and end */
parm = RNA_def_float_vector(func, "origin", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 20ae69dc031..fb2a60db0fd 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -30,6 +30,8 @@
#include "DNA_screen_types.h"
#include "DNA_workspace_types.h"
+#include "ED_info.h"
+
const EnumPropertyItem rna_enum_region_type_items[] = {
{RGN_TYPE_WINDOW, "WINDOW", 0, "Window", ""},
{RGN_TYPE_HEADER, "HEADER", 0, "Header", ""},
@@ -90,6 +92,12 @@ static bool rna_Screen_is_animation_playing_get(PointerRNA *UNUSED(ptr))
return wm ? (ED_screen_animation_playing(wm) != NULL) : 0;
}
+static bool rna_Screen_is_scrubbing_get(PointerRNA *ptr)
+{
+ bScreen *screen = (bScreen *)ptr->data;
+ return screen->scrubbing;
+}
+
static int rna_region_alignment_get(PointerRNA *ptr)
{
ARegion *region = ptr->data;
@@ -223,7 +231,7 @@ static int rna_Area_ui_type_get(PointerRNA *ptr)
* the area type is changing.
* So manually do the lookup in those cases, but do not actually change area->type
* since that prevents a proper exit when the area type is changing.
- * Logic copied from `ED_area_initialize()`.*/
+ * Logic copied from `ED_area_init()`.*/
SpaceType *type = area->type;
if (type == NULL || area_changing) {
type = BKE_spacetype_from_id(area_type);
@@ -280,6 +288,11 @@ static void rna_View2D_view_to_region(
}
}
+static const char *rna_Screen_statusbar_info_get(struct bScreen *screen, Main *bmain, bContext *C)
+{
+ return ED_info_statusbar_string(bmain, screen, C);
+}
+
#else
/* Area.spaces */
@@ -354,7 +367,7 @@ static void rna_def_area(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Area_type_update");
prop = RNA_def_property(srna, "ui_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, DummyRNA_NULL_items); /* infact dummy */
+ RNA_def_property_enum_items(prop, DummyRNA_NULL_items); /* in fact dummy */
RNA_def_property_enum_default(prop, SPACE_VIEW3D << 16);
RNA_def_property_enum_funcs(
prop, "rna_Area_ui_type_get", "rna_Area_ui_type_set", "rna_Area_ui_type_itemf");
@@ -530,6 +543,9 @@ static void rna_def_screen(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
srna = RNA_def_struct(brna, "Screen", "ID");
RNA_def_struct_sdna(srna, "Screen"); /* it is actually bScreen but for 2.5 the dna is patched! */
RNA_def_struct_ui_text(
@@ -548,6 +564,12 @@ static void rna_def_screen(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_Screen_is_animation_playing_get", NULL);
RNA_def_property_ui_text(prop, "Animation Playing", "Animation playback is active");
+ prop = RNA_def_property(srna, "is_scrubbing", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_funcs(prop, "rna_Screen_is_scrubbing_get", NULL);
+ RNA_def_property_ui_text(
+ prop, "User is Scrubbing", "True when the user is scrubbing through time");
+
prop = RNA_def_property(srna, "is_temporary", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_sdna(prop, NULL, "temp", 1);
@@ -558,11 +580,18 @@ static void rna_def_screen(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_Screen_fullscreen_get", NULL);
RNA_def_property_ui_text(prop, "Maximize", "An area is maximized, filling this screen");
+ /* Status Bar. */
+
prop = RNA_def_property(srna, "show_statusbar", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SCREEN_COLLAPSE_STATUSBAR);
- RNA_def_property_ui_text(prop, "Show Status Bar", "Show status bar");
+ RNA_def_property_ui_text(prop, "Show Status Bar", "Show Status Bar");
RNA_def_property_update(prop, 0, "rna_Screen_bar_update");
+ func = RNA_def_function(srna, "statusbar_info", "rna_Screen_statusbar_info_get");
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_CONTEXT);
+ parm = RNA_def_string(func, "statusbar_info", NULL, 0, "Status Bar Info", "");
+ RNA_def_function_return(func, parm);
+
/* Define Anim Playback Areas */
prop = RNA_def_property(srna, "use_play_top_left_3d_editor", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "redraws_flag", TIME_REGION);
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 7342879e9e6..0cfc6fd569c 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -749,6 +749,25 @@ static IDProperty *rna_Sequence_idprops(PointerRNA *ptr, bool create)
return seq->prop;
}
+static bool rna_MovieSequence_reload_if_needed(ID *scene_id, Sequence *seq, Main *bmain)
+{
+ Scene *scene = (Scene *)scene_id;
+ bool has_reloaded;
+ bool can_produce_frames;
+
+ BKE_sequence_movie_reload_if_needed(bmain, scene, seq, &has_reloaded, &can_produce_frames);
+
+ if (has_reloaded && can_produce_frames) {
+ BKE_sequence_calc(scene, seq);
+ BKE_sequence_invalidate_cache_raw(scene, seq);
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
+ WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
+ }
+
+ return can_produce_frames;
+}
+
static PointerRNA rna_MovieSequence_metadata_get(Sequence *seq)
{
if (seq == NULL || seq->anims.first == NULL) {
@@ -843,6 +862,43 @@ static int rna_Sequence_input_count_get(PointerRNA *ptr)
return BKE_sequence_effect_get_num_inputs(seq->type);
}
+static void rna_Sequence_input_set(PointerRNA *ptr,
+ PointerRNA ptr_value,
+ struct ReportList *reports,
+ int input_num)
+{
+
+ Sequence *seq = ptr->data;
+ Sequence *input = ptr_value.data;
+
+ if (BKE_sequencer_render_loop_check(input, seq)) {
+ BKE_report(reports, RPT_ERROR, "Cannot reassign inputs: recursion detected");
+ return;
+ }
+
+ switch (input_num) {
+ case 1:
+ seq->seq1 = input;
+ break;
+ case 2:
+ seq->seq2 = input;
+ break;
+ }
+}
+
+static void rna_Sequence_input_1_set(PointerRNA *ptr,
+ PointerRNA ptr_value,
+ struct ReportList *reports)
+{
+ rna_Sequence_input_set(ptr, ptr_value, reports, 1);
+}
+
+static void rna_Sequence_input_2_set(PointerRNA *ptr,
+ PointerRNA ptr_value,
+ struct ReportList *reports)
+{
+ rna_Sequence_input_set(ptr, ptr_value, reports, 2);
+}
# if 0
static void rna_SoundSequence_filename_set(PointerRNA *ptr, const char *value)
{
@@ -1253,6 +1309,24 @@ static void rna_Sequence_modifier_clear(Sequence *seq, bContext *C)
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
}
+static void rna_SequenceModifier_strip_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *reports)
+{
+ SequenceModifierData *smd = ptr->data;
+ Scene *scene = (Scene *)ptr->owner_id;
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *seq = sequence_get_by_modifier(ed, smd);
+ Sequence *target = (Sequence *)value.data;
+
+ if (target != NULL && BKE_sequencer_render_loop_check(target, seq)) {
+ BKE_report(reports, RPT_ERROR, "Recursion detected, can not use this strip");
+ return;
+ }
+
+ smd->mask_sequence = target;
+}
+
static float rna_Sequence_fps_get(PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->owner_id;
@@ -2126,7 +2200,7 @@ static void rna_def_proxy(StructRNA *srna)
prop = RNA_def_property(srna, "use_proxy", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_USE_PROXY);
RNA_def_property_ui_text(
- prop, "Use Proxy / Timecode", "Use a preview proxy and/or timecode index for this strip");
+ prop, "Use Proxy / Timecode", "Use a preview proxy and/or time-code index for this strip");
RNA_def_property_boolean_funcs(prop, NULL, "rna_Sequence_use_proxy_set");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
@@ -2174,6 +2248,7 @@ static void rna_def_effect_inputs(StructRNA *srna, int count)
prop = RNA_def_property(srna, "input_1", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "seq1");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_Sequence_input_1_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Input 1", "First input for the effect strip");
}
@@ -2181,6 +2256,7 @@ static void rna_def_effect_inputs(StructRNA *srna, int count)
prop = RNA_def_property(srna, "input_2", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "seq2");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_NULL);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_Sequence_input_2_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Input 2", "Second input for the effect strip");
}
@@ -2385,6 +2461,13 @@ static void rna_def_movie(BlenderRNA *brna)
"rna_Sequence_filepath_set");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_filepath_update");
+ func = RNA_def_function(srna, "reload_if_needed", "rna_MovieSequence_reload_if_needed");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+ /* return type */
+ parm = RNA_def_boolean(
+ func, "can_produce_frames", 0, "True if the strip can produce frames, False otherwise", "");
+ RNA_def_function_return(func, parm);
+
/* metadata */
func = RNA_def_function(srna, "metadata", "rna_MovieSequence_metadata_get");
RNA_def_function_ui_description(func, "Retrieve metadata of the movie file");
@@ -3027,8 +3110,11 @@ static void rna_def_modifier(BlenderRNA *brna)
prop = RNA_def_property(srna, "input_mask_strip", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mask_sequence");
- RNA_def_property_pointer_funcs(
- prop, NULL, NULL, NULL, "rna_SequenceModifier_otherSequence_poll");
+ RNA_def_property_pointer_funcs(prop,
+ NULL,
+ "rna_SequenceModifier_strip_set",
+ NULL,
+ "rna_SequenceModifier_otherSequence_poll");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Mask Strip", "Strip used as mask input for the modifier");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 28603132c77..59cedf8fcb8 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -79,7 +79,6 @@ static Sequence *alloc_generic_sequence(
Editing *ed, const char *name, int frame_start, int channel, int type, const char *file)
{
Sequence *seq;
- Strip *strip;
StripElem *se;
seq = BKE_sequence_alloc(ed->seqbasep, frame_start, channel, type);
@@ -87,8 +86,7 @@ static Sequence *alloc_generic_sequence(
BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2);
BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq);
- seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
- seq->strip->us = 1;
+ Strip *strip = seq->strip;
if (file) {
strip->stripdata = se = MEM_callocN(sizeof(StripElem), "stripelem");
@@ -207,33 +205,28 @@ static Sequence *rna_Sequences_new_image(ID *id,
return seq;
}
-static Sequence *rna_Sequences_new_movie(ID *id,
- Editing *ed,
- ReportList *reports,
- const char *name,
- const char *file,
- int channel,
- int frame_start)
+static Sequence *rna_Sequences_new_movie(
+ ID *id, Editing *ed, const char *name, const char *file, int channel, int frame_start)
{
Scene *scene = (Scene *)id;
Sequence *seq;
StripAnim *sanim;
- struct anim *an = openanim(file, IB_rect, 0, NULL);
+ seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIE, file);
+ struct anim *an = openanim(file, IB_rect, 0, NULL);
if (an == NULL) {
- BKE_report(reports, RPT_ERROR, "Sequences.new_movie: unable to open movie file");
- return NULL;
+ /* Without anim, the strip gets duration 0, which makes it impossible to select in the UI. */
+ seq->len = 1;
}
+ else {
+ sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
+ BLI_addtail(&seq->anims, sanim);
+ sanim->anim = an;
- seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIE, file);
-
- sanim = MEM_mallocN(sizeof(StripAnim), "Strip Anim");
- BLI_addtail(&seq->anims, sanim);
- sanim->anim = an;
-
- seq->anim_preseek = IMB_anim_get_preseek(an);
- seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN);
+ seq->anim_preseek = IMB_anim_get_preseek(an);
+ seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN);
+ }
BKE_sequence_calc_disp(scene, seq);
BKE_sequence_invalidate_cache_composite(scene, seq);
@@ -377,13 +370,14 @@ static void rna_Sequences_remove(
Sequence *seq = seq_ptr->data;
Scene *scene = (Scene *)id;
- if (BLI_remlink_safe(&ed->seqbase, seq) == false) {
+ if (BLI_findindex(&ed->seqbase, seq) == -1) {
BKE_reportf(
reports, RPT_ERROR, "Sequence '%s' not in scene '%s'", seq->name + 2, scene->id.name + 2);
return;
}
- BKE_sequence_free(scene, seq, true);
+ BKE_sequencer_flag_for_removal(scene, &ed->seqbase, seq);
+ BKE_sequencer_remove_flagged_sequences(scene, &ed->seqbase);
RNA_POINTER_INVALIDATE(seq_ptr);
DEG_relations_tag_update(bmain);
@@ -506,7 +500,7 @@ void RNA_api_sequence_strip(StructRNA *srna)
func = RNA_def_function(srna, "invalidate_cache", "rna_Sequence_invalidate_cache_rnafunc");
RNA_def_function_flag(func, FUNC_USE_SELF_ID);
RNA_def_function_ui_description(func,
- "Invalidate Cached images for strip and all dependant strips. ");
+ "Invalidate cached images for strip and all dependent strips");
parm = RNA_def_enum(func, "type", seq_cahce_type_items, 0, "Type", "Cache Type");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
}
@@ -669,7 +663,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "new_movie", "rna_Sequences_new_movie");
- RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
RNA_def_function_ui_description(func, "Add a new movie sequence");
parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
diff --git a/source/blender/makesrna/intern/rna_shader_fx.c b/source/blender/makesrna/intern/rna_shader_fx.c
index 80f3cab147c..7b039b91188 100644
--- a/source/blender/makesrna/intern/rna_shader_fx.c
+++ b/source/blender/makesrna/intern/rna_shader_fx.c
@@ -168,7 +168,7 @@ static char *rna_ShaderFx_path(PointerRNA *ptr)
static void rna_ShaderFx_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
DEG_id_tag_update(ptr->owner_id, ID_RECALC_GEOMETRY);
- WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ptr->owner_id);
+ WM_main_add_notifier(NC_OBJECT | ND_SHADERFX, ptr->owner_id);
}
static void rna_ShaderFx_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -220,7 +220,7 @@ static void rna_def_shader_fx_blur(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "radius");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Size", "Factor of Blur");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samples");
@@ -228,18 +228,18 @@ static void rna_def_shader_fx_blur(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 32, 2, -1);
RNA_def_property_int_default(prop, 4);
RNA_def_property_ui_text(prop, "Samples", "Number of Blur Samples (zero, disable blur)");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "rotation");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_text(prop, "Rotation", "Rotation of the effect");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "use_dof_mode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_BLUR_DOF_MODE);
RNA_def_property_ui_text(prop, "Use as Depth Of Field", "Blur using camera depth of field");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
}
static void rna_def_shader_fx_colorize(BlenderRNA *brna)
@@ -256,27 +256,27 @@ static void rna_def_shader_fx_colorize(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "factor");
RNA_def_property_range(prop, 0, 1.0);
RNA_def_property_ui_text(prop, "Factor", "Mix factor");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "low_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "low_color");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Low Color", "First color used for effect");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "high_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "high_color");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "High Color", "Second color used for effect");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, rna_enum_shaderfx_colorize_modes_items);
RNA_def_property_ui_text(prop, "Mode", "Effect mode");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
}
static void rna_def_shader_fx_wave(BlenderRNA *brna)
@@ -298,25 +298,25 @@ static void rna_def_shader_fx_wave(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "orientation");
RNA_def_property_enum_items(prop, prop_shaderfx_wave_type_items);
RNA_def_property_ui_text(prop, "Orientation", "Direction of the wave");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "amplitude");
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_text(prop, "Amplitude", "Amplitude of Wave");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "period", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "period");
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_text(prop, "Period", "Period of Wave");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "phase", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "phase");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_text(prop, "Phase", "Phase Shift of Wave");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
}
static void rna_def_shader_fx_pixel(BlenderRNA *brna)
@@ -334,12 +334,12 @@ static void rna_def_shader_fx_pixel(BlenderRNA *brna)
RNA_def_property_range(prop, 1, SHRT_MAX);
RNA_def_property_array(prop, 2);
RNA_def_property_ui_text(prop, "Size", "Pixel size");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "use_antialiasing", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", FX_PIXEL_FILTER_NEAREST);
- RNA_def_property_ui_text(prop, "Antialiasing", "Antialiase pixels");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_ui_text(prop, "Antialiasing", "Antialias pixels");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
}
static void rna_def_shader_fx_rim(BlenderRNA *brna)
@@ -356,34 +356,34 @@ static void rna_def_shader_fx_rim(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "offset");
RNA_def_property_range(prop, SHRT_MIN, SHRT_MAX);
RNA_def_property_ui_text(prop, "Offset", "Offset of the rim");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "rim_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "rim_rgb");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Rim Color", "Color used for Rim");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "mask_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "mask_rgb");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Mask Color", "Color that must be kept");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, rna_enum_shaderfx_rim_modes_items);
RNA_def_property_ui_text(prop, "Mode", "Blend mode");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "blur", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "blur");
RNA_def_property_range(prop, 0, SHRT_MAX);
RNA_def_property_ui_text(
prop, "Blur", "Number of pixels for blurring rim (set to 0 to disable)");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samples");
@@ -391,7 +391,7 @@ static void rna_def_shader_fx_rim(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 32, 2, -1);
RNA_def_property_int_default(prop, 4);
RNA_def_property_ui_text(prop, "Samples", "Number of Blur Samples (zero, disable blur)");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
}
static void rna_def_shader_fx_shadow(BlenderRNA *brna)
@@ -420,58 +420,58 @@ static void rna_def_shader_fx_shadow(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "offset");
RNA_def_property_range(prop, SHRT_MIN, SHRT_MAX);
RNA_def_property_ui_text(prop, "Offset", "Offset of the shadow");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "scale");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_text(prop, "Scale", "Offset of the shadow");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "shadow_rgba");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Shadow Color", "Color used for Shadow");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "orientation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "orientation");
RNA_def_property_enum_items(prop, prop_shaderfx_shadow_type_items);
RNA_def_property_ui_text(prop, "Orientation", "Direction of the wave");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "amplitude");
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_text(prop, "Amplitude", "Amplitude of Wave");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "period", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "period");
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_text(prop, "Period", "Period of Wave");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "phase", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "phase");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_text(prop, "Phase", "Phase Shift of Wave");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "rotation");
RNA_def_property_range(prop, DEG2RAD(-360), DEG2RAD(360));
RNA_def_property_ui_range(prop, DEG2RAD(-360), DEG2RAD(360), 5, 2);
RNA_def_property_ui_text(prop, "Rotation", "Rotation around center or object");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "blur", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "blur");
RNA_def_property_range(prop, 0, SHRT_MAX);
RNA_def_property_ui_text(
prop, "Blur", "Number of pixels for blurring shadow (set to 0 to disable)");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samples");
@@ -479,17 +479,17 @@ static void rna_def_shader_fx_shadow(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 32, 2, -1);
RNA_def_property_int_default(prop, 4);
RNA_def_property_ui_text(prop, "Samples", "Number of Blur Samples (zero, disable blur)");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "use_object", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_SHADOW_USE_OBJECT);
RNA_def_property_ui_text(prop, "Use Object", "Use object as center of rotation");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "use_wave", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_SHADOW_USE_WAVE);
RNA_def_property_ui_text(prop, "Wave", "Use wave effect");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
}
static void rna_def_shader_fx_glow(BlenderRNA *brna)
@@ -507,41 +507,41 @@ static void rna_def_shader_fx_glow(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "glow_color");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Glow Color", "Color used for generated glow");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "glow_color[3]");
RNA_def_property_range(prop, 0.0, 1.0f);
RNA_def_property_ui_text(prop, "Opacity", "Effect Opacity");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "select_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_float_sdna(prop, NULL, "select_color");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Select Color", "Color selected to apply glow");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, rna_enum_shaderfx_glow_modes_items);
RNA_def_property_ui_text(prop, "Mode", "Glow mode");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "threshold");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 3);
RNA_def_property_ui_text(prop, "Threshold", "Limit to select color for glow effect");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
/* Use blur fields to make compatible with blur filter */
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "blur");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Size", "Size of the effect");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "samples");
@@ -549,26 +549,26 @@ static void rna_def_shader_fx_glow(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, 32, 2, -1);
RNA_def_property_int_default(prop, 4);
RNA_def_property_ui_text(prop, "Samples", "Number of Blur Samples");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "use_glow_under", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_GLOW_USE_ALPHA);
RNA_def_property_ui_text(
prop, "Glow Under", "Glow only areas with alpha (not supported with Regular blend mode)");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "rotation");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_text(prop, "Rotation", "Rotation of the effect");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
/* blend mode */
prop = RNA_def_property(srna, "blend_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "blend_mode");
RNA_def_property_enum_items(prop, rna_enum_glow_blend_modes_items);
RNA_def_property_ui_text(prop, "Blend Mode", "Blend mode");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
}
static void rna_def_shader_fx_swirl(BlenderRNA *brna)
@@ -585,19 +585,19 @@ static void rna_def_shader_fx_swirl(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "radius");
RNA_def_property_range(prop, 0, SHRT_MAX);
RNA_def_property_ui_text(prop, "Radius", "Radius to apply");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "angle");
RNA_def_property_range(prop, DEG2RAD(-5 * 360), DEG2RAD(5 * 360));
RNA_def_property_ui_range(prop, DEG2RAD(-5 * 360), DEG2RAD(5 * 360), 5, 2);
RNA_def_property_ui_text(prop, "Angle", "Angle of rotation");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "use_transparent", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_SWIRL_MAKE_TRANSPARENT);
RNA_def_property_ui_text(prop, "Transparent", "Make image transparent outside of radius");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Object", "Object to determine center location");
@@ -620,12 +620,12 @@ static void rna_def_shader_fx_flip(BlenderRNA *brna)
prop = RNA_def_property(srna, "flip_horizontal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_FLIP_HORIZONTAL);
RNA_def_property_ui_text(prop, "Horizontal", "Flip image horizontally");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "flip_vertical", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_FLIP_VERTICAL);
RNA_def_property_ui_text(prop, "Vertical", "Flip image vertically");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
}
void RNA_def_shader_fx(BlenderRNA *brna)
@@ -644,7 +644,7 @@ void RNA_def_shader_fx(BlenderRNA *brna)
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ShaderFx_name_set");
RNA_def_property_ui_text(prop, "Name", "Effect name");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER | NA_RENAME, NULL);
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX | NA_RENAME, NULL);
RNA_def_struct_name_property(srna, prop);
/* enums */
@@ -661,7 +661,7 @@ void RNA_def_shader_fx(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Realtime", "Display effect in viewport");
RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_ON, 1);
prop = RNA_def_property(srna, "show_render", PROP_BOOLEAN, PROP_NONE);
@@ -669,12 +669,12 @@ void RNA_def_shader_fx(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "Render", "Use effect during render");
RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_ON, 1);
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, NULL);
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, NULL);
prop = RNA_def_property(srna, "show_in_editmode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", eShaderFxMode_Editmode);
RNA_def_property_ui_text(prop, "Edit Mode", "Display effect in Edit mode");
- RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
+ RNA_def_property_update(prop, NC_OBJECT | ND_SHADERFX, "rna_ShaderFx_update");
RNA_def_property_ui_icon(prop, ICON_EDITMODE_HLT, 0);
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 49a21799d5b..155f5ab3043 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1776,87 +1776,28 @@ static const EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSE
{
SpaceProperties *sbuts = (SpaceProperties *)(ptr->data);
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 (totitem) {
- RNA_enum_item_add_separator(&item, &totitem);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_OUTPUT)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OUTPUT);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_VIEW_LAYER);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD);
- }
- if (totitem) {
- RNA_enum_item_add_separator(&item, &totitem);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OBJECT);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MODIFIER);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SHADERFX);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PARTICLE);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PHYSICS);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_CONSTRAINT);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_DATA)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_DATA);
- (item + totitem - 1)->icon = sbuts->dataicon;
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_BONE)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE_CONSTRAINT);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MATERIAL);
- }
+ /* We use 32 tabs maximum here so a flag for each can fit into a 32 bit integer flag.
+ * A theoretical maximum would be BCONTEXT_TOT * 2, with every tab displayed and a spacer
+ * in every other item. But this size is currently limited by the size of integer
+ * supported by RNA enums. */
+ int context_tabs_array[32];
+ int totitem = ED_buttons_tabs_list(sbuts, context_tabs_array);
+ BLI_assert(totitem <= ARRAY_SIZE(context_tabs_array));
+
+ int totitem_added = 0;
+ for (int i = 0; i < totitem; i++) {
+ if (context_tabs_array[i] == -1) {
+ RNA_enum_item_add_separator(&item, &totitem_added);
+ continue;
+ }
- if (totitem) {
- RNA_enum_item_add_separator(&item, &totitem);
- }
+ RNA_enum_items_add_value(&item, &totitem_added, buttons_context_items, context_tabs_array[i]);
- if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TEXTURE);
+ /* Add the object data icon dynamically for the data tab. */
+ if (context_tabs_array[i] == BCONTEXT_DATA) {
+ (item + totitem_added - 1)->icon = sbuts->dataicon;
+ }
}
RNA_enum_item_end(&item, &totitem);
@@ -6601,7 +6542,7 @@ static void rna_def_space_clip(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_graph_only_selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_SEL_ONLY);
RNA_def_property_ui_text(
- prop, "Only Selected", "Only include channels relating to selected objects and data");
+ prop, "Only Show 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_SPACE | ND_SPACE_CLIP, NULL);
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 54fe2e4b513..27297a4d19a 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -2440,7 +2440,7 @@ static void rna_def_trackingDopesheet(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_only_selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_DOPE_SELECTED_ONLY);
RNA_def_property_ui_text(
- prop, "Only Selected", "Only include channels relating to selected objects and data");
+ prop, "Only Show 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_MOVIECLIP | NA_EDITED, "rna_trackingDopesheet_tagUpdate");
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index c31b313d827..0567b22d23f 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -179,6 +179,7 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = {
# include "BKE_blender.h"
# include "BKE_global.h"
# include "BKE_idprop.h"
+# include "BKE_image.h"
# include "BKE_main.h"
# include "BKE_mesh_runtime.h"
# include "BKE_paint.h"
@@ -187,8 +188,9 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = {
# include "DEG_depsgraph.h"
-# include "GPU_draw.h"
+# include "GPU_extensions.h"
# include "GPU_select.h"
+# include "GPU_texture.h"
# include "BLF_api.h"
@@ -362,13 +364,14 @@ static void rna_userdef_load_ui_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- GPU_set_anisotropic(U.anisotropic_filter);
+ GPU_samplers_free();
+ GPU_samplers_init();
rna_userdef_update(bmain, scene, ptr);
}
static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- GPU_free_images(bmain);
+ BKE_image_free_all_gputextures(bmain);
rna_userdef_update(bmain, scene, ptr);
}
@@ -439,13 +442,12 @@ 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 */
+ /* Set the time-code style. */
userdef->timecode_style = value;
- /* adjust the v2d gridsize if needed so that timecodes don't overlap
+ /* Adjust the v2d grid-size if needed so that time-codes don't overlap
* NOTE: most of these have been hand-picked to avoid overlaps while still keeping
- * things from getting too blown out
- */
+ * things from getting too blown out. */
switch (value) {
case USER_TIMECODE_MINIMAL:
case USER_TIMECODE_SECONDS_ONLY:
@@ -1066,6 +1068,11 @@ static void rna_UserDef_studiolight_light_ambient_get(PointerRNA *ptr, float *va
copy_v3_v3(values, sl->light_ambient);
}
+int rna_show_statusbar_vram_editable(struct PointerRNA *UNUSED(ptr), const char **UNUSED(r_info))
+{
+ return GPU_mem_stats_supported() ? PROP_EDITABLE : 0;
+}
+
#else
# define USERDEF_TAG_DIRTY_PROPERTY_UPDATE_ENABLE \
@@ -2272,7 +2279,7 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
prop = RNA_def_property(srna, "editmesh_active", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
- RNA_def_property_ui_text(prop, "Active Vert/Edge/Face", "");
+ RNA_def_property_ui_text(prop, "Active Vertex/Edge/Face", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_COLOR_GAMMA);
@@ -2971,7 +2978,7 @@ static void rna_def_userdef_theme_space_image(BlenderRNA *brna)
prop = RNA_def_property(srna, "editmesh_active", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
- RNA_def_property_ui_text(prop, "Active Vert/Edge/Face", "");
+ RNA_def_property_ui_text(prop, "Active Vertex/Edge/Face", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "wire_edit", PROP_FLOAT, PROP_COLOR_GAMMA);
@@ -3973,12 +3980,13 @@ static void rna_def_userdef_studiolights(BlenderRNA *brna)
func = RNA_def_function(srna, "new", "rna_StudioLights_new");
RNA_def_function_ui_description(func, "Create studiolight from default lighting");
- parm = RNA_def_string(func,
- "path",
- NULL,
- 0,
- "Path",
- "Path to the file that will contain the lighing info (without extension)");
+ parm = RNA_def_string(
+ func,
+ "path",
+ NULL,
+ 0,
+ "Path",
+ "Path to the file that will contain the lighting info (without extension)");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func, "studio_light", "StudioLight", "", "Newly created StudioLight");
RNA_def_function_return(func, parm);
@@ -4587,7 +4595,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
"no matter opening direction");
static const EnumPropertyItem header_align_items[] = {
- {0, "NONE", 0, "Default", "Keep existing header alignment"},
+ {0, "NONE", 0, "Keep Existing", "Keep existing header alignment"},
{USER_HEADER_FROM_PREF, "TOP", 0, "Top", "Top aligned on load"},
{USER_HEADER_FROM_PREF | USER_HEADER_BOTTOM,
"BOTTOM",
@@ -4770,6 +4778,29 @@ static void rna_def_userdef_view(BlenderRNA *brna)
"Translate New Names",
"Translate the names of new data-blocks (objects, materials...)");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* Statusbar. */
+
+ prop = RNA_def_property(srna, "show_statusbar_memory", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "statusbar_flag", STATUSBAR_SHOW_MEMORY);
+ RNA_def_property_ui_text(prop, "Show Memory", "Show Blender memory usage");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_INFO, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "show_statusbar_vram", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "statusbar_flag", STATUSBAR_SHOW_VRAM);
+ RNA_def_property_ui_text(prop, "Show VRAM", "Show GPU video memory usage");
+ RNA_def_property_editable_func(prop, "rna_show_statusbar_vram_editable");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_INFO, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "show_statusbar_version", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "statusbar_flag", STATUSBAR_SHOW_VERSION);
+ RNA_def_property_ui_text(prop, "Show Version", "Show Blender version string");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_INFO, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "show_statusbar_stats", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "statusbar_flag", STATUSBAR_SHOW_STATS);
+ RNA_def_property_ui_text(prop, "Show Statistics", "Show scene statistics");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_INFO, "rna_userdef_update");
}
static void rna_def_userdef_edit(BlenderRNA *brna)
@@ -4959,7 +4990,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
/* grease pencil */
prop = RNA_def_property(srna, "grease_pencil_manhattan_distance", PROP_INT, PROP_PIXEL);
- RNA_def_property_int_sdna(prop, NULL, "gp_manhattendist");
+ RNA_def_property_int_sdna(prop, NULL, "gp_manhattandist");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop,
"Grease Pencil Manhattan Distance",
@@ -6084,6 +6115,10 @@ static void rna_def_userdef_experimental(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "use_cycles_debug", 1);
RNA_def_property_ui_text(prop, "Cycles Debug", "Enable Cycles debugging options for developers");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "use_sculpt_vertex_colors", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "use_sculpt_vertex_colors", 1);
+ RNA_def_property_ui_text(prop, "Sculpt Vertex Colors", "Use the new Vertex Painting system");
}
static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop)
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 80a1ebab64e..cf87e3598b6 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -23,9 +23,9 @@ set(INC
intern
../blenfont
../blenkernel
- ../blentranslation
../blenlib
../blenloader
+ ../blentranslation
../bmesh
../depsgraph
../editors/include
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index ba676bbe459..b011abf336d 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -18,8 +18,7 @@
* \ingroup modifiers
*/
-#ifndef __MOD_MODIFIERTYPES_H__
-#define __MOD_MODIFIERTYPES_H__
+#pragma once
#include "BKE_modifier.h"
@@ -94,5 +93,3 @@ void modifier_type_init(ModifierTypeInfo *types[]);
#ifdef __cplusplus
}
#endif
-
-#endif /* __MOD_MODIFIERTYPES_H__ */
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index b62c03d1b03..e7f47a09d95 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -165,10 +165,15 @@ static void deformVerts(ModifierData *md,
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
struct BMEditMesh *em,
- Mesh *UNUSED(mesh),
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
+ if (mesh != NULL) {
+ deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ return;
+ }
+
ArmatureModifierData *amd = (ArmatureModifierData *)md;
MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 21bb7f4764a..c0428785009 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -73,6 +73,7 @@ static void initData(ModifierData *md)
bmd->face_str_mode = MOD_BEVEL_FACE_STRENGTH_NONE;
bmd->miter_inner = MOD_BEVEL_MITER_SHARP;
bmd->miter_outer = MOD_BEVEL_MITER_SHARP;
+ bmd->affect_type = MOD_BEVEL_AFFECT_EDGES;
bmd->spread = 0.1f;
bmd->mat = -1;
bmd->profile = 0.5f;
@@ -117,7 +118,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MDeformVert *dvert = NULL;
BevelModifierData *bmd = (BevelModifierData *)md;
const float threshold = cosf(bmd->bevel_angle + 0.000000175f);
- const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0;
const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK);
const int offset_type = bmd->val_flags;
const int profile_type = bmd->profile_type;
@@ -131,7 +131,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
const int miter_outer = bmd->miter_outer;
const int miter_inner = bmd->miter_inner;
const float spread = bmd->spread;
- const int vmesh_method = bmd->vmesh_method;
const bool invert_vgroup = (bmd->flags & MOD_BEVEL_INVERT_VGROUP) != 0;
bm = BKE_mesh_to_bmesh_ex(mesh,
@@ -152,7 +151,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MOD_get_vgroup(ctx->object, mesh, bmd->defgrp_name, &dvert, &vgroup);
}
- if (vertex_only) {
+ if (bmd->affect_type == MOD_BEVEL_AFFECT_VERTICES) {
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
weight = BM_elem_float_data_get(&bm->vdata, v, CD_BWEIGHT);
@@ -230,7 +229,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
profile_type,
bmd->res,
bmd->profile,
- vertex_only,
+ bmd->affect_type,
bmd->lim_flags & MOD_BEVEL_WEIGHT,
do_clamp,
dvert,
@@ -246,7 +245,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
spread,
mesh->smoothresh,
bmd->custom_profile,
- vmesh_method);
+ bmd->vmesh_method);
result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
@@ -286,7 +285,7 @@ static void panel_draw(const bContext *C, Panel *panel)
PointerRNA ob_ptr;
modifier_panel_get_property_pointers(C, panel, &ob_ptr, &ptr);
- bool edge_bevel = RNA_enum_get(&ptr, "affect") != MOD_BEVEL_VERT;
+ bool edge_bevel = RNA_enum_get(&ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
uiItemR(layout, &ptr, "affect", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
@@ -308,7 +307,7 @@ static void panel_draw(const bContext *C, Panel *panel)
col = uiLayoutColumn(layout, false);
uiItemR(col, &ptr, "limit_method", 0, NULL, ICON_NONE);
int limit_method = RNA_enum_get(&ptr, "limit_method");
- if (limit_method != MOD_BEVEL_ANGLE) {
+ if (limit_method == MOD_BEVEL_ANGLE) {
sub = uiLayoutColumn(col, false);
uiLayoutSetActive(sub, edge_bevel);
uiItemR(col, &ptr, "angle_limit", 0, NULL, ICON_NONE);
@@ -331,7 +330,7 @@ static void profile_panel_draw(const bContext *C, Panel *panel)
int profile_type = RNA_enum_get(&ptr, "profile_type");
int miter_inner = RNA_enum_get(&ptr, "miter_inner");
int miter_outer = RNA_enum_get(&ptr, "miter_outer");
- bool edge_bevel = RNA_enum_get(&ptr, "affect") != MOD_BEVEL_VERT;
+ bool edge_bevel = RNA_enum_get(&ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
uiItemR(layout, &ptr, "profile_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
@@ -368,7 +367,7 @@ static void geometry_panel_draw(const bContext *C, Panel *panel)
PointerRNA ptr;
modifier_panel_get_property_pointers(C, panel, NULL, &ptr);
- bool edge_bevel = RNA_enum_get(&ptr, "affect") != MOD_BEVEL_VERT;
+ bool edge_bevel = RNA_enum_get(&ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
uiLayoutSetPropSep(layout, true);
@@ -402,7 +401,7 @@ static void shading_panel_draw(const bContext *C, Panel *panel)
PointerRNA ptr;
modifier_panel_get_property_pointers(C, panel, NULL, &ptr);
- bool edge_bevel = RNA_enum_get(&ptr, "affect") != MOD_BEVEL_VERT;
+ bool edge_bevel = RNA_enum_get(&ptr, "affect") != MOD_BEVEL_AFFECT_VERTICES;
uiLayoutSetPropSep(layout, true);
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index 760e4717b6d..42adf305ee9 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -150,10 +150,15 @@ static void deformVerts(ModifierData *md,
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
BMEditMesh *em,
- Mesh *UNUSED(mesh),
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
+ if (mesh != NULL) {
+ deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ return;
+ }
+
CurveModifierData *cmd = (CurveModifierData *)md;
bool use_dverts = false;
int defgrp_index = -1;
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index f6ad25ce282..4e46e135b72 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -254,7 +254,7 @@ static void remap_faces_3_6_9_12(Mesh *mesh,
Mesh *split,
MFace *mf,
int *facepa,
- int *vertpa,
+ const int *vertpa,
int i,
EdgeHash *eh,
int cur,
@@ -322,7 +322,7 @@ static void remap_faces_5_10(Mesh *mesh,
Mesh *split,
MFace *mf,
int *facepa,
- int *vertpa,
+ const int *vertpa,
int i,
EdgeHash *eh,
int cur,
@@ -378,7 +378,7 @@ static void remap_faces_15(Mesh *mesh,
Mesh *split,
MFace *mf,
int *facepa,
- int *vertpa,
+ const int *vertpa,
int i,
EdgeHash *eh,
int cur,
@@ -462,7 +462,7 @@ static void remap_faces_7_11_13_14(Mesh *mesh,
Mesh *split,
MFace *mf,
int *facepa,
- int *vertpa,
+ const int *vertpa,
int i,
EdgeHash *eh,
int cur,
@@ -531,7 +531,7 @@ static void remap_faces_19_21_22(Mesh *mesh,
Mesh *split,
MFace *mf,
int *facepa,
- int *vertpa,
+ const int *vertpa,
int i,
EdgeHash *eh,
int cur,
@@ -585,7 +585,7 @@ static void remap_faces_23(Mesh *mesh,
Mesh *split,
MFace *mf,
int *facepa,
- int *vertpa,
+ const int *vertpa,
int i,
EdgeHash *eh,
int cur,
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index c8cfc07562f..746f9e56c06 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -23,6 +23,7 @@
#include "BLI_utildefines.h"
+#include "BLI_bitmap.h"
#include "BLI_math.h"
#include "BLT_translation.h"
@@ -40,6 +41,7 @@
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_screen.h"
@@ -139,7 +141,10 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
struct HookData_cb {
float (*vertexCos)[3];
- MDeformVert *dvert;
+ /**
+ * When anything other than -1, use deform groups.
+ * This is not the same as checking `dvert` for NULL when we have edit-meshes.
+ */
int defgrp_index;
struct CurveMapping *curfalloff;
@@ -160,6 +165,20 @@ struct HookData_cb {
bool invert_vgroup;
};
+static BLI_bitmap *hook_index_array_to_bitmap(HookModifierData *hmd, const int numVerts)
+{
+ BLI_bitmap *indexar_used = BLI_BITMAP_NEW(numVerts, __func__);
+ int i;
+ int *index_pt;
+ for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
+ const int j = *index_pt;
+ if (j < numVerts) {
+ BLI_BITMAP_ENABLE(indexar_used, i);
+ }
+ }
+ return indexar_used;
+}
+
static float hook_falloff(const struct HookData_cb *hd, const float len_sq)
{
BLI_assert(hd->falloff_sq);
@@ -226,7 +245,7 @@ static float hook_falloff(const struct HookData_cb *hd, const float len_sq)
}
}
-static void hook_co_apply(struct HookData_cb *hd, const int j)
+static void hook_co_apply(struct HookData_cb *hd, int j, const MDeformVert *dv)
{
float *co = hd->vertexCos[j];
float fac;
@@ -250,9 +269,9 @@ static void hook_co_apply(struct HookData_cb *hd, const int j)
}
if (fac) {
- if (hd->dvert) {
- fac *= hd->invert_vgroup ? 1.0f - BKE_defvert_find_weight(&hd->dvert[j], hd->defgrp_index) :
- BKE_defvert_find_weight(&hd->dvert[j], hd->defgrp_index);
+ if (dv != NULL) {
+ fac *= hd->invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, hd->defgrp_index) :
+ BKE_defvert_find_weight(dv, hd->defgrp_index);
}
if (fac) {
@@ -267,6 +286,7 @@ static void deformVerts_do(HookModifierData *hmd,
const ModifierEvalContext *UNUSED(ctx),
Object *ob,
Mesh *mesh,
+ BMEditMesh *em,
float (*vertexCos)[3],
int numVerts)
{
@@ -274,6 +294,7 @@ static void deformVerts_do(HookModifierData *hmd,
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_target->pose, hmd->subtarget);
float dmat[4][4];
int i, *index_pt;
+ MDeformVert *dvert;
struct HookData_cb hd;
const bool invert_vgroup = (hmd->flag & MOD_HOOK_INVERT_VGROUP) != 0;
@@ -283,12 +304,21 @@ static void deformVerts_do(HookModifierData *hmd,
}
if (hmd->curfalloff) {
- BKE_curvemapping_initialize(hmd->curfalloff);
+ BKE_curvemapping_init(hmd->curfalloff);
}
/* Generic data needed for applying per-vertex calculations (initialize all members) */
hd.vertexCos = vertexCos;
- MOD_get_vgroup(ob, mesh, hmd->name, &hd.dvert, &hd.defgrp_index);
+
+ MOD_get_vgroup(ob, mesh, hmd->name, &dvert, &hd.defgrp_index);
+ int cd_dvert_offset = -1;
+
+ if ((em != NULL) && (hd.defgrp_index != -1)) {
+ cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+ if (cd_dvert_offset == -1) {
+ hd.defgrp_index = -1;
+ }
+ }
hd.curfalloff = hmd->curfalloff;
@@ -337,32 +367,62 @@ static void deformVerts_do(HookModifierData *hmd,
}
else if (hmd->indexar) { /* vertex indices? */
const int *origindex_ar;
-
/* if mesh is present and has original index data, use it */
if (mesh && (origindex_ar = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX))) {
- for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
- if (*index_pt < numVerts) {
- int j;
-
- for (j = 0; j < numVerts; j++) {
- if (origindex_ar[j] == *index_pt) {
- hook_co_apply(&hd, j);
- }
- }
+ int numVerts_orig = numVerts;
+ if (ob->type == OB_MESH) {
+ const Mesh *me_orig = ob->data;
+ numVerts_orig = me_orig->totvert;
+ }
+ BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, numVerts_orig);
+ for (i = 0; i < numVerts; i++) {
+ int i_orig = origindex_ar[i];
+ BLI_assert(i_orig < numVerts_orig);
+ if (BLI_BITMAP_TEST(indexar_used, i_orig)) {
+ hook_co_apply(&hd, i, dvert ? &dvert[i] : NULL);
}
}
+ MEM_freeN(indexar_used);
}
else { /* missing mesh or ORIGINDEX */
- for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
- if (*index_pt < numVerts) {
- hook_co_apply(&hd, *index_pt);
+ if ((em != NULL) && (hd.defgrp_index != -1)) {
+ BLI_assert(em->bm->totvert == numVerts);
+ BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, numVerts);
+ BMIter iter;
+ BMVert *v;
+ BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ if (BLI_BITMAP_TEST(indexar_used, i)) {
+ const MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(v, cd_dvert_offset);
+ hook_co_apply(&hd, i, dv);
+ }
+ }
+ MEM_freeN(indexar_used);
+ }
+ else {
+ for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
+ const int j = *index_pt;
+ if (j < numVerts) {
+ hook_co_apply(&hd, j, dvert ? &dvert[j] : NULL);
+ }
}
}
}
}
- else if (hd.dvert) { /* vertex group hook */
- for (i = 0; i < numVerts; i++) {
- hook_co_apply(&hd, i);
+ else if (hd.defgrp_index != -1) { /* vertex group hook */
+ if (em != NULL) {
+ BLI_assert(em->bm->totvert == numVerts);
+ BMIter iter;
+ BMVert *v;
+ BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+ const MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(v, cd_dvert_offset);
+ hook_co_apply(&hd, i, dv);
+ }
+ }
+ else {
+ BLI_assert(dvert != NULL);
+ for (i = 0; i < numVerts; i++) {
+ hook_co_apply(&hd, i, &dvert[i]);
+ }
}
}
}
@@ -376,7 +436,7 @@ static void deformVerts(struct ModifierData *md,
HookModifierData *hmd = (HookModifierData *)md;
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- deformVerts_do(hmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ deformVerts_do(hmd, ctx, ctx->object, mesh_src, NULL, vertexCos, numVerts);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -391,14 +451,8 @@ static void deformVertsEM(struct ModifierData *md,
int numVerts)
{
HookModifierData *hmd = (HookModifierData *)md;
- Mesh *mesh_src = MOD_deform_mesh_eval_get(
- ctx->object, editData, mesh, NULL, numVerts, false, false);
-
- deformVerts_do(hmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ deformVerts_do(hmd, ctx, ctx->object, mesh, mesh ? NULL : editData, vertexCos, numVerts);
}
static void panel_draw(const bContext *C, Panel *panel)
diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c
index b1a9258ec51..bf891c4938b 100644
--- a/source/blender/modifiers/intern/MOD_lattice.c
+++ b/source/blender/modifiers/intern/MOD_lattice.c
@@ -130,10 +130,15 @@ static void deformVerts(ModifierData *md,
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
struct BMEditMesh *em,
- struct Mesh *UNUSED(mesh),
+ struct Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
+ if (mesh != NULL) {
+ deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ return;
+ }
+
LatticeModifierData *lmd = (LatticeModifierData *)md;
MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc
index 93fb7749392..7b09d3c470d 100644
--- a/source/blender/modifiers/intern/MOD_mask.cc
+++ b/source/blender/modifiers/intern/MOD_mask.cc
@@ -44,12 +44,7 @@
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
-
-/* SpaceType struct has a member called 'new' which obviously conflicts with C++
- * so temporarily redefining the new keyword to make it compile. */
-#define new extern_new
#include "BKE_screen.h"
-#undef new
#include "UI_interface.h"
#include "UI_resources.h"
diff --git a/source/blender/modifiers/intern/MOD_meshcache_util.h b/source/blender/modifiers/intern/MOD_meshcache_util.h
index 0a6c0e73632..74131099e3c 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_util.h
+++ b/source/blender/modifiers/intern/MOD_meshcache_util.h
@@ -18,8 +18,7 @@
* \ingroup modifiers
*/
-#ifndef __MOD_MESHCACHE_UTIL_H__
-#define __MOD_MESHCACHE_UTIL_H__
+#pragma once
/* MOD_meshcache_mdd.c */
bool MOD_meshcache_read_mdd_index(FILE *fp,
@@ -73,5 +72,3 @@ void MOD_meshcache_calc_range(const float frame,
float *r_factor);
#define FRAME_SNAP_EPS 0.0001f
-
-#endif /* __MOD_MESHCACHE_UTIL_H__ */
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index e53de598218..ae031bffb04 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -409,11 +409,12 @@ static void meshdeformModifier_do(ModifierData *md,
totcagevert = cagemesh->totvert;
if (mmd->totvert != totvert) {
- BKE_modifier_set_error(md, "Verts changed from %d to %d", mmd->totvert, totvert);
+ BKE_modifier_set_error(md, "Vertices changed from %d to %d", mmd->totvert, totvert);
goto finally;
}
else if (mmd->totcagevert != totcagevert) {
- BKE_modifier_set_error(md, "Cage verts changed from %d to %d", mmd->totcagevert, totcagevert);
+ BKE_modifier_set_error(
+ md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert);
goto finally;
}
else if (mmd->bindcagecos == NULL) {
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index 8f6676dd0b2..5513e6b4971 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -33,6 +33,8 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "MEM_guardedalloc.h"
+
#include "BKE_cachefile.h"
#include "BKE_context.h"
#include "BKE_lib_query.h"
@@ -65,6 +67,9 @@ static void initData(ModifierData *md)
mcmd->cache_file = NULL;
mcmd->object_path[0] = '\0';
mcmd->read_flag = MOD_MESHSEQ_READ_ALL;
+ mcmd->velocity_scale = 1.0f;
+ mcmd->vertex_velocities = NULL;
+ mcmd->num_vertices = 0;
mcmd->reader = NULL;
mcmd->reader_object_path[0] = '\0';
@@ -91,6 +96,10 @@ static void freeData(ModifierData *md)
mcmd->reader_object_path[0] = '\0';
BKE_cachefile_reader_free(mcmd->cache_file, &mcmd->reader);
}
+
+ if (mcmd->vertex_velocities) {
+ MEM_freeN(mcmd->vertex_velocities);
+ }
}
static bool isDisabled(const struct Scene *UNUSED(scene),
@@ -154,6 +163,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Mesh *result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag);
+ mcmd->velocity_delta = 1.0f;
+ if (mcmd->cache_file->velocity_unit == CACHEFILE_VELOCITY_UNIT_SECOND) {
+ mcmd->velocity_delta /= FPS;
+ }
+
+ mcmd->last_lookup_time = time;
+
+ if (result != NULL) {
+ mcmd->num_vertices = result->totvert;
+ }
+
if (err_str) {
BKE_modifier_set_error(md, "%s", err_str);
}
@@ -221,6 +241,8 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(layout, &ptr, "read_data", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
+ uiItemR(layout, &ptr, "velocity_scale", 0, NULL, ICON_NONE);
+
modifier_panel_end(layout, &ptr);
}
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index 53e53315cfe..f091385ff8e 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -75,6 +75,29 @@ static void initData(ModifierData *md)
mmd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
mmd->quality = 4;
mmd->flags |= (eMultiresModifierFlag_UseCrease | eMultiresModifierFlag_ControlEdges);
+
+ /* Open subdivision panels by default. */
+ md->ui_expand_flag = (1 << 0) | (1 << 1);
+}
+
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
+{
+ MultiresModifierData *mmd = (MultiresModifierData *)md;
+ if (mmd->flags & eMultiresModifierFlag_UseCustomNormals) {
+ r_cddata_masks->lmask |= CD_MASK_NORMAL;
+ r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL;
+ }
+}
+
+static bool dependsOnNormals(ModifierData *md)
+{
+ MultiresModifierData *mmd = (MultiresModifierData *)md;
+ if (mmd->flags & eMultiresModifierFlag_UseCustomNormals) {
+ return true;
+ }
+ return false;
}
static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag)
@@ -205,6 +228,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Happens on bad topology, ut also on empty input mesh. */
return result;
}
+ const bool use_clnors = mmd->flags & eMultiresModifierFlag_UseCustomNormals &&
+ mesh->flag & ME_AUTOSMOOTH &&
+ CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
/* NOTE: Orco needs final coordinates on CPU side, which are expected to be
* accessible via MVert. For this reason we do not evaluate multires to
* grids when orco is requested. */
@@ -240,7 +266,22 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
// BKE_subdiv_stats_print(&subdiv->stats);
}
else {
+ if (use_clnors) {
+ /* If custom normals are present and the option is turned on calculate the split
+ * normals and clear flag so the normals get interpolated to the result mesh. */
+ BKE_mesh_calc_normals_split(mesh);
+ CustomData_clear_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+
result = multires_as_mesh(mmd, ctx, mesh, subdiv);
+
+ if (use_clnors) {
+ float(*lnors)[3] = CustomData_get_layer(&result->ldata, CD_NORMAL);
+ BLI_assert(lnors != NULL);
+ BKE_mesh_set_custom_normals(result, lnors);
+ CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
// BKE_subdiv_stats_print(&subdiv->stats);
if (subdiv != runtime_data->subdiv) {
BKE_subdiv_free(subdiv);
@@ -287,13 +328,37 @@ static void deformMatrices(ModifierData *md,
static void panel_draw(const bContext *C, Panel *panel)
{
- uiLayout *row, *col, *split, *col2;
+ uiLayout *col;
+ uiLayout *layout = panel->layout;
+
+ PointerRNA ptr;
+ modifier_panel_get_property_pointers(C, panel, NULL, &ptr);
+
+ uiLayoutSetPropSep(layout, true);
+
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, &ptr, "levels", 0, IFACE_("Level Viewport"), ICON_NONE);
+ uiItemR(col, &ptr, "sculpt_levels", 0, IFACE_("Sculpt"), ICON_NONE);
+ uiItemR(col, &ptr, "render_levels", 0, IFACE_("Render"), ICON_NONE);
+
+ uiItemR(layout, &ptr, "show_only_control_edges", 0, NULL, ICON_NONE);
+
+ modifier_panel_end(layout, &ptr);
+}
+
+static void subdivisions_panel_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *row;
uiLayout *layout = panel->layout;
PointerRNA ptr;
PointerRNA ob_ptr;
modifier_panel_get_property_pointers(C, panel, &ob_ptr, &ptr);
+ uiLayoutSetEnabled(layout, RNA_enum_get(&ob_ptr, "mode") != OB_MODE_EDIT);
+
+ MultiresModifierData *mmd = (MultiresModifierData *)ptr.data;
+
/**
* Changing some of the properties can not be done once there is an
* actual displacement stored for this multi-resolution modifier.
@@ -304,33 +369,9 @@ static void panel_draw(const bContext *C, Panel *panel)
* non-zero displacement, but such checks will be too slow to be done
* on every redraw.
*/
- bool has_displacement = RNA_int_get(&ptr, "total_levels") != 0;
- MultiresModifierData *mmd = (MultiresModifierData *)ptr.data;
-
- uiLayoutSetPropSep(layout, true);
-
- col = uiLayoutColumn(layout, false);
- uiLayoutSetEnabled(col, !has_displacement);
- uiItemR(col, &ptr, "subdivision_type", 0, NULL, ICON_NONE);
-
- col = uiLayoutColumn(layout, true);
- uiItemR(col, &ptr, "sculpt_levels", 0, IFACE_("Levels Sculpt"), ICON_NONE);
- uiItemR(col, &ptr, "levels", 0, IFACE_("Viewport"), ICON_NONE);
- uiItemR(col, &ptr, "render_levels", 0, IFACE_("Render"), ICON_NONE);
- uiItemR(layout, &ptr, "show_only_control_edges", 0, NULL, ICON_NONE);
- uiItemS(layout);
-
- split = uiLayoutSplit(layout, 0.5f, false);
- uiLayoutSetEnabled(split, RNA_enum_get(&ob_ptr, "mode") != OB_MODE_EDIT);
- col = uiLayoutColumn(split, false);
- col2 = uiLayoutColumn(split, false);
-
- uiItemO(col, IFACE_("Unsubdivide"), ICON_NONE, "OBJECT_OT_multires_unsubdivide");
-
- row = uiLayoutRow(col2, true);
PointerRNA op_ptr;
- uiItemFullO(row,
+ uiItemFullO(layout,
"OBJECT_OT_multires_subdivide",
IFACE_("Subdivide"),
ICON_NONE,
@@ -340,10 +381,12 @@ static void panel_draw(const bContext *C, Panel *panel)
&op_ptr);
RNA_enum_set(&op_ptr, "mode", MULTIRES_SUBDIVIDE_CATMULL_CLARK);
RNA_string_set(&op_ptr, "modifier", ((ModifierData *)mmd)->name);
+
+ row = uiLayoutRow(layout, false);
uiItemFullO(row,
"OBJECT_OT_multires_subdivide",
IFACE_("Simple"),
- ICON_NONE, /* TODO: Needs icon, remove text */
+ ICON_NONE,
NULL,
WM_OP_EXEC_DEFAULT,
0,
@@ -353,7 +396,7 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemFullO(row,
"OBJECT_OT_multires_subdivide",
IFACE_("Linear"),
- ICON_NONE, /* TODO: Needs icon, remove text */
+ ICON_NONE,
NULL,
WM_OP_EXEC_DEFAULT,
0,
@@ -361,13 +404,41 @@ static void panel_draw(const bContext *C, Panel *panel)
RNA_enum_set(&op_ptr, "mode", MULTIRES_SUBDIVIDE_LINEAR);
RNA_string_set(&op_ptr, "modifier", ((ModifierData *)mmd)->name);
- uiItemL(col, "", ICON_NONE);
- uiItemO(col2, IFACE_("Delete Higher"), ICON_NONE, "OBJECT_OT_multires_higher_levels_delete");
+ uiItemS(layout);
- uiItemO(col, IFACE_("Reshape"), ICON_NONE, "OBJECT_OT_multires_reshape");
- uiItemO(col2, IFACE_("Apply Base"), ICON_NONE, "OBJECT_OT_multires_base_apply");
+ uiItemO(layout, IFACE_("Unsubdivide"), ICON_NONE, "OBJECT_OT_multires_unsubdivide");
- uiItemS(layout);
+ row = uiLayoutRow(layout, false);
+ uiItemL(row, "", ICON_NONE);
+ uiItemO(row, IFACE_("Delete Higher"), ICON_NONE, "OBJECT_OT_multires_higher_levels_delete");
+}
+
+static void shape_panel_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *row;
+ uiLayout *layout = panel->layout;
+
+ PointerRNA ptr;
+ PointerRNA ob_ptr;
+ modifier_panel_get_property_pointers(C, panel, &ob_ptr, &ptr);
+
+ uiLayoutSetEnabled(layout, RNA_enum_get(&ob_ptr, "mode") != OB_MODE_EDIT);
+
+ row = uiLayoutRow(layout, false);
+ uiItemO(row, IFACE_("Reshape"), ICON_NONE, "OBJECT_OT_multires_reshape");
+ uiItemO(row, IFACE_("Apply Base"), ICON_NONE, "OBJECT_OT_multires_base_apply");
+}
+
+static void generate_panel_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *col, *row;
+ uiLayout *layout = panel->layout;
+
+ PointerRNA ptr;
+ modifier_panel_get_property_pointers(C, panel, NULL, &ptr);
+ MultiresModifierData *mmd = (MultiresModifierData *)ptr.data;
+
+ bool is_external = RNA_boolean_get(&ptr, "is_external");
if (mmd->totlvl == 0) {
uiItemO(
@@ -376,16 +447,15 @@ static void panel_draw(const bContext *C, Panel *panel)
col = uiLayoutColumn(layout, false);
row = uiLayoutRow(col, false);
- if (RNA_boolean_get(&ptr, "is_external")) {
+ if (is_external) {
uiItemO(row, IFACE_("Pack External"), ICON_NONE, "OBJECT_OT_multires_external_pack");
+ uiLayoutSetPropSep(col, true);
row = uiLayoutRow(col, false);
- uiItemR(row, &ptr, "filepath", 0, "", ICON_NONE);
+ uiItemR(row, &ptr, "filepath", 0, NULL, ICON_NONE);
}
else {
uiItemO(col, IFACE_("Save External..."), ICON_NONE, "OBJECT_OT_multires_external_save");
}
-
- modifier_panel_end(layout, &ptr);
}
static void advanced_panel_draw(const bContext *C, Panel *panel)
@@ -400,21 +470,28 @@ static void advanced_panel_draw(const bContext *C, Panel *panel)
uiLayoutSetPropSep(layout, true);
- col = uiLayoutColumn(layout, false);
- uiLayoutSetEnabled(col, !has_displacement);
- uiItemR(col, &ptr, "quality", 0, NULL, ICON_NONE);
+ uiLayoutSetEnabled(layout, !has_displacement);
- uiItemR(layout, &ptr, "uv_smooth", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "subdivision_type", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "quality", 0, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
- uiLayoutSetEnabled(col, !has_displacement);
- uiItemR(col, &ptr, "use_creases", 0, NULL, ICON_NONE);
+ uiLayoutSetEnabled(col, true);
+ uiItemR(col, &ptr, "uv_smooth", 0, NULL, ICON_NONE);
+
+ uiItemR(layout, &ptr, "use_creases", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "use_custom_normals", 0, NULL, ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
{
PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Multires, panel_draw);
modifier_subpanel_register(
+ region_type, "subdivide", "Subdivions", NULL, subdivisions_panel_draw, panel_type);
+ modifier_subpanel_register(region_type, "shape", "Shape", NULL, shape_panel_draw, panel_type);
+ modifier_subpanel_register(
+ region_type, "generate", "Generate", NULL, generate_panel_draw, panel_type);
+ modifier_subpanel_register(
region_type, "advanced", "Advanced", NULL, advanced_panel_draw, panel_type);
}
@@ -438,12 +515,12 @@ ModifierTypeInfo modifierType_Multires = {
/* modifyVolume */ NULL,
/* initData */ initData,
- /* requiredDataMask */ NULL,
+ /* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
/* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index cb5c67087c4..7b31886a220 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -59,7 +59,7 @@
#include "MOD_ui_common.h"
#ifdef WITH_OCEANSIM
-static void init_cache_data(Object *ob, struct OceanModifierData *omd)
+static void init_cache_data(Object *ob, struct OceanModifierData *omd, const int resolution)
{
const char *relbase = BKE_modifier_path_relbase_from_global(ob);
@@ -71,7 +71,7 @@ static void init_cache_data(Object *ob, struct OceanModifierData *omd)
omd->chop_amount,
omd->foam_coverage,
omd->foam_fade,
- omd->resolution);
+ resolution);
}
static void simulate_ocean_modifier(struct OceanModifierData *omd)
@@ -87,7 +87,11 @@ static void initData(ModifierData *md)
#ifdef WITH_OCEANSIM
OceanModifierData *omd = (OceanModifierData *)md;
+ /* Render resolution */
omd->resolution = 7;
+ /* Display resolution for the non-render case */
+ omd->viewport_resolution = 7;
+
omd->spatial_size = 50;
omd->wave_alignment = 0.0;
@@ -126,7 +130,7 @@ static void initData(ModifierData *md)
omd->spraylayername[0] = '\0'; /* layer name empty by default */
omd->ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(omd->ocean, omd);
+ BKE_ocean_init_from_modifier(omd->ocean, omd, omd->viewport_resolution);
simulate_ocean_modifier(omd);
#else /* WITH_OCEANSIM */
/* unused */
@@ -164,7 +168,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
tomd->oceancache = NULL;
tomd->ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(tomd->ocean, tomd);
+ BKE_ocean_init_from_modifier(tomd->ocean, tomd, tomd->viewport_resolution);
simulate_ocean_modifier(tomd);
#else /* WITH_OCEANSIM */
/* unused */
@@ -288,7 +292,7 @@ static void generate_ocean_geometry_uvs(void *__restrict userdata,
}
}
-static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig)
+static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, const int resolution)
{
Mesh *result;
@@ -297,10 +301,10 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig)
int num_verts;
int num_polys;
- const bool use_threading = omd->resolution > 4;
+ const bool use_threading = resolution > 4;
- gogd.rx = omd->resolution * omd->resolution;
- gogd.ry = omd->resolution * omd->resolution;
+ gogd.rx = resolution * resolution;
+ gogd.ry = resolution * resolution;
gogd.res_x = gogd.rx * omd->repeat_x;
gogd.res_y = gogd.ry * omd->repeat_y;
@@ -362,6 +366,9 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
Mesh *result = NULL;
OceanResult ocr;
+ const int resolution = (ctx->flag & MOD_APPLY_RENDER) ? omd->resolution :
+ omd->viewport_resolution;
+
MVert *mverts;
int cfra_for_cache;
@@ -383,7 +390,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
/* do ocean simulation */
if (omd->cached == true) {
if (!omd->oceancache) {
- init_cache_data(ob, omd);
+ init_cache_data(ob, omd, resolution);
}
BKE_ocean_simulate_cache(omd->oceancache, cfra_scene);
}
@@ -393,12 +400,12 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
* This function is only called on an original object when applying the modifier
* using the 'Apply Modifier' button, and thus it is not called frequently for
* simulation. */
- allocated_ocean |= BKE_ocean_ensure(omd);
+ allocated_ocean |= BKE_ocean_ensure(omd, resolution);
simulate_ocean_modifier(omd);
}
if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) {
- result = generate_ocean_geometry(omd, mesh);
+ result = generate_ocean_geometry(omd, mesh, resolution);
BKE_mesh_ensure_normals(result);
}
else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
@@ -558,7 +565,10 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(sub, &ptr, "repeat_x", 0, IFACE_("Repeat X"), ICON_NONE);
uiItemR(sub, &ptr, "repeat_y", 0, IFACE_("Y"), ICON_NONE);
}
- uiItemR(col, &ptr, "resolution", 0, NULL, ICON_NONE);
+
+ sub = uiLayoutColumn(col, true);
+ uiItemR(sub, &ptr, "viewport_resolution", 0, IFACE_("Resolution Viewport"), ICON_NONE);
+ uiItemR(sub, &ptr, "resolution", 0, IFACE_("Render"), ICON_NONE);
uiItemR(col, &ptr, "time", 0, NULL, ICON_NONE);
@@ -598,7 +608,7 @@ static void waves_panel_draw(const bContext *C, Panel *panel)
uiItemS(layout);
col = uiLayoutColumn(layout, false);
- uiItemR(col, &ptr, "wave_alignment", 0, IFACE_("Alignment"), ICON_NONE);
+ uiItemR(col, &ptr, "wave_alignment", UI_ITEM_R_SLIDER, IFACE_("Alignment"), ICON_NONE);
sub = uiLayoutColumn(col, false);
uiLayoutSetActive(sub, RNA_float_get(&ptr, "wave_alignment") > 0.0f);
uiItemR(sub, &ptr, "wave_direction", 0, IFACE_("Direction"), ICON_NONE);
@@ -657,7 +667,7 @@ static void spray_panel_draw(const bContext *C, Panel *panel)
modifier_panel_get_property_pointers(C, panel, NULL, &ptr);
bool use_foam = RNA_boolean_get(&ptr, "use_foam");
- bool use_spray = RNA_boolean_get(&ptr, "use_spray") && use_foam;
+ bool use_spray = RNA_boolean_get(&ptr, "use_spray");
uiLayoutSetPropSep(layout, true);
@@ -682,7 +692,7 @@ static void spectrum_panel_draw(const bContext *C, Panel *panel)
col = uiLayoutColumn(layout, false);
uiItemR(col, &ptr, "spectrum", 0, NULL, ICON_NONE);
if (ELEM(spectrum, MOD_OCEAN_SPECTRUM_TEXEL_MARSEN_ARSLOE, MOD_OCEAN_SPECTRUM_JONSWAP)) {
- uiItemR(col, &ptr, "sharpen_peak_jonswap", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "sharpen_peak_jonswap", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(col, &ptr, "fetch_jonswap", 0, NULL, ICON_NONE);
}
}
diff --git a/source/blender/modifiers/intern/MOD_simulation.cc b/source/blender/modifiers/intern/MOD_simulation.cc
index 85eb66cd826..92ad02ae34a 100644
--- a/source/blender/modifiers/intern/MOD_simulation.cc
+++ b/source/blender/modifiers/intern/MOD_simulation.cc
@@ -29,6 +29,7 @@
#include "BLI_float3.hh"
#include "BLI_listbase.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
@@ -45,13 +46,10 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_pointcloud.h"
+#include "BKE_screen.h"
#include "BKE_simulation.h"
-/* SpaceType struct has a member called 'new' which obviously conflicts with C++
- * so temporarily redefining the new keyword to make it compile. */
-#define new extern_new
-#include "BKE_screen.h"
-#undef new
+#include "BLO_read_write.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -90,15 +88,8 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
static const ParticleSimulationState *find_particle_state(SimulationModifierData *smd)
{
- if (smd->simulation == nullptr) {
- return nullptr;
- }
- LISTBASE_FOREACH (const SimulationState *, state, &smd->simulation->states) {
- if (state->type == SIM_STATE_TYPE_PARTICLES) {
- return (ParticleSimulationState *)state;
- }
- }
- return nullptr;
+ return (const ParticleSimulationState *)BKE_simulation_state_try_find_by_name_and_type(
+ smd->simulation, smd->data_path, SIM_TYPE_NAME_PARTICLE_SIMULATION);
}
static PointCloud *modifyPointCloud(ModifierData *md,
@@ -117,11 +108,13 @@ static PointCloud *modifyPointCloud(ModifierData *md,
}
const float3 *positions = (const float3 *)CustomData_get_layer_named(
- &state->attributes, CD_LOCATION, "Position");
+ &state->attributes, CD_PROP_FLOAT3, "Position");
+ const float *radii = (const float *)CustomData_get_layer_named(
+ &state->attributes, CD_PROP_FLOAT, "Radius");
memcpy(pointcloud->co, positions, sizeof(float3) * state->tot_particles);
for (int i = 0; i < state->tot_particles; i++) {
- pointcloud->radius[i] = 0.05f;
+ pointcloud->radius[i] = radii[i];
}
return pointcloud;
@@ -135,6 +128,9 @@ static void panel_draw(const bContext *C, Panel *panel)
PointerRNA ob_ptr;
modifier_panel_get_property_pointers(C, panel, &ob_ptr, &ptr);
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
uiItemR(layout, &ptr, "simulation", 0, NULL, ICON_NONE);
uiItemR(layout, &ptr, "data_path", 0, NULL, ICON_NONE);
@@ -146,6 +142,37 @@ static void panelRegister(ARegionType *region_type)
modifier_panel_register(region_type, eModifierType_Simulation, panel_draw);
}
+static void blendWrite(BlendWriter *writer, const ModifierData *md)
+{
+ const SimulationModifierData *smd = (const SimulationModifierData *)md;
+ BLO_write_string(writer, smd->data_path);
+}
+
+static void blendRead(BlendDataReader *reader, ModifierData *md)
+{
+ SimulationModifierData *smd = (SimulationModifierData *)md;
+ BLO_read_data_address(reader, &smd->data_path);
+}
+
+static void copyData(const ModifierData *md, ModifierData *target, const int flag)
+{
+ const SimulationModifierData *smd = (const SimulationModifierData *)md;
+ SimulationModifierData *tsmd = (SimulationModifierData *)target;
+
+ BKE_modifier_copydata_generic(md, target, flag);
+ if (smd->data_path != nullptr) {
+ tsmd->data_path = BLI_strdup(smd->data_path);
+ }
+}
+
+static void freeData(ModifierData *md)
+{
+ SimulationModifierData *smd = (SimulationModifierData *)md;
+ if (smd->data_path) {
+ MEM_freeN(smd->data_path);
+ }
+}
+
ModifierTypeInfo modifierType_Simulation = {
/* name */ "Simulation",
/* structName */ "SimulationModifierData",
@@ -153,7 +180,7 @@ ModifierTypeInfo modifierType_Simulation = {
/* type */ eModifierTypeType_None,
/* flags */ (ModifierTypeFlag)0,
- /* copyData */ BKE_modifier_copydata_generic,
+ /* copyData */ copyData,
/* deformVerts */ NULL,
/* deformMatrices */ NULL,
@@ -166,7 +193,7 @@ ModifierTypeInfo modifierType_Simulation = {
/* initData */ NULL,
/* requiredDataMask */ NULL,
- /* freeData */ NULL,
+ /* freeData */ freeData,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
@@ -176,6 +203,6 @@ ModifierTypeInfo modifierType_Simulation = {
/* foreachTexLink */ NULL,
/* freeRuntimeData */ NULL,
/* panelRegister */ panelRegister,
- /* blendWrite */ NULL,
- /* blendRead */ NULL,
+ /* blendWrite */ blendWrite,
+ /* blendRead */ blendRead,
};
diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c
index b03b949c946..deece2b999b 100644
--- a/source/blender/modifiers/intern/MOD_smooth.c
+++ b/source/blender/modifiers/intern/MOD_smooth.c
@@ -147,7 +147,7 @@ static void smoothModifier_do(
MDeformVert *dv = dvert;
for (int i = 0; i < numVerts; i++, dv++) {
float *vco_orig = vertexCos[i];
- if (num_accumulated_vecs[0] > 0) {
+ if (num_accumulated_vecs[i] > 0) {
mul_v3_fl(accumulated_vecs[i], 1.0f / (float)num_accumulated_vecs[i]);
}
float *vco_new = accumulated_vecs[i];
@@ -174,7 +174,7 @@ static void smoothModifier_do(
else { /* no vertex group */
for (int i = 0; i < numVerts; i++) {
float *vco_orig = vertexCos[i];
- if (num_accumulated_vecs[0] > 0) {
+ if (num_accumulated_vecs[i] > 0) {
mul_v3_fl(accumulated_vecs[i], 1.0f / (float)num_accumulated_vecs[i]);
}
float *vco_new = accumulated_vecs[i];
diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c
index a56194354f8..7e5e4ecd9d3 100644
--- a/source/blender/modifiers/intern/MOD_solidify_extrude.c
+++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c
@@ -284,7 +284,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
new_edge_arr = MEM_malloc_arrayN(((numEdges * 2) + numVerts), sizeof(*new_edge_arr), __func__);
edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges");
- edge_order = MEM_malloc_arrayN(numEdges, sizeof(*edge_order), "solid_mod eorder");
+ edge_order = MEM_malloc_arrayN(numEdges, sizeof(*edge_order), "solid_mod order");
/* save doing 2 loops here... */
#if 0
diff --git a/source/blender/modifiers/intern/MOD_solidify_util.h b/source/blender/modifiers/intern/MOD_solidify_util.h
index 6ab4734c451..e9f0709f7ea 100644
--- a/source/blender/modifiers/intern/MOD_solidify_util.h
+++ b/source/blender/modifiers/intern/MOD_solidify_util.h
@@ -18,8 +18,7 @@
* \ingroup modifiers
*/
-#ifndef __MOD_SOLIDIFY_UTIL_H__
-#define __MOD_SOLIDIFY_UTIL_H__
+#pragma once
/* MOD_solidify_extrude.c */
Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md,
@@ -30,5 +29,3 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md,
Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh);
-
-#endif /* __MOD_SOLIDIFY_UTIL_H__ */
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index d5ff31bd3b1..8424b549f85 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -36,6 +36,7 @@
#include "DNA_screen_types.h"
#include "BKE_context.h"
+#include "BKE_mesh.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_subdiv.h"
@@ -77,6 +78,26 @@ static void initData(ModifierData *md)
smd->flags |= (eSubsurfModifierFlag_UseCrease | eSubsurfModifierFlag_ControlEdges);
}
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
+{
+ SubsurfModifierData *smd = (SubsurfModifierData *)md;
+ if (smd->flags & eSubsurfModifierFlag_UseCustomNormals) {
+ r_cddata_masks->lmask |= CD_MASK_NORMAL;
+ r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL;
+ }
+}
+
+static bool dependsOnNormals(ModifierData *md)
+{
+ SubsurfModifierData *smd = (SubsurfModifierData *)md;
+ if (smd->flags & eSubsurfModifierFlag_UseCustomNormals) {
+ return true;
+ }
+ return false;
+}
+
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
#if 0
@@ -242,6 +263,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Happens on bad topology, but also on empty input mesh. */
return result;
}
+ const bool use_clnors = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) &&
+ (mesh->flag & ME_AUTOSMOOTH) &&
+ CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
+ if (use_clnors) {
+ /* If custom normals are present and the option is turned on calculate the split
+ * normals and clear flag so the normals get interpolated to the result mesh. */
+ BKE_mesh_calc_normals_split(mesh);
+ CustomData_clear_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
/* TODO(sergey): Decide whether we ever want to use CCG for subsurf,
* maybe when it is a last modifier in the stack? */
if (true) {
@@ -250,6 +280,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
else {
result = subdiv_as_ccg(smd, ctx, mesh, subdiv);
}
+
+ if (use_clnors) {
+ float(*lnors)[3] = CustomData_get_layer(&result->ldata, CD_NORMAL);
+ BLI_assert(lnors != NULL);
+ BKE_mesh_set_custom_normals(result, lnors);
+ CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
// BKE_subdiv_stats_print(&subdiv->stats);
if (subdiv != runtime_data->subdiv) {
BKE_subdiv_free(subdiv);
@@ -416,6 +454,7 @@ static void advanced_panel_draw(const bContext *C, Panel *panel)
uiItemR(layout, &ptr, "quality", 0, NULL, ICON_NONE);
uiItemR(layout, &ptr, "uv_smooth", 0, NULL, ICON_NONE);
uiItemR(layout, &ptr, "use_creases", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "use_custom_normals", 0, NULL, ICON_NONE);
}
static void panelRegister(ARegionType *region_type)
@@ -453,12 +492,12 @@ ModifierTypeInfo modifierType_Subsurf = {
/* modifyVolume */ NULL,
/* initData */ initData,
- /* requiredDataMask */ NULL,
+ /* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
/* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index fc41afb6613..6a0e82a686b 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -1130,7 +1130,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig,
freeData((ModifierData *)smd_orig);
}
else if (data.success == MOD_SDEF_BIND_RESULT_OVERLAP_ERR) {
- BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains overlapping verts");
+ BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains overlapping vertices");
freeData((ModifierData *)smd_orig);
}
else if (data.success == MOD_SDEF_BIND_RESULT_GENERIC_ERR) {
@@ -1280,7 +1280,7 @@ static void surfacedeformModifier_do(ModifierData *md,
/* Poly count checks */
if (smd->numverts != numverts) {
- BKE_modifier_set_error(md, "Verts changed from %u to %u", smd->numverts, numverts);
+ BKE_modifier_set_error(md, "Vertices changed from %u to %u", smd->numverts, numverts);
return;
}
else if (smd->numpoly != tnumpoly) {
diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c
index 2f0e70d1bee..01b9e972086 100644
--- a/source/blender/modifiers/intern/MOD_ui_common.c
+++ b/source/blender/modifiers/intern/MOD_ui_common.c
@@ -33,7 +33,6 @@
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
#include "ED_object.h"
@@ -50,24 +49,13 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h" /* Self include */
-static Object *get_modifier_object(const bContext *C)
-{
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
- if (sbuts != NULL && (sbuts->pinid != NULL) && GS(sbuts->pinid->name) == ID_OB) {
- return (Object *)sbuts->pinid;
- }
- else {
- return CTX_data_active_object(C);
- }
-}
-
/**
* Poll function so these modifier panels don't show for other object types with modifiers (only
* grease pencil currently).
*/
static bool modifier_ui_poll(const bContext *C, PanelType *UNUSED(pt))
{
- Object *ob = get_modifier_object(C);
+ Object *ob = ED_object_active_context(C);
return (ob != NULL) && (ob->type != OB_GPENCIL);
}
@@ -81,7 +69,7 @@ static bool modifier_ui_poll(const bContext *C, PanelType *UNUSED(pt))
*/
static void modifier_reorder(bContext *C, Panel *panel, int new_index)
{
- Object *ob = get_modifier_object(C);
+ Object *ob = ED_object_active_context(C);
ModifierData *md = BLI_findlink(&ob->modifiers, panel->runtime.list_index);
PointerRNA props_ptr;
@@ -95,14 +83,14 @@ static void modifier_reorder(bContext *C, Panel *panel, int new_index)
static short get_modifier_expand_flag(const bContext *C, Panel *panel)
{
- Object *ob = get_modifier_object(C);
+ Object *ob = ED_object_active_context(C);
ModifierData *md = BLI_findlink(&ob->modifiers, panel->runtime.list_index);
return md->ui_expand_flag;
}
static void set_modifier_expand_flag(const bContext *C, Panel *panel, short expand_flag)
{
- Object *ob = get_modifier_object(C);
+ Object *ob = ED_object_active_context(C);
ModifierData *md = BLI_findlink(&ob->modifiers, panel->runtime.list_index);
md->ui_expand_flag = expand_flag;
}
@@ -135,7 +123,7 @@ void modifier_panel_get_property_pointers(const bContext *C,
PointerRNA *r_ob_ptr,
PointerRNA *r_md_ptr)
{
- Object *ob = get_modifier_object(C);
+ Object *ob = ED_object_active_context(C);
ModifierData *md = BLI_findlink(&ob->modifiers, panel->runtime.list_index);
@@ -228,7 +216,7 @@ static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
ModifierData *md = (ModifierData *)md_v;
PointerRNA ptr;
- Object *ob = get_modifier_object(C);
+ Object *ob = ED_object_active_context(C);
RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr);
uiLayoutSetContextPointer(layout, "modifier", &ptr);
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
@@ -243,12 +231,19 @@ static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
/* Apply as shapekey. */
if (BKE_modifier_is_same_topology(md) && !BKE_modifier_is_non_geometrical(md)) {
- uiItemEnumO(layout,
- "OBJECT_OT_modifier_apply",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply As Shapekey"),
- ICON_SHAPEKEY_DATA,
- "apply_as",
- MODIFIER_APPLY_SHAPE);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply As Shapekey"),
+ ICON_SHAPEKEY_DATA,
+ "OBJECT_OT_modifier_apply_as_shapekey",
+ "keep_modifier",
+ false);
+
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Save As Shapekey"),
+ ICON_SHAPEKEY_DATA,
+ "OBJECT_OT_modifier_apply_as_shapekey",
+ "keep_modifier",
+ true);
}
/* Duplicate. */
@@ -303,7 +298,7 @@ static void modifier_panel_header(const bContext *C, Panel *panel)
uiLayout *layout = panel->layout;
PointerRNA ptr;
- Object *ob = get_modifier_object(C);
+ Object *ob = ED_object_active_context(C);
/* Don't use #modifier_panel_get_property_pointers, we don't want to lock the header. */
ModifierData *md = BLI_findlink(&ob->modifiers, panel->runtime.list_index);
diff --git a/source/blender/modifiers/intern/MOD_ui_common.h b/source/blender/modifiers/intern/MOD_ui_common.h
index 59c0fe1c413..cac8806a2bf 100644
--- a/source/blender/modifiers/intern/MOD_ui_common.h
+++ b/source/blender/modifiers/intern/MOD_ui_common.h
@@ -18,8 +18,7 @@
* \ingroup modifiers
*/
-#ifndef __MOD_UI_COMMON_H__
-#define __MOD_UI_COMMON_H__
+#pragma once
/* so modifier types match their defines */
#include "MOD_modifiertypes.h"
@@ -66,5 +65,3 @@ struct PanelType *modifier_subpanel_register(struct ARegionType *region_type,
#ifdef __cplusplus
}
#endif
-
-#endif /* __MOD_UI_COMMON_H__ */
diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h
index a05e25d204c..05a24b92242 100644
--- a/source/blender/modifiers/intern/MOD_util.h
+++ b/source/blender/modifiers/intern/MOD_util.h
@@ -18,8 +18,7 @@
* \ingroup modifiers
*/
-#ifndef __MOD_UTIL_H__
-#define __MOD_UTIL_H__
+#pragma once
/* so modifier types match their defines */
#include "MOD_modifiertypes.h"
@@ -60,4 +59,3 @@ void MOD_depsgraph_update_object_bone_relation(struct DepsNodeHandle *node,
struct Object *object,
const char *bonename,
const char *description);
-#endif /* __MOD_UTIL_H__ */
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index cbe774e91da..2657e3d894a 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -236,7 +236,7 @@ static void warpModifier_do(WarpModifierData *wmd,
}
if (wmd->curfalloff) {
- BKE_curvemapping_initialize(wmd->curfalloff);
+ BKE_curvemapping_init(wmd->curfalloff);
}
invert_m4_m4(obinv, ob->obmat);
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index 54d3aa46344..4ee1f9f669a 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -83,7 +83,7 @@ void weightvg_do_map(
}
if (cmap && falloff_type == MOD_WVG_MAPPING_CURVE) {
- BKE_curvemapping_initialize(cmap);
+ BKE_curvemapping_init(cmap);
}
/* Map each weight (vertex) to its new value, accordingly to the chosen mode. */
@@ -382,4 +382,4 @@ void weightvg_ui_common(const bContext *C, PointerRNA *ob_ptr, PointerRNA *ptr,
}
}
}
-} \ No newline at end of file
+}
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.h b/source/blender/modifiers/intern/MOD_weightvg_util.h
index 725574dc0a5..c00acd27d38 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.h
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.h
@@ -21,8 +21,7 @@
* \ingroup modifiers
*/
-#ifndef __MOD_WEIGHTVG_UTIL_H__
-#define __MOD_WEIGHTVG_UTIL_H__
+#pragma once
struct CurveMapping;
struct MDeformVert;
@@ -92,4 +91,3 @@ void weightvg_update_vg(struct MDeformVert *dvert,
const bool do_normalize);
void weightvg_ui_common(const bContext *C, PointerRNA *ob_ptr, PointerRNA *ptr, uiLayout *layout);
-#endif /* __MOD_WEIGHTVG_UTIL_H__ */
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index 8039856172a..6bb4f3dc1b5 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -72,7 +72,7 @@ static void initData(ModifierData *md)
wmd->default_weight = 0.0f;
wmd->cmap_curve = BKE_curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
- BKE_curvemapping_initialize(wmd->cmap_curve);
+ BKE_curvemapping_init(wmd->cmap_curve);
wmd->rem_threshold = 0.01f;
wmd->add_threshold = 0.01f;
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 31b5e922dab..33b95d50cc0 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -30,6 +30,7 @@ set(INC
../blenlib
../blentranslation
../depsgraph
+ ../functions
../gpu
../imbuf
../makesdna
@@ -37,6 +38,7 @@ set(INC
../render/extern/include
../../../intern/glew-mx
../../../intern/guardedalloc
+ ../../../intern/sky/include
)
set(INC_SYS
@@ -133,6 +135,8 @@ set(SRC
function/nodes/node_fn_combine_strings.cc
function/nodes/node_fn_float_compare.cc
function/nodes/node_fn_group_instance_id.cc
+ function/nodes/node_fn_object_transforms.cc
+ function/nodes/node_fn_random_float.cc
function/nodes/node_fn_switch.cc
function/node_function_util.cc
@@ -157,7 +161,7 @@ set(SRC
shader/nodes/node_shader_bsdf_velvet.c
shader/nodes/node_shader_bump.c
shader/nodes/node_shader_camera.c
- shader/nodes/node_shader_clamp.c
+ shader/nodes/node_shader_clamp.cc
shader/nodes/node_shader_common.c
shader/nodes/node_shader_curves.c
shader/nodes/node_shader_displacement.c
@@ -174,9 +178,9 @@ set(SRC
shader/nodes/node_shader_layer_weight.c
shader/nodes/node_shader_light_falloff.c
shader/nodes/node_shader_light_path.c
- shader/nodes/node_shader_map_range.c
+ shader/nodes/node_shader_map_range.cc
shader/nodes/node_shader_mapping.c
- shader/nodes/node_shader_math.c
+ shader/nodes/node_shader_math.cc
shader/nodes/node_shader_mixRgb.c
shader/nodes/node_shader_mix_shader.c
shader/nodes/node_shader_normal.c
@@ -191,8 +195,8 @@ set(SRC
shader/nodes/node_shader_rgb.c
shader/nodes/node_shader_script.c
shader/nodes/node_shader_sepcombHSV.c
- shader/nodes/node_shader_sepcombRGB.c
- shader/nodes/node_shader_sepcombXYZ.c
+ shader/nodes/node_shader_sepcombRGB.cc
+ shader/nodes/node_shader_sepcombXYZ.cc
shader/nodes/node_shader_shaderToRgb.c
shader/nodes/node_shader_squeeze.c
shader/nodes/node_shader_subsurface_scattering.c
@@ -213,11 +217,11 @@ set(SRC
shader/nodes/node_shader_tex_white_noise.c
shader/nodes/node_shader_uvAlongStroke.c
shader/nodes/node_shader_uvmap.c
- shader/nodes/node_shader_valToRgb.c
- shader/nodes/node_shader_value.c
+ shader/nodes/node_shader_valToRgb.cc
+ shader/nodes/node_shader_value.cc
shader/nodes/node_shader_vectTransform.c
shader/nodes/node_shader_vector_displacement.c
- shader/nodes/node_shader_vector_math.c
+ shader/nodes/node_shader_vector_math.cc
shader/nodes/node_shader_vector_rotate.c
shader/nodes/node_shader_vertex_color.c
shader/nodes/node_shader_volume_absorption.c
@@ -229,10 +233,12 @@ set(SRC
shader/node_shader_tree.c
shader/node_shader_util.c
+ simulation/nodes/node_sim_age_reached_event.cc
simulation/nodes/node_sim_common.cc
simulation/nodes/node_sim_emit_particles.cc
simulation/nodes/node_sim_execute_condition.cc
simulation/nodes/node_sim_force.cc
+ simulation/nodes/node_sim_kill_particle.cc
simulation/nodes/node_sim_multi_execute.cc
simulation/nodes/node_sim_particle_attribute.cc
simulation/nodes/node_sim_particle_birth_event.cc
@@ -271,20 +277,28 @@ set(SRC
texture/node_texture_tree.c
texture/node_texture_util.c
+ intern/derived_node_tree.cc
intern/node_common.c
intern/node_exec.c
intern/node_socket.cc
+ intern/node_tree_dependencies.cc
+ intern/node_tree_multi_function.cc
+ intern/node_tree_ref.cc
intern/node_util.c
composite/node_composite_util.h
- function/node_function_util.h
+ function/node_function_util.hh
shader/node_shader_util.h
simulation/node_simulation_util.h
texture/node_texture_util.h
NOD_common.h
NOD_composite.h
+ NOD_derived_node_tree.hh
NOD_function.h
+ NOD_node_tree_dependencies.hh
+ NOD_node_tree_multi_function.hh
+ NOD_node_tree_ref.hh
NOD_shader.h
NOD_simulation.h
NOD_socket.h
@@ -296,6 +310,8 @@ set(SRC
)
set(LIB
+ bf_functions
+ bf_intern_sky
)
if(WITH_PYTHON)
diff --git a/source/blender/nodes/NOD_common.h b/source/blender/nodes/NOD_common.h
index dcc4f4d0b76..50ed992dcb6 100644
--- a/source/blender/nodes/NOD_common.h
+++ b/source/blender/nodes/NOD_common.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NOD_COMMON_H__
-#define __NOD_COMMON_H__
+#pragma once
#include "BKE_node.h"
@@ -49,5 +48,3 @@ void node_group_output_update(struct bNodeTree *ntree, struct bNode *node);
#ifdef __cplusplus
}
#endif
-
-#endif /* __NOD_COMMON_H__ */
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index 6b1dd239294..99bcb849ebd 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NOD_COMPOSITE_H__
-#define __NOD_COMPOSITE_H__
+#pragma once
#include "BKE_node.h"
@@ -150,5 +149,3 @@ void register_node_type_cmp_custom_group(bNodeType *ntype);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/blenkernel/BKE_derived_node_tree.hh b/source/blender/nodes/NOD_derived_node_tree.hh
index 2ed96f0c60d..570b6cb704d 100644
--- a/source/blender/blenkernel/BKE_derived_node_tree.hh
+++ b/source/blender/nodes/NOD_derived_node_tree.hh
@@ -14,11 +14,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_DERIVED_NODE_TREE_HH__
-#define __BKE_DERIVED_NODE_TREE_HH__
+#pragma once
/** \file
- * \ingroup bke
+ * \ingroup nodes
*
* DerivedNodeTree provides a flattened view on a bNodeTree, i.e. node groups are inlined. It
* builds on top of NodeTreeRef and supports similar queries efficiently.
@@ -30,9 +29,9 @@
* There is a dot graph exporter for debugging purposes.
*/
-#include "BKE_node_tree_ref.hh"
+#include "NOD_node_tree_ref.hh"
-namespace blender::bke {
+namespace blender::nodes {
class DSocket;
class DInputSocket;
@@ -46,15 +45,15 @@ class DSocket : NonCopyable, NonMovable {
protected:
DNode *node_;
const SocketRef *socket_ref_;
- uint id_;
+ int id_;
friend DerivedNodeTree;
public:
const DNode &node() const;
- uint id() const;
- uint index() const;
+ int id() const;
+ int index() const;
bool is_input() const;
bool is_output() const;
@@ -105,7 +104,7 @@ class DGroupInput : NonCopyable, NonMovable {
const InputSocketRef *socket_ref_;
DParentNode *parent_;
Vector<DInputSocket *> linked_sockets_;
- uint id_;
+ int id_;
friend DerivedNodeTree;
@@ -114,7 +113,7 @@ class DGroupInput : NonCopyable, NonMovable {
bNodeSocket *bsocket() const;
const DParentNode *parent() const;
Span<const DInputSocket *> linked_sockets() const;
- uint id() const;
+ int id() const;
StringRefNull name() const;
};
@@ -126,7 +125,7 @@ class DNode : NonCopyable, NonMovable {
Span<DInputSocket *> inputs_;
Span<DOutputSocket *> outputs_;
- uint id_;
+ int id_;
friend DerivedNodeTree;
@@ -137,10 +136,13 @@ class DNode : NonCopyable, NonMovable {
Span<const DInputSocket *> inputs() const;
Span<const DOutputSocket *> outputs() const;
- const DInputSocket &input(uint index) const;
- const DOutputSocket &output(uint index) const;
+ const DInputSocket &input(int index) const;
+ const DOutputSocket &output(int index) const;
- uint id() const;
+ const DInputSocket &input(int index, StringRef expected_name) const;
+ const DOutputSocket &output(int index, StringRef expected_name) const;
+
+ int id() const;
PointerRNA *rna() const;
StringRefNull idname() const;
@@ -154,14 +156,14 @@ class DParentNode : NonCopyable, NonMovable {
private:
const NodeRef *node_ref_;
DParentNode *parent_;
- uint id_;
+ int id_;
friend DerivedNodeTree;
public:
const DParentNode *parent() const;
const NodeRef &node_ref() const;
- uint id() const;
+ int id() const;
};
using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>;
@@ -169,7 +171,6 @@ using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>;
class DerivedNodeTree : NonCopyable, NonMovable {
private:
LinearAllocator<> allocator_;
- bNodeTree *btree_;
Vector<DNode *> nodes_by_id_;
Vector<DGroupInput *> group_inputs_;
Vector<DParentNode *> parent_nodes_;
@@ -178,7 +179,7 @@ class DerivedNodeTree : NonCopyable, NonMovable {
Vector<DInputSocket *> input_sockets_;
Vector<DOutputSocket *> output_sockets_;
- Map<const bNodeType *, Vector<DNode *>> nodes_by_type_;
+ MultiValueMap<const bNodeType *, DNode *> nodes_by_type_;
public:
DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs);
@@ -237,12 +238,12 @@ inline const DNode &DSocket::node() const
return *node_;
}
-inline uint DSocket::id() const
+inline int DSocket::id() const
{
return id_;
}
-inline uint DSocket::index() const
+inline int DSocket::index() const
{
return socket_ref_->index();
}
@@ -313,12 +314,12 @@ inline const InputSocketRef &DInputSocket::socket_ref() const
inline Span<const DOutputSocket *> DInputSocket::linked_sockets() const
{
- return linked_sockets_.as_span();
+ return linked_sockets_;
}
inline Span<const DGroupInput *> DInputSocket::linked_group_inputs() const
{
- return linked_group_inputs_.as_span();
+ return linked_group_inputs_;
}
inline bool DInputSocket::is_linked() const
@@ -337,7 +338,7 @@ inline const OutputSocketRef &DOutputSocket::socket_ref() const
inline Span<const DInputSocket *> DOutputSocket::linked_sockets() const
{
- return linked_sockets_.as_span();
+ return linked_sockets_;
}
/* --------------------------------------------------------------------
@@ -361,10 +362,10 @@ inline const DParentNode *DGroupInput::parent() const
inline Span<const DInputSocket *> DGroupInput::linked_sockets() const
{
- return linked_sockets_.as_span();
+ return linked_sockets_;
}
-inline uint DGroupInput::id() const
+inline int DGroupInput::id() const
{
return id_;
}
@@ -398,17 +399,33 @@ inline Span<const DOutputSocket *> DNode::outputs() const
return outputs_;
}
-inline const DInputSocket &DNode::input(uint index) const
+inline const DInputSocket &DNode::input(int index) const
{
return *inputs_[index];
}
-inline const DOutputSocket &DNode::output(uint index) const
+inline const DOutputSocket &DNode::output(int index) const
{
return *outputs_[index];
}
-inline uint DNode::id() const
+inline const DInputSocket &DNode::input(int index, StringRef expected_name) const
+{
+ const DInputSocket &socket = *inputs_[index];
+ BLI_assert(socket.name() == expected_name);
+ UNUSED_VARS_NDEBUG(expected_name);
+ return socket;
+}
+
+inline const DOutputSocket &DNode::output(int index, StringRef expected_name) const
+{
+ const DOutputSocket &socket = *outputs_[index];
+ BLI_assert(socket.name() == expected_name);
+ UNUSED_VARS_NDEBUG(expected_name);
+ return socket;
+}
+
+inline int DNode::id() const
{
return id_;
}
@@ -442,7 +459,7 @@ inline const NodeRef &DParentNode::node_ref() const
return *node_ref_;
}
-inline uint DParentNode::id() const
+inline int DParentNode::id() const
{
return id_;
}
@@ -453,46 +470,38 @@ inline uint DParentNode::id() const
inline Span<const DNode *> DerivedNodeTree::nodes() const
{
- return nodes_by_id_.as_span();
+ return nodes_by_id_;
}
inline Span<const DNode *> DerivedNodeTree::nodes_by_type(StringRefNull idname) const
{
- const bNodeType *nodetype = nodeTypeFind(idname.data());
+ const bNodeType *nodetype = nodeTypeFind(idname.c_str());
return this->nodes_by_type(nodetype);
}
inline Span<const DNode *> DerivedNodeTree::nodes_by_type(const bNodeType *nodetype) const
{
- const Vector<DNode *> *nodes = nodes_by_type_.lookup_ptr(nodetype);
- if (nodes == nullptr) {
- return {};
- }
- else {
- return nodes->as_span();
- }
+ return nodes_by_type_.lookup(nodetype);
}
inline Span<const DSocket *> DerivedNodeTree::sockets() const
{
- return sockets_by_id_.as_span();
+ return sockets_by_id_;
}
inline Span<const DInputSocket *> DerivedNodeTree::input_sockets() const
{
- return input_sockets_.as_span();
+ return input_sockets_;
}
inline Span<const DOutputSocket *> DerivedNodeTree::output_sockets() const
{
- return output_sockets_.as_span();
+ return output_sockets_;
}
inline Span<const DGroupInput *> DerivedNodeTree::group_inputs() const
{
- return group_inputs_.as_span();
+ return group_inputs_;
}
-} // namespace blender::bke
-
-#endif /* __BKE_DERIVED_NODE_TREE_HH__ */
+} // namespace blender::nodes
diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h
index 377ae8bfb84..58a968151ac 100644
--- a/source/blender/nodes/NOD_function.h
+++ b/source/blender/nodes/NOD_function.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __NOD_FUNCTION_H__
-#define __NOD_FUNCTION_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -26,9 +25,9 @@ void register_node_type_fn_float_compare(void);
void register_node_type_fn_switch(void);
void register_node_type_fn_group_instance_id(void);
void register_node_type_fn_combine_strings(void);
+void register_node_type_fn_object_transforms(void);
+void register_node_type_fn_random_float(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __NOD_FUNCTION_H__ */
diff --git a/source/blender/nodes/NOD_node_tree_dependencies.hh b/source/blender/nodes/NOD_node_tree_dependencies.hh
new file mode 100644
index 00000000000..13bb2bde2f3
--- /dev/null
+++ b/source/blender/nodes/NOD_node_tree_dependencies.hh
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "BLI_vector_set.hh"
+
+#include "DNA_ID.h"
+#include "DNA_object_types.h"
+
+struct bNodeTree;
+
+namespace blender::nodes {
+
+class NodeTreeDependencies {
+ private:
+ VectorSet<Object *> transform_deps_;
+ VectorSet<Object *> geometry_deps_;
+ VectorSet<ID *> id_deps_;
+
+ public:
+ void add_transform_dependency(Object *object)
+ {
+ if (object == nullptr) {
+ return;
+ }
+ transform_deps_.add(object);
+ id_deps_.add(&object->id);
+ }
+
+ void add_geometry_dependency(Object *object)
+ {
+ if (object == nullptr) {
+ return;
+ }
+ geometry_deps_.add(object);
+ id_deps_.add(&object->id);
+ }
+
+ bool depends_on(ID *id) const
+ {
+ return id_deps_.contains(id);
+ }
+
+ Span<Object *> transform_dependencies()
+ {
+ return transform_deps_;
+ }
+
+ Span<Object *> geometry_dependencies()
+ {
+ return geometry_deps_;
+ }
+
+ Span<ID *> id_dependencies()
+ {
+ return id_deps_;
+ }
+};
+
+NodeTreeDependencies find_node_tree_dependencies(bNodeTree &ntree);
+
+} // namespace blender::nodes
diff --git a/source/blender/nodes/NOD_node_tree_multi_function.hh b/source/blender/nodes/NOD_node_tree_multi_function.hh
new file mode 100644
index 00000000000..cbd7a47f090
--- /dev/null
+++ b/source/blender/nodes/NOD_node_tree_multi_function.hh
@@ -0,0 +1,388 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup nodes
+ *
+ * This file allows you to generate a multi-function network from a user-generated node tree.
+ */
+
+#include "FN_multi_function_builder.hh"
+#include "FN_multi_function_network.hh"
+
+#include "NOD_derived_node_tree.hh"
+
+#include "BLI_resource_collector.hh"
+
+namespace blender::nodes {
+
+/* Maybe this should be moved to BKE_node.h. */
+inline bool is_multi_function_data_socket(const bNodeSocket *bsocket)
+{
+ if (bsocket->typeinfo->get_mf_data_type != nullptr) {
+ BLI_assert(bsocket->typeinfo->expand_in_mf_network != nullptr);
+ return true;
+ }
+ return false;
+}
+
+/**
+ * A MFNetworkTreeMap maps various components of a DerivedNodeTree to components of a
+ * fn::MFNetwork. This is necessary for further processing of a multi-function network that has
+ * been generated from a node tree.
+ */
+class MFNetworkTreeMap {
+ private:
+ /**
+ * Store by id instead of using a hash table to avoid unnecessary hash table lookups.
+ *
+ * Input sockets in a node tree can have multiple corresponding sockets in the generated
+ * MFNetwork. This is because nodes are allowed to expand into multiple multi-function nodes.
+ */
+ const DerivedNodeTree &tree_;
+ fn::MFNetwork &network_;
+ Array<Vector<fn::MFSocket *, 1>> sockets_by_dsocket_id_;
+ Array<fn::MFOutputSocket *> socket_by_group_input_id_;
+
+ public:
+ MFNetworkTreeMap(const DerivedNodeTree &tree, fn::MFNetwork &network)
+ : tree_(tree),
+ network_(network),
+ sockets_by_dsocket_id_(tree.sockets().size()),
+ socket_by_group_input_id_(tree.group_inputs().size(), nullptr)
+ {
+ }
+
+ const DerivedNodeTree &tree() const
+ {
+ return tree_;
+ }
+
+ const fn::MFNetwork &network() const
+ {
+ return network_;
+ }
+
+ fn::MFNetwork &network()
+ {
+ return network_;
+ }
+
+ void add(const DSocket &dsocket, fn::MFSocket &socket)
+ {
+ BLI_assert(dsocket.is_input() == socket.is_input());
+ BLI_assert(dsocket.is_input() || sockets_by_dsocket_id_[dsocket.id()].size() == 0);
+ sockets_by_dsocket_id_[dsocket.id()].append(&socket);
+ }
+
+ void add(const DInputSocket &dsocket, fn::MFInputSocket &socket)
+ {
+ sockets_by_dsocket_id_[dsocket.id()].append(&socket);
+ }
+
+ void add(const DOutputSocket &dsocket, fn::MFOutputSocket &socket)
+ {
+ /* There can be at most one matching output socket. */
+ BLI_assert(sockets_by_dsocket_id_[dsocket.id()].size() == 0);
+ sockets_by_dsocket_id_[dsocket.id()].append(&socket);
+ }
+
+ void add(Span<const DInputSocket *> dsockets, Span<fn::MFInputSocket *> sockets)
+ {
+ assert_same_size(dsockets, sockets);
+ for (int i : dsockets.index_range()) {
+ this->add(*dsockets[i], *sockets[i]);
+ }
+ }
+
+ void add(Span<const DOutputSocket *> dsockets, Span<fn::MFOutputSocket *> sockets)
+ {
+ assert_same_size(dsockets, sockets);
+ for (int i : dsockets.index_range()) {
+ this->add(*dsockets[i], *sockets[i]);
+ }
+ }
+
+ void add(const DGroupInput &group_input, fn::MFOutputSocket &socket)
+ {
+ BLI_assert(socket_by_group_input_id_[group_input.id()] == nullptr);
+ socket_by_group_input_id_[group_input.id()] = &socket;
+ }
+
+ void add_try_match(const DNode &dnode, fn::MFNode &node)
+ {
+ this->add_try_match(dnode.inputs(), node.inputs());
+ this->add_try_match(dnode.outputs(), node.outputs());
+ }
+
+ void add_try_match(Span<const DSocket *> dsockets, Span<fn::MFSocket *> sockets)
+ {
+ int used_sockets = 0;
+ for (const DSocket *dsocket : dsockets) {
+ if (!dsocket->is_available()) {
+ continue;
+ }
+ if (!is_multi_function_data_socket(dsocket->bsocket())) {
+ continue;
+ }
+ fn::MFSocket *socket = sockets[used_sockets];
+ this->add(*dsocket, *socket);
+ used_sockets++;
+ }
+ }
+
+ fn::MFOutputSocket &lookup(const DGroupInput &group_input)
+ {
+ fn::MFOutputSocket *socket = socket_by_group_input_id_[group_input.id()];
+ BLI_assert(socket != nullptr);
+ return *socket;
+ }
+
+ fn::MFOutputSocket &lookup(const DOutputSocket &dsocket)
+ {
+ auto &sockets = sockets_by_dsocket_id_[dsocket.id()];
+ BLI_assert(sockets.size() == 1);
+ return sockets[0]->as_output();
+ }
+
+ Span<fn::MFInputSocket *> lookup(const DInputSocket &dsocket)
+ {
+ return sockets_by_dsocket_id_[dsocket.id()].as_span().cast<fn::MFInputSocket *>();
+ }
+
+ fn::MFInputSocket &lookup_dummy(const DInputSocket &dsocket)
+ {
+ Span<fn::MFInputSocket *> sockets = this->lookup(dsocket);
+ BLI_assert(sockets.size() == 1);
+ fn::MFInputSocket &socket = *sockets[0];
+ BLI_assert(socket.node().is_dummy());
+ return socket;
+ }
+
+ fn::MFOutputSocket &lookup_dummy(const DOutputSocket &dsocket)
+ {
+ fn::MFOutputSocket &socket = this->lookup(dsocket);
+ BLI_assert(socket.node().is_dummy());
+ return socket;
+ }
+
+ bool is_mapped(const DSocket &dsocket) const
+ {
+ return sockets_by_dsocket_id_[dsocket.id()].size() >= 1;
+ }
+};
+
+/**
+ * This data is necessary throughout the generation of a MFNetwork from a node tree.
+ */
+struct CommonMFNetworkBuilderData {
+ ResourceCollector &resources;
+ fn::MFNetwork &network;
+ MFNetworkTreeMap &network_map;
+ const DerivedNodeTree &tree;
+};
+
+class MFNetworkBuilderBase {
+ protected:
+ CommonMFNetworkBuilderData &common_;
+
+ public:
+ MFNetworkBuilderBase(CommonMFNetworkBuilderData &common) : common_(common)
+ {
+ }
+
+ /**
+ * Returns the network that is currently being built.
+ */
+ fn::MFNetwork &network()
+ {
+ return common_.network;
+ }
+
+ /**
+ * Returns the map between the node tree and the multi-function network that is being built.
+ */
+ MFNetworkTreeMap &network_map()
+ {
+ return common_.network_map;
+ }
+
+ /**
+ * Returns a resource collector that will only be destructed after the multi-function network is
+ * destructed.
+ */
+ ResourceCollector &resources()
+ {
+ return common_.resources;
+ }
+
+ /**
+ * Constructs a new function that will live at least as long as the MFNetwork.
+ */
+ template<typename T, typename... Args> T &construct_fn(Args &&... args)
+ {
+ BLI_STATIC_ASSERT((std::is_base_of_v<fn::MultiFunction, T>), "");
+ void *buffer = common_.resources.linear_allocator().allocate(sizeof(T), alignof(T));
+ T *fn = new (buffer) T(std::forward<Args>(args)...);
+ common_.resources.add(destruct_ptr<T>(fn), fn->name().c_str());
+ return *fn;
+ }
+};
+
+/**
+ * This class is used by socket implementations to define how an unlinked input socket is handled
+ * in a multi-function network.
+ */
+class SocketMFNetworkBuilder : public MFNetworkBuilderBase {
+ private:
+ bNodeSocket *bsocket_;
+ fn::MFOutputSocket *built_socket_ = nullptr;
+
+ public:
+ SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DSocket &dsocket)
+ : MFNetworkBuilderBase(common), bsocket_(dsocket.bsocket())
+ {
+ }
+
+ SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DGroupInput &group_input)
+ : MFNetworkBuilderBase(common), bsocket_(group_input.bsocket())
+ {
+ }
+
+ /**
+ * Returns the socket that is currently being built.
+ */
+ bNodeSocket &bsocket()
+ {
+ return *bsocket_;
+ }
+
+ /**
+ * Utility method that returns bsocket->default_value for the current socket.
+ */
+ template<typename T> T *socket_default_value()
+ {
+ return (T *)bsocket_->default_value;
+ }
+
+ /**
+ * Builds a function node for that socket that outputs the given constant value.
+ */
+ template<typename T> void set_constant_value(T value)
+ {
+ this->construct_generator_fn<fn::CustomMF_Constant<T>>(std::move(value));
+ }
+
+ template<typename T, typename... Args> void construct_generator_fn(Args &&... args)
+ {
+ const fn::MultiFunction &fn = this->construct_fn<T>(std::forward<Args>(args)...);
+ this->set_generator_fn(fn);
+ }
+
+ /**
+ * Uses the first output of the given multi-function as value of the socket.
+ */
+ void set_generator_fn(const fn::MultiFunction &fn)
+ {
+ fn::MFFunctionNode &node = common_.network.add_function(fn);
+ this->set_socket(node.output(0));
+ }
+
+ /**
+ * Define a multi-function socket that outputs the value of the bsocket.
+ */
+ void set_socket(fn::MFOutputSocket &socket)
+ {
+ built_socket_ = &socket;
+ }
+
+ fn::MFOutputSocket *built_socket()
+ {
+ return built_socket_;
+ }
+};
+
+/**
+ * This class is used by node implementations to define how a user-level node expands into
+ * multi-function nodes internally.
+ */
+class NodeMFNetworkBuilder : public MFNetworkBuilderBase {
+ private:
+ const DNode &dnode_;
+
+ public:
+ NodeMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DNode &dnode)
+ : MFNetworkBuilderBase(common), dnode_(dnode)
+ {
+ }
+
+ /**
+ * Tells the builder to build a function that corresponds to the node that is being built. It
+ * will try to match up sockets.
+ */
+ template<typename T, typename... Args> T &construct_and_set_matching_fn(Args &&... args)
+ {
+ T &function = this->construct_fn<T>(std::forward<Args>(args)...);
+ this->set_matching_fn(function);
+ return function;
+ }
+
+ const fn::MultiFunction &get_not_implemented_fn()
+ {
+ return this->get_default_fn("Not Implemented (" + dnode_.name() + ")");
+ }
+
+ const fn::MultiFunction &get_default_fn(StringRef name);
+
+ const void set_not_implemented()
+ {
+ this->set_matching_fn(this->get_not_implemented_fn());
+ }
+
+ /**
+ * Tells the builder that the given function corresponds to the node that is being built. It will
+ * try to match up sockets. For that it skips unavailable and non-data sockets.
+ */
+ void set_matching_fn(const fn::MultiFunction &function)
+ {
+ fn::MFFunctionNode &node = common_.network.add_function(function);
+ common_.network_map.add_try_match(dnode_, node);
+ }
+
+ /**
+ * Returns the node that is currently being built.
+ */
+ bNode &bnode()
+ {
+ return *dnode_.node_ref().bnode();
+ }
+
+ /**
+ * Returns the node that is currently being built.
+ */
+ const DNode &dnode() const
+ {
+ return dnode_;
+ }
+};
+
+MFNetworkTreeMap insert_node_tree_into_mf_network(fn::MFNetwork &network,
+ const DerivedNodeTree &tree,
+ ResourceCollector &resources);
+
+} // namespace blender::nodes
diff --git a/source/blender/blenkernel/BKE_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh
index e25849cb569..6d1c239d2cb 100644
--- a/source/blender/blenkernel/BKE_node_tree_ref.hh
+++ b/source/blender/nodes/NOD_node_tree_ref.hh
@@ -14,11 +14,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BKE_NODE_TREE_REF_HH__
-#define __BKE_NODE_TREE_REF_HH__
+#pragma once
/** \file
- * \ingroup bke
+ * \ingroup nodes
*
* NodeTreeRef makes querying information about a bNodeTree more efficient. It is an immutable data
* structure. It should not be used after anymore, after the underlying node tree changed.
@@ -47,6 +46,7 @@
#include "BLI_array.hh"
#include "BLI_linear_allocator.hh"
#include "BLI_map.hh"
+#include "BLI_multi_value_map.hh"
#include "BLI_string_ref.hh"
#include "BLI_timeit.hh"
#include "BLI_utility_mixins.hh"
@@ -58,7 +58,7 @@
#include "RNA_access.h"
-namespace blender::bke {
+namespace blender::nodes {
class SocketRef;
class InputSocketRef;
@@ -71,8 +71,8 @@ class SocketRef : NonCopyable, NonMovable {
NodeRef *node_;
bNodeSocket *bsocket_;
bool is_input_;
- uint id_;
- uint index_;
+ int id_;
+ int index_;
PointerRNA rna_;
Vector<SocketRef *> linked_sockets_;
Vector<SocketRef *> directly_linked_sockets_;
@@ -87,8 +87,8 @@ class SocketRef : NonCopyable, NonMovable {
const NodeRef &node() const;
const NodeTreeRef &tree() const;
- uint id() const;
- uint index() const;
+ int id() const;
+ int index() const;
bool is_input() const;
bool is_output() const;
@@ -124,7 +124,7 @@ class NodeRef : NonCopyable, NonMovable {
NodeTreeRef *tree_;
bNode *bnode_;
PointerRNA rna_;
- uint id_;
+ int id_;
Vector<InputSocketRef *> inputs_;
Vector<OutputSocketRef *> outputs_;
@@ -136,8 +136,8 @@ class NodeRef : NonCopyable, NonMovable {
Span<const InputSocketRef *> inputs() const;
Span<const OutputSocketRef *> outputs() const;
- const InputSocketRef &input(uint index) const;
- const OutputSocketRef &output(uint index) const;
+ const InputSocketRef &input(int index) const;
+ const OutputSocketRef &output(int index) const;
bNode *bnode() const;
bNodeTree *btree() const;
@@ -146,7 +146,7 @@ class NodeRef : NonCopyable, NonMovable {
StringRefNull idname() const;
StringRefNull name() const;
- uint id() const;
+ int id() const;
bool is_reroute_node() const;
bool is_group_node() const;
@@ -162,7 +162,7 @@ class NodeTreeRef : NonCopyable, NonMovable {
Vector<SocketRef *> sockets_by_id_;
Vector<InputSocketRef *> input_sockets_;
Vector<OutputSocketRef *> output_sockets_;
- Map<const bNodeType *, Vector<NodeRef *>> nodes_by_type_;
+ MultiValueMap<const bNodeType *, NodeRef *> nodes_by_type_;
public:
NodeTreeRef(bNodeTree *btree);
@@ -197,12 +197,12 @@ class NodeTreeRef : NonCopyable, NonMovable {
inline Span<const SocketRef *> SocketRef::linked_sockets() const
{
- return linked_sockets_.as_span();
+ return linked_sockets_;
}
inline Span<const SocketRef *> SocketRef::directly_linked_sockets() const
{
- return directly_linked_sockets_.as_span();
+ return directly_linked_sockets_;
}
inline bool SocketRef::is_linked() const
@@ -220,12 +220,12 @@ inline const NodeTreeRef &SocketRef::tree() const
return node_->tree();
}
-inline uint SocketRef::id() const
+inline int SocketRef::id() const
{
return id_;
}
-inline uint SocketRef::index() const
+inline int SocketRef::index() const
{
return index_;
}
@@ -326,20 +326,20 @@ inline const NodeTreeRef &NodeRef::tree() const
inline Span<const InputSocketRef *> NodeRef::inputs() const
{
- return inputs_.as_span();
+ return inputs_;
}
inline Span<const OutputSocketRef *> NodeRef::outputs() const
{
- return outputs_.as_span();
+ return outputs_;
}
-inline const InputSocketRef &NodeRef::input(uint index) const
+inline const InputSocketRef &NodeRef::input(int index) const
{
return *inputs_[index];
}
-inline const OutputSocketRef &NodeRef::output(uint index) const
+inline const OutputSocketRef &NodeRef::output(int index) const
{
return *outputs_[index];
}
@@ -369,7 +369,7 @@ inline StringRefNull NodeRef::name() const
return bnode_->name;
}
-inline uint NodeRef::id() const
+inline int NodeRef::id() const
{
return id_;
}
@@ -400,39 +400,33 @@ inline bool NodeRef::is_group_output_node() const
inline Span<const NodeRef *> NodeTreeRef::nodes() const
{
- return nodes_by_id_.as_span();
+ return nodes_by_id_;
}
inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(StringRefNull idname) const
{
- const bNodeType *nodetype = nodeTypeFind(idname.data());
+ const bNodeType *nodetype = nodeTypeFind(idname.c_str());
return this->nodes_by_type(nodetype);
}
inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(const bNodeType *nodetype) const
{
- const Vector<NodeRef *> *nodes = nodes_by_type_.lookup_ptr(nodetype);
- if (nodes == nullptr) {
- return {};
- }
- else {
- return nodes->as_span();
- }
+ return nodes_by_type_.lookup(nodetype);
}
inline Span<const SocketRef *> NodeTreeRef::sockets() const
{
- return sockets_by_id_.as_span();
+ return sockets_by_id_;
}
inline Span<const InputSocketRef *> NodeTreeRef::input_sockets() const
{
- return input_sockets_.as_span();
+ return input_sockets_;
}
inline Span<const OutputSocketRef *> NodeTreeRef::output_sockets() const
{
- return output_sockets_.as_span();
+ return output_sockets_;
}
inline bNodeTree *NodeTreeRef::btree() const
@@ -440,6 +434,4 @@ inline bNodeTree *NodeTreeRef::btree() const
return btree_;
}
-} // namespace blender::bke
-
-#endif /* __BKE_NODE_TREE_REF_HH__ */
+} // namespace blender::nodes
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index bf548aea5f4..2911e0fbea6 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NOD_SHADER_H__
-#define __NOD_SHADER_H__
+#pragma once
#include "BKE_node.h"
@@ -146,5 +145,3 @@ void register_node_type_sh_custom_group(bNodeType *ntype);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/nodes/NOD_simulation.h b/source/blender/nodes/NOD_simulation.h
index 2947d38fe83..266ded997c6 100644
--- a/source/blender/nodes/NOD_simulation.h
+++ b/source/blender/nodes/NOD_simulation.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __NOD_SIMULATION_H__
-#define __NOD_SIMULATION_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -39,9 +38,9 @@ void register_node_type_sim_particle_mesh_collision_event(void);
void register_node_type_sim_emit_particles(void);
void register_node_type_sim_time(void);
void register_node_type_sim_particle_attribute(void);
+void register_node_type_sim_age_reached_event(void);
+void register_node_type_sim_kill_particle(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __NOD_SIMULATION_H__ */
diff --git a/source/blender/nodes/NOD_socket.h b/source/blender/nodes/NOD_socket.h
index ce6f0da4aee..3344a25bdea 100644
--- a/source/blender/nodes/NOD_socket.h
+++ b/source/blender/nodes/NOD_socket.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NOD_SOCKET_H__
-#define __NOD_SOCKET_H__
+#pragma once
#include "DNA_listBase.h"
@@ -48,10 +47,13 @@ void node_verify_socket_templates(struct bNodeTree *ntree, struct bNode *node);
void node_socket_init_default_value(struct bNodeSocket *sock);
void node_socket_copy_default_value(struct bNodeSocket *to, const struct bNodeSocket *from);
+void node_socket_skip_reroutes(struct ListBase *links,
+ struct bNode *node,
+ struct bNodeSocket *socket,
+ struct bNode **r_node,
+ struct bNodeSocket **r_socket);
void register_standard_node_socket_types(void);
#ifdef __cplusplus
}
#endif
-
-#endif /* __NOD_SOCKET_H__ */
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 91aa11566d3..7922a73902c 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -270,12 +270,16 @@ DefNode(SimulationNode, SIM_NODE_PARTICLE_MESH_COLLISION_EVENT, 0, "PARTIC
DefNode(SimulationNode, SIM_NODE_EMIT_PARTICLES, 0, "EMIT_PARTICLES", EmitParticles, "Emit Particles", "")
DefNode(SimulationNode, SIM_NODE_TIME, def_sim_time, "TIME", Time, "Time", "")
DefNode(SimulationNode, SIM_NODE_PARTICLE_ATTRIBUTE, def_sim_particle_attribute, "PARTICLE_ATTRIBUTE", ParticleAttribute, "Particle Attribute", "")
+DefNode(SimulationNode, SIM_NODE_AGE_REACHED_EVENT, 0, "AGE_REACHED_EVENT", AgeReachedEvent, "Age Reached Event", "")
+DefNode(SimulationNode, SIM_NODE_KILL_PARTICLE, 0, "KILL_PARTICLE", KillParticle, "Kill Particle", "")
DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "")
DefNode(FunctionNode, FN_NODE_FLOAT_COMPARE, def_float_compare, "FLOAT_COMPARE", FloatCompare, "Float Compare", "")
DefNode(FunctionNode, FN_NODE_SWITCH, def_fn_switch, "SWITCH", Switch, "Switch", "")
DefNode(FunctionNode, FN_NODE_GROUP_INSTANCE_ID, 0, "GROUP_INSTANCE_ID", GroupInstanceID, "Group Instance ID", "")
DefNode(FunctionNode, FN_NODE_COMBINE_STRINGS, 0, "COMBINE_STRINGS", CombineStrings, "Combine Strings", "")
+DefNode(FunctionNode, FN_NODE_OBJECT_TRANSFORMS, 0, "OBJECT_TRANSFORMS", ObjectTransforms, "Object Transforms", "")
+DefNode(FunctionNode, FN_NODE_RANDOM_FLOAT, 0, "RANDOM_FLOAT", RandomFloat, "Random Float", "")
/* undefine macros */
diff --git a/source/blender/nodes/NOD_texture.h b/source/blender/nodes/NOD_texture.h
index 07a05f01bc5..af59fefd925 100644
--- a/source/blender/nodes/NOD_texture.h
+++ b/source/blender/nodes/NOD_texture.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NOD_TEXTURE_H__
-#define __NOD_TEXTURE_H__
+#pragma once
#include "BKE_node.h"
@@ -78,5 +77,3 @@ void register_node_type_tex_proc_distnoise(void);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h
index 0edc864e98f..8810b760e8c 100644
--- a/source/blender/nodes/composite/node_composite_util.h
+++ b/source/blender/nodes/composite/node_composite_util.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NODE_COMPOSITE_UTIL_H__
-#define __NODE_COMPOSITE_UTIL_H__
+#pragma once
#include "DNA_ID.h"
#include "DNA_movieclip_types.h"
@@ -63,5 +62,3 @@ void cmp_node_type_base(
#ifdef __cplusplus
}
#endif
-
-#endif /* __NODE_COMPOSITE_UTIL_H__ */
diff --git a/source/blender/nodes/function/node_function_util.cc b/source/blender/nodes/function/node_function_util.cc
index 0927ba335fe..342c330a8fa 100644
--- a/source/blender/nodes/function/node_function_util.cc
+++ b/source/blender/nodes/function/node_function_util.cc
@@ -14,7 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "node_function_util.h"
+#include "node_function_util.hh"
#include "node_util.h"
bool fn_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
diff --git a/source/blender/nodes/function/node_function_util.h b/source/blender/nodes/function/node_function_util.hh
index 85e252f9bdd..d57d1383019 100644
--- a/source/blender/nodes/function/node_function_util.h
+++ b/source/blender/nodes/function/node_function_util.hh
@@ -14,11 +14,11 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __NODE_FUNCTION_UTIL_H__
-#define __NODE_FUNCTION_UTIL_H__
+#pragma once
#include <string.h>
+#include "BLI_float3.hh"
#include "BLI_utildefines.h"
#include "MEM_guardedalloc.h"
@@ -30,11 +30,12 @@
#include "BLT_translation.h"
#include "NOD_function.h"
+#include "NOD_node_tree_multi_function.hh"
#include "node_util.h"
+#include "FN_multi_function_builder.hh"
+
void fn_node_type_base(
struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
bool fn_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
-
-#endif /* __NODE_FUNCTION_UTIL_H__ */
diff --git a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc
index 615ad4c6733..231771abbfa 100644
--- a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc
+++ b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc
@@ -19,7 +19,7 @@
#include "RNA_enum_types.h"
-#include "node_function_util.h"
+#include "node_function_util.hh"
static bNodeSocketTemplate fn_node_boolean_math_in[] = {
{SOCK_BOOLEAN, N_("Boolean")},
@@ -50,6 +50,33 @@ static void node_boolean_math_label(bNodeTree *UNUSED(ntree), bNode *node, char
BLI_strncpy(label, IFACE_(name), maxlen);
}
+static const blender::fn::MultiFunction &get_multi_function(bNode &bnode)
+{
+ static blender::fn::CustomMF_SI_SI_SO<bool, bool, bool> and_fn{
+ "And", [](bool a, bool b) { return a && b; }};
+ static blender::fn::CustomMF_SI_SI_SO<bool, bool, bool> or_fn{
+ "Or", [](bool a, bool b) { return a || b; }};
+ static blender::fn::CustomMF_SI_SO<bool, bool> not_fn{"Not", [](bool a) { return !a; }};
+
+ switch (bnode.custom1) {
+ case NODE_BOOLEAN_MATH_AND:
+ return and_fn;
+ case NODE_BOOLEAN_MATH_OR:
+ return or_fn;
+ case NODE_BOOLEAN_MATH_NOT:
+ return not_fn;
+ }
+
+ BLI_assert(false);
+ return blender::fn::dummy_multi_function;
+}
+
+static void node_boolean_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ const blender::fn::MultiFunction &fn = get_multi_function(builder.bnode());
+ builder.set_matching_fn(fn);
+}
+
void register_node_type_fn_boolean_math()
{
static bNodeType ntype;
@@ -58,5 +85,6 @@ void register_node_type_fn_boolean_math()
node_type_socket_templates(&ntype, fn_node_boolean_math_in, fn_node_boolean_math_out);
node_type_label(&ntype, node_boolean_math_label);
node_type_update(&ntype, node_boolean_math_update);
+ ntype.expand_in_mf_network = node_boolean_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/function/nodes/node_fn_combine_strings.cc b/source/blender/nodes/function/nodes/node_fn_combine_strings.cc
index 1b6091451d9..a545c4f0749 100644
--- a/source/blender/nodes/function/nodes/node_fn_combine_strings.cc
+++ b/source/blender/nodes/function/nodes/node_fn_combine_strings.cc
@@ -1,4 +1,20 @@
-#include "node_function_util.h"
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_function_util.hh"
static bNodeSocketTemplate fn_node_combine_strings_in[] = {
{SOCK_STRING, N_("A")},
@@ -11,11 +27,20 @@ static bNodeSocketTemplate fn_node_combine_strings_out[] = {
{-1, ""},
};
+static void fn_node_combine_strings_expand_in_mf_network(
+ blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ static blender::fn::CustomMF_SI_SI_SO<std::string, std::string, std::string> combine_fn{
+ "Combine Strings", [](const std::string &a, const std::string &b) { return a + b; }};
+ builder.set_matching_fn(combine_fn);
+}
+
void register_node_type_fn_combine_strings()
{
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_COMBINE_STRINGS, "Combine Strings", 0, 0);
node_type_socket_templates(&ntype, fn_node_combine_strings_in, fn_node_combine_strings_out);
+ ntype.expand_in_mf_network = fn_node_combine_strings_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/function/nodes/node_fn_float_compare.cc b/source/blender/nodes/function/nodes/node_fn_float_compare.cc
index 9788402850b..f8bd9a30940 100644
--- a/source/blender/nodes/function/nodes/node_fn_float_compare.cc
+++ b/source/blender/nodes/function/nodes/node_fn_float_compare.cc
@@ -14,12 +14,14 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <cmath>
+
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "RNA_enum_types.h"
-#include "node_function_util.h"
+#include "node_function_util.hh"
static bNodeSocketTemplate fn_node_float_compare_in[] = {
{SOCK_FLOAT, N_("A"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
@@ -54,6 +56,46 @@ static void node_float_compare_label(bNodeTree *UNUSED(ntree),
BLI_strncpy(label, IFACE_(name), maxlen);
}
+static const blender::fn::MultiFunction &get_multi_function(bNode &node)
+{
+ static blender::fn::CustomMF_SI_SI_SO<float, float, bool> less_than_fn{
+ "Less Than", [](float a, float b) { return a < b; }};
+ static blender::fn::CustomMF_SI_SI_SO<float, float, bool> less_equal_fn{
+ "Less Equal", [](float a, float b) { return a <= b; }};
+ static blender::fn::CustomMF_SI_SI_SO<float, float, bool> greater_than_fn{
+ "Greater Than", [](float a, float b) { return a > b; }};
+ static blender::fn::CustomMF_SI_SI_SO<float, float, bool> greater_equal_fn{
+ "Greater Equal", [](float a, float b) { return a >= b; }};
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> equal_fn{
+ "Equal", [](float a, float b, float epsilon) { return std::abs(a - b) <= epsilon; }};
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> not_equal_fn{
+ "Not Equal", [](float a, float b, float epsilon) { return std::abs(a - b) > epsilon; }};
+
+ switch (node.custom1) {
+ case NODE_FLOAT_COMPARE_LESS_THAN:
+ return less_than_fn;
+ case NODE_FLOAT_COMPARE_LESS_EQUAL:
+ return less_equal_fn;
+ case NODE_FLOAT_COMPARE_GREATER_THAN:
+ return greater_than_fn;
+ case NODE_FLOAT_COMPARE_GREATER_EQUAL:
+ return greater_equal_fn;
+ case NODE_FLOAT_COMPARE_EQUAL:
+ return equal_fn;
+ case NODE_FLOAT_COMPARE_NOT_EQUAL:
+ return not_equal_fn;
+ }
+
+ BLI_assert(false);
+ return blender::fn::dummy_multi_function;
+}
+
+static void node_float_compare_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ const blender::fn::MultiFunction &fn = get_multi_function(builder.bnode());
+ builder.set_matching_fn(fn);
+}
+
void register_node_type_fn_float_compare()
{
static bNodeType ntype;
@@ -62,5 +104,6 @@ void register_node_type_fn_float_compare()
node_type_socket_templates(&ntype, fn_node_float_compare_in, fn_node_float_compare_out);
node_type_label(&ntype, node_float_compare_label);
node_type_update(&ntype, node_float_compare_update);
+ ntype.expand_in_mf_network = node_float_compare_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/function/nodes/node_fn_group_instance_id.cc b/source/blender/nodes/function/nodes/node_fn_group_instance_id.cc
index 2ac86ee2407..1e22cde721d 100644
--- a/source/blender/nodes/function/nodes/node_fn_group_instance_id.cc
+++ b/source/blender/nodes/function/nodes/node_fn_group_instance_id.cc
@@ -1,15 +1,45 @@
-#include "node_function_util.h"
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_function_util.hh"
static bNodeSocketTemplate fn_node_group_instance_id_out[] = {
{SOCK_STRING, N_("Identifier")},
{-1, ""},
};
+static void fn_node_group_instance_id_expand_in_mf_network(
+ blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ const blender::nodes::DNode &node = builder.dnode();
+ std::string id = "/";
+ for (const blender::nodes::DParentNode *parent = node.parent(); parent;
+ parent = parent->parent()) {
+ id = "/" + parent->node_ref().name() + id;
+ }
+ builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<std::string>>(
+ std::move(id));
+}
+
void register_node_type_fn_group_instance_id()
{
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_GROUP_INSTANCE_ID, "Group Instance ID", 0, 0);
node_type_socket_templates(&ntype, nullptr, fn_node_group_instance_id_out);
+ ntype.expand_in_mf_network = fn_node_group_instance_id_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/function/nodes/node_fn_object_transforms.cc b/source/blender/nodes/function/nodes/node_fn_object_transforms.cc
new file mode 100644
index 00000000000..26b25406590
--- /dev/null
+++ b/source/blender/nodes/function/nodes/node_fn_object_transforms.cc
@@ -0,0 +1,88 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_function_util.hh"
+
+#include "BKE_persistent_data_handle.hh"
+
+static bNodeSocketTemplate fn_node_object_transforms_in[] = {
+ {SOCK_OBJECT, N_("Object")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate fn_node_object_transforms_out[] = {
+ {SOCK_VECTOR, N_("Location")},
+ {-1, ""},
+};
+
+class ObjectTransformsFunction : public blender::fn::MultiFunction {
+ public:
+ ObjectTransformsFunction()
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Object Transforms");
+ signature.depends_on_context();
+ signature.single_input<blender::bke::PersistentObjectHandle>("Object");
+ signature.single_output<blender::float3>("Location");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext context) const override
+ {
+ blender::fn::VSpan handles =
+ params.readonly_single_input<blender::bke::PersistentObjectHandle>(0, "Object");
+ blender::MutableSpan locations = params.uninitialized_single_output<blender::float3>(
+ 1, "Location");
+
+ const blender::bke::PersistentDataHandleMap *handle_map =
+ context.get_global_context<blender::bke::PersistentDataHandleMap>(
+ "PersistentDataHandleMap");
+ if (handle_map == nullptr) {
+ locations.fill_indices(mask, {0, 0, 0});
+ return;
+ }
+
+ for (int64_t i : mask) {
+ blender::bke::PersistentObjectHandle handle = handles[i];
+ const Object *object = handle_map->lookup(handle);
+ blender::float3 location;
+ if (object == nullptr) {
+ location = {0, 0, 0};
+ }
+ else {
+ location = object->loc;
+ }
+ locations[i] = location;
+ }
+ }
+};
+
+static void fn_node_object_transforms_expand_in_mf_network(
+ blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ static ObjectTransformsFunction fn;
+ builder.set_matching_fn(fn);
+}
+
+void register_node_type_fn_object_transforms()
+{
+ static bNodeType ntype;
+
+ fn_node_type_base(&ntype, FN_NODE_OBJECT_TRANSFORMS, "Object Transforms", 0, 0);
+ node_type_socket_templates(&ntype, fn_node_object_transforms_in, fn_node_object_transforms_out);
+ ntype.expand_in_mf_network = fn_node_object_transforms_expand_in_mf_network;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/function/nodes/node_fn_random_float.cc b/source/blender/nodes/function/nodes/node_fn_random_float.cc
new file mode 100644
index 00000000000..2ee0830637a
--- /dev/null
+++ b/source/blender/nodes/function/nodes/node_fn_random_float.cc
@@ -0,0 +1,89 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_function_util.hh"
+
+#include "BLI_hash.h"
+
+static bNodeSocketTemplate fn_node_random_float_in[] = {
+ {SOCK_FLOAT, N_("Min"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {SOCK_FLOAT, N_("Max"), 1.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {SOCK_INT, N_("Seed")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate fn_node_random_float_out[] = {
+ {SOCK_FLOAT, N_("Value")},
+ {-1, ""},
+};
+
+class RandomFloatFunction : public blender::fn::MultiFunction {
+ private:
+ uint32_t function_seed_;
+
+ public:
+ RandomFloatFunction(uint32_t function_seed) : function_seed_(function_seed)
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Random float");
+ signature.single_input<float>("Min");
+ signature.single_input<float>("Max");
+ signature.single_input<int>("Seed");
+ signature.single_output<float>("Value");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ blender::fn::VSpan<float> min_values = params.readonly_single_input<float>(0, "Min");
+ blender::fn::VSpan<float> max_values = params.readonly_single_input<float>(1, "Max");
+ blender::fn::VSpan<int> seeds = params.readonly_single_input<int>(2, "Seed");
+ blender::MutableSpan<float> values = params.uninitialized_single_output<float>(3, "Value");
+
+ for (int64_t i : mask) {
+ const float min_value = min_values[i];
+ const float max_value = max_values[i];
+ const int seed = seeds[i];
+ const float value = BLI_hash_int_01((uint32_t)seed ^ function_seed_);
+ values[i] = value * (max_value - min_value) + min_value;
+ }
+ }
+};
+
+static void fn_node_random_float_expand_in_mf_network(
+ blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ uint32_t function_seed = 1746872341u;
+ const blender::nodes::DNode &node = builder.dnode();
+ const blender::DefaultHash<blender::StringRefNull> hasher;
+ function_seed = 33 * function_seed + hasher(node.name());
+ for (const blender::nodes::DParentNode *parent = node.parent(); parent != nullptr;
+ parent = parent->parent()) {
+ function_seed = 33 * function_seed + hasher(parent->node_ref().name());
+ }
+
+ builder.construct_and_set_matching_fn<RandomFloatFunction>(function_seed);
+}
+
+void register_node_type_fn_random_float()
+{
+ static bNodeType ntype;
+
+ fn_node_type_base(&ntype, FN_NODE_RANDOM_FLOAT, "Random Float", 0, 0);
+ node_type_socket_templates(&ntype, fn_node_random_float_in, fn_node_random_float_out);
+ ntype.expand_in_mf_network = fn_node_random_float_expand_in_mf_network;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/function/nodes/node_fn_switch.cc b/source/blender/nodes/function/nodes/node_fn_switch.cc
index cb721058875..281ddb05c76 100644
--- a/source/blender/nodes/function/nodes/node_fn_switch.cc
+++ b/source/blender/nodes/function/nodes/node_fn_switch.cc
@@ -15,7 +15,7 @@
*/
#include "BLI_listbase.h"
-#include "node_function_util.h"
+#include "node_function_util.hh"
static bNodeSocketTemplate fn_node_switch_in[] = {
{SOCK_BOOLEAN, N_("Switch")},
diff --git a/source/blender/blenkernel/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc
index 01317eeb5ce..bcef8c33a3b 100644
--- a/source/blender/blenkernel/intern/derived_node_tree.cc
+++ b/source/blender/nodes/intern/derived_node_tree.cc
@@ -14,13 +14,13 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "BKE_derived_node_tree.hh"
+#include "NOD_derived_node_tree.hh"
#include "BLI_dot_export.hh"
#define UNINITIALIZED_ID UINT32_MAX
-namespace blender::bke {
+namespace blender::nodes {
static const NodeTreeRef &get_tree_ref(NodeTreeRefMap &node_tree_refs, bNodeTree *btree)
{
@@ -28,7 +28,7 @@ static const NodeTreeRef &get_tree_ref(NodeTreeRefMap &node_tree_refs, bNodeTree
[&]() { return std::make_unique<NodeTreeRef>(btree); });
}
-DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs) : btree_(btree)
+DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs)
{
const NodeTreeRef &main_tree_ref = get_tree_ref(node_tree_refs, btree);
@@ -83,7 +83,7 @@ DNode &DerivedNodeTree::create_node(const NodeRef &node_ref,
node.outputs_ = allocator_.construct_elements_and_pointer_array<DOutputSocket>(
node_ref.outputs().size());
- for (uint i : node.inputs_.index_range()) {
+ for (int i : node.inputs_.index_range()) {
const InputSocketRef &socket_ref = node_ref.input(i);
DInputSocket &socket = *node.inputs_[i];
@@ -94,7 +94,7 @@ DNode &DerivedNodeTree::create_node(const NodeRef &node_ref,
r_sockets_map[socket_ref.id()] = &socket;
}
- for (uint i : node.outputs_.index_range()) {
+ for (int i : node.outputs_.index_range()) {
const OutputSocketRef &socket_ref = node_ref.output(i);
DOutputSocket &socket = *node.outputs_[i];
@@ -113,7 +113,7 @@ BLI_NOINLINE void DerivedNodeTree::expand_groups(Vector<DNode *> &all_nodes,
Vector<DParentNode *> &all_parent_nodes,
NodeTreeRefMap &node_tree_refs)
{
- for (uint i = 0; i < all_nodes.size(); i++) {
+ for (int i = 0; i < all_nodes.size(); i++) {
DNode &node = *all_nodes[i];
if (node.node_ref_->is_group_node()) {
this->expand_group_node(node, all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs);
@@ -181,10 +181,10 @@ BLI_NOINLINE void DerivedNodeTree::relink_group_inputs(const NodeTreeRef &group_
const NodeRef &input_node_ref = *node_refs[0];
DNode &input_node = *nodes_by_id[input_node_ref.id()];
- uint input_amount = group_node.inputs().size();
+ int input_amount = group_node.inputs().size();
BLI_assert(input_amount == input_node_ref.outputs().size() - 1);
- for (uint input_index : IndexRange(input_amount)) {
+ for (int input_index : IndexRange(input_amount)) {
DInputSocket *outside_group = group_node.inputs_[input_index];
DOutputSocket *inside_group = input_node.outputs_[input_index];
@@ -228,10 +228,10 @@ BLI_NOINLINE void DerivedNodeTree::relink_group_outputs(const NodeTreeRef &group
const NodeRef &output_node_ref = *node_refs[0];
DNode &output_node = *nodes_by_id[output_node_ref.id()];
- uint output_amount = group_node.outputs().size();
+ int output_amount = group_node.outputs().size();
BLI_assert(output_amount == output_node_ref.inputs().size() - 1);
- for (uint output_index : IndexRange(output_amount)) {
+ for (int output_index : IndexRange(output_amount)) {
DOutputSocket *outside_group = group_node.outputs_[output_index];
DInputSocket *inside_group = output_node.inputs_[output_index];
@@ -316,12 +316,12 @@ BLI_NOINLINE void DerivedNodeTree::store_in_this_and_init_ids(
group_inputs_ = std::move(all_group_inputs);
parent_nodes_ = std::move(all_parent_nodes);
- for (uint node_index : nodes_by_id_.index_range()) {
+ for (int node_index : nodes_by_id_.index_range()) {
DNode *node = nodes_by_id_[node_index];
node->id_ = node_index;
const bNodeType *nodetype = node->node_ref_->bnode()->typeinfo;
- nodes_by_type_.lookup_or_add_default(nodetype).append(node);
+ nodes_by_type_.add(nodetype, node);
for (DInputSocket *socket : node->inputs_) {
socket->id_ = sockets_by_id_.append_and_get_index(socket);
@@ -333,7 +333,7 @@ BLI_NOINLINE void DerivedNodeTree::store_in_this_and_init_ids(
}
}
- for (uint i : group_inputs_.index_range()) {
+ for (int i : group_inputs_.index_range()) {
group_inputs_[i]->id_ = i;
}
}
@@ -438,4 +438,4 @@ std::string DerivedNodeTree::to_dot() const
return digraph.to_dot_string();
}
-} // namespace blender::bke
+} // namespace blender::nodes
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index 996fb93eb76..439e41b963b 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -132,6 +132,9 @@ static bNodeSocket *group_verify_socket(
if (sock) {
strcpy(sock->name, iosock->name);
+ const int mask = SOCK_HIDE_VALUE;
+ sock->flag = (sock->flag & ~mask) | (iosock->flag & mask);
+
if (iosock->typeinfo->interface_verify_socket) {
iosock->typeinfo->interface_verify_socket(ntree, iosock, gnode, sock, "interface");
}
diff --git a/source/blender/nodes/intern/node_common.h b/source/blender/nodes/intern/node_common.h
index 7810e9f1f14..7aad6782640 100644
--- a/source/blender/nodes/intern/node_common.h
+++ b/source/blender/nodes/intern/node_common.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NODE_COMMON_H__
-#define __NODE_COMMON_H__
+#pragma once
#include "DNA_listBase.h"
@@ -40,5 +39,3 @@ void ntree_update_reroute_nodes(struct bNodeTree *ntree);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h
index 87a61f0a490..806dd10d9bf 100644
--- a/source/blender/nodes/intern/node_exec.h
+++ b/source/blender/nodes/intern/node_exec.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NODE_EXEC_H__
-#define __NODE_EXEC_H__
+#pragma once
#include "DNA_listBase.h"
@@ -105,5 +104,3 @@ void ntreeTexEndExecTree_internal(struct bNodeTreeExec *exec);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index b23511c3bdb..0dfae7424cb 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -25,6 +25,8 @@
#include "DNA_node_types.h"
+#include "BLI_color.hh"
+#include "BLI_float3.hh"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
@@ -32,12 +34,14 @@
#include "BKE_lib_id.h"
#include "BKE_node.h"
+#include "BKE_persistent_data_handle.hh"
#include "RNA_access.h"
#include "RNA_types.h"
#include "MEM_guardedalloc.h"
+#include "NOD_node_tree_multi_function.hh"
#include "NOD_socket.h"
struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree,
@@ -352,6 +356,54 @@ void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from)
to->flag |= (from->flag & SOCK_HIDE_VALUE);
}
+void node_socket_skip_reroutes(
+ ListBase *links, bNode *node, bNodeSocket *socket, bNode **r_node, bNodeSocket **r_socket)
+{
+ const int loop_limit = 100; /* Limit in case there is a connection cycle. */
+
+ if (socket->in_out == SOCK_IN) {
+ bNodeLink *first_link = (bNodeLink *)links->first;
+
+ for (int i = 0; node->type == NODE_REROUTE && i < loop_limit; i++) {
+ bNodeLink *link = first_link;
+
+ for (; link; link = link->next) {
+ if (link->fromnode == node && link->tonode != node) {
+ break;
+ }
+ }
+
+ if (link) {
+ node = link->tonode;
+ socket = link->tosock;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ else {
+ for (int i = 0; node->type == NODE_REROUTE && i < loop_limit; i++) {
+ bNodeSocket *input = (bNodeSocket *)node->inputs.first;
+
+ if (input && input->link) {
+ node = input->link->fromnode;
+ socket = input->link->fromsock;
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ if (r_node) {
+ *r_node = node;
+ }
+ if (r_socket) {
+ *r_socket = socket;
+ }
+}
+
static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree),
bNodeSocket *stemp,
bNode *UNUSED(node),
@@ -510,39 +562,162 @@ static bNodeSocketType *make_socket_type_control_flow(int type)
return stype;
}
+static bNodeSocketType *make_socket_type_bool()
+{
+ bNodeSocketType *socktype = make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE);
+ socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<bool>(); };
+ socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
+ bool value = builder.socket_default_value<bNodeSocketValueBoolean>()->value;
+ builder.set_constant_value(value);
+ };
+ return socktype;
+}
+
+static bNodeSocketType *make_socket_type_float(PropertySubType subtype)
+{
+ bNodeSocketType *socktype = make_standard_socket_type(SOCK_FLOAT, subtype);
+ socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<float>(); };
+ socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
+ float value = builder.socket_default_value<bNodeSocketValueFloat>()->value;
+ builder.set_constant_value(value);
+ };
+ return socktype;
+}
+
+static bNodeSocketType *make_socket_type_int(PropertySubType subtype)
+{
+ bNodeSocketType *socktype = make_standard_socket_type(SOCK_INT, subtype);
+ socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<int>(); };
+ socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
+ int value = builder.socket_default_value<bNodeSocketValueInt>()->value;
+ builder.set_constant_value(value);
+ };
+ return socktype;
+}
+
+static bNodeSocketType *make_socket_type_vector(PropertySubType subtype)
+{
+ bNodeSocketType *socktype = make_standard_socket_type(SOCK_VECTOR, subtype);
+ socktype->get_mf_data_type = []() {
+ return blender::fn::MFDataType::ForSingle<blender::float3>();
+ };
+ socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
+ blender::float3 value = builder.socket_default_value<bNodeSocketValueVector>()->value;
+ builder.set_constant_value(value);
+ };
+ return socktype;
+}
+
+static bNodeSocketType *make_socket_type_rgba()
+{
+ bNodeSocketType *socktype = make_standard_socket_type(SOCK_RGBA, PROP_NONE);
+ socktype->get_mf_data_type = []() {
+ return blender::fn::MFDataType::ForSingle<blender::Color4f>();
+ };
+ socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
+ blender::Color4f value = builder.socket_default_value<bNodeSocketValueRGBA>()->value;
+ builder.set_constant_value(value);
+ };
+ return socktype;
+}
+
+static bNodeSocketType *make_socket_type_string()
+{
+ bNodeSocketType *socktype = make_standard_socket_type(SOCK_STRING, PROP_NONE);
+ socktype->get_mf_data_type = []() { return blender::fn::MFDataType::ForSingle<std::string>(); };
+ socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
+ std::string value = builder.socket_default_value<bNodeSocketValueString>()->value;
+ builder.set_constant_value(value);
+ };
+ return socktype;
+}
+
+class ObjectSocketMultiFunction : public blender::fn::MultiFunction {
+ private:
+ Object *object_;
+
+ public:
+ ObjectSocketMultiFunction(Object *object) : object_(object)
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Object Socket");
+ signature.depends_on_context();
+ signature.single_output<blender::bke::PersistentObjectHandle>("Object");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext context) const override
+ {
+ blender::MutableSpan output =
+ params.uninitialized_single_output<blender::bke::PersistentObjectHandle>(0, "Object");
+
+ /* Try to get a handle map, so that the object can be converted to a handle. */
+ const blender::bke::PersistentDataHandleMap *handle_map =
+ context.get_global_context<blender::bke::PersistentDataHandleMap>(
+ "PersistentDataHandleMap");
+
+ if (handle_map == nullptr) {
+ /* Return empty handles when there is no handle map. */
+ output.fill_indices(mask, blender::bke::PersistentObjectHandle());
+ return;
+ }
+
+ blender::bke::PersistentObjectHandle handle = handle_map->lookup(object_);
+ for (int64_t i : mask) {
+ output[i] = handle;
+ }
+ }
+};
+
+MAKE_CPP_TYPE(PersistentObjectHandle, blender::bke::PersistentObjectHandle);
+
+static bNodeSocketType *make_socket_type_object()
+{
+ bNodeSocketType *socktype = make_standard_socket_type(SOCK_OBJECT, PROP_NONE);
+ socktype->get_mf_data_type = []() {
+ /* Objects are not passed along as raw pointers, but as handles. */
+ return blender::fn::MFDataType::ForSingle<blender::bke::PersistentObjectHandle>();
+ };
+ socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
+ Object *object = builder.socket_default_value<bNodeSocketValueObject>()->value;
+ builder.construct_generator_fn<ObjectSocketMultiFunction>(object);
+ };
+ return socktype;
+}
+
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_socket_type_float(PROP_NONE));
+ nodeRegisterSocketType(make_socket_type_float(PROP_UNSIGNED));
+ nodeRegisterSocketType(make_socket_type_float(PROP_PERCENTAGE));
+ nodeRegisterSocketType(make_socket_type_float(PROP_FACTOR));
+ nodeRegisterSocketType(make_socket_type_float(PROP_ANGLE));
+ nodeRegisterSocketType(make_socket_type_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_socket_type_int(PROP_NONE));
+ nodeRegisterSocketType(make_socket_type_int(PROP_UNSIGNED));
+ nodeRegisterSocketType(make_socket_type_int(PROP_PERCENTAGE));
+ nodeRegisterSocketType(make_socket_type_int(PROP_FACTOR));
- nodeRegisterSocketType(make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE));
+ nodeRegisterSocketType(make_socket_type_bool());
- 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));
- nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_VELOCITY));
- 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_socket_type_vector(PROP_NONE));
+ nodeRegisterSocketType(make_socket_type_vector(PROP_TRANSLATION));
+ nodeRegisterSocketType(make_socket_type_vector(PROP_DIRECTION));
+ nodeRegisterSocketType(make_socket_type_vector(PROP_VELOCITY));
+ nodeRegisterSocketType(make_socket_type_vector(PROP_ACCELERATION));
+ nodeRegisterSocketType(make_socket_type_vector(PROP_EULER));
+ nodeRegisterSocketType(make_socket_type_vector(PROP_XYZ));
- nodeRegisterSocketType(make_standard_socket_type(SOCK_RGBA, PROP_NONE));
+ nodeRegisterSocketType(make_socket_type_rgba());
- nodeRegisterSocketType(make_standard_socket_type(SOCK_STRING, PROP_NONE));
+ nodeRegisterSocketType(make_socket_type_string());
nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE));
- nodeRegisterSocketType(make_standard_socket_type(SOCK_OBJECT, PROP_NONE));
+ nodeRegisterSocketType(make_socket_type_object());
nodeRegisterSocketType(make_standard_socket_type(SOCK_IMAGE, PROP_NONE));
diff --git a/source/blender/nodes/intern/node_tree_dependencies.cc b/source/blender/nodes/intern/node_tree_dependencies.cc
new file mode 100644
index 00000000000..efe75a10f7e
--- /dev/null
+++ b/source/blender/nodes/intern/node_tree_dependencies.cc
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "NOD_node_tree_dependencies.hh"
+
+#include "DNA_node_types.h"
+
+#include "BKE_node.h"
+
+namespace blender::nodes {
+
+static void add_dependencies_of_node_tree(bNodeTree &ntree, NodeTreeDependencies &r_dependencies)
+{
+ /* TODO: Do a bit more sophisticated parsing to see which dependencies are really required. */
+ LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ if (socket->type == SOCK_OBJECT) {
+ Object *object = ((bNodeSocketValueObject *)socket->default_value)->value;
+ if (object != nullptr) {
+ r_dependencies.add_transform_dependency(object);
+ if (object->type == OB_MESH) {
+ r_dependencies.add_geometry_dependency(object);
+ }
+ }
+ }
+ }
+
+ if (node->type == NODE_GROUP) {
+ bNodeTree *group = (bNodeTree *)node->id;
+ if (group != nullptr) {
+ add_dependencies_of_node_tree(*group, r_dependencies);
+ }
+ }
+ }
+}
+
+NodeTreeDependencies find_node_tree_dependencies(bNodeTree &ntree)
+{
+ NodeTreeDependencies dependencies;
+ add_dependencies_of_node_tree(ntree, dependencies);
+ return dependencies;
+}
+
+} // namespace blender::nodes
diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc
new file mode 100644
index 00000000000..82842c4ef32
--- /dev/null
+++ b/source/blender/nodes/intern/node_tree_multi_function.cc
@@ -0,0 +1,344 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "NOD_node_tree_multi_function.hh"
+
+#include "BLI_color.hh"
+#include "BLI_float3.hh"
+
+namespace blender::nodes {
+
+/* Maybe this should be moved to BKE_node.h. */
+static std::optional<fn::MFDataType> try_get_multi_function_data_type_of_socket(
+ const bNodeSocket *bsocket)
+{
+ if (bsocket->typeinfo->get_mf_data_type == nullptr) {
+ return {};
+ }
+ return bsocket->typeinfo->get_mf_data_type();
+}
+
+const fn::MultiFunction &NodeMFNetworkBuilder::get_default_fn(StringRef name)
+{
+ Vector<fn::MFDataType, 10> input_types;
+ Vector<fn::MFDataType, 10> output_types;
+
+ for (const DInputSocket *dsocket : dnode_.inputs()) {
+ if (dsocket->is_available()) {
+ std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
+ dsocket->bsocket());
+ if (data_type.has_value()) {
+ input_types.append(*data_type);
+ }
+ }
+ }
+ for (const DOutputSocket *dsocket : dnode_.outputs()) {
+ if (dsocket->is_available()) {
+ std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
+ dsocket->bsocket());
+ if (data_type.has_value()) {
+ output_types.append(*data_type);
+ }
+ }
+ }
+
+ const fn::MultiFunction &fn = this->construct_fn<fn::CustomMF_DefaultOutput>(
+ name, input_types, output_types);
+ return fn;
+}
+
+static void insert_dummy_node(CommonMFNetworkBuilderData &common, const DNode &dnode)
+{
+ constexpr int stack_capacity = 10;
+
+ Vector<fn::MFDataType, stack_capacity> input_types;
+ Vector<StringRef, stack_capacity> input_names;
+ Vector<const DInputSocket *, stack_capacity> input_dsockets;
+
+ for (const DInputSocket *dsocket : dnode.inputs()) {
+ if (dsocket->is_available()) {
+ std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
+ dsocket->bsocket());
+ if (data_type.has_value()) {
+ input_types.append(*data_type);
+ input_names.append(dsocket->name());
+ input_dsockets.append(dsocket);
+ }
+ }
+ }
+
+ Vector<fn::MFDataType, stack_capacity> output_types;
+ Vector<StringRef, stack_capacity> output_names;
+ Vector<const DOutputSocket *, stack_capacity> output_dsockets;
+
+ for (const DOutputSocket *dsocket : dnode.outputs()) {
+ if (dsocket->is_available()) {
+ std::optional<fn::MFDataType> data_type = try_get_multi_function_data_type_of_socket(
+ dsocket->bsocket());
+ if (data_type.has_value()) {
+ output_types.append(*data_type);
+ output_names.append(dsocket->name());
+ output_dsockets.append(dsocket);
+ }
+ }
+ }
+
+ fn::MFDummyNode &dummy_node = common.network.add_dummy(
+ dnode.name(), input_types, output_types, input_names, output_names);
+
+ common.network_map.add(input_dsockets, dummy_node.inputs());
+ common.network_map.add(output_dsockets, dummy_node.outputs());
+}
+
+static bool has_data_sockets(const DNode &dnode)
+{
+ for (const DInputSocket *socket : dnode.inputs()) {
+ if (is_multi_function_data_socket(socket->bsocket())) {
+ return true;
+ }
+ }
+ for (const DOutputSocket *socket : dnode.outputs()) {
+ if (is_multi_function_data_socket(socket->bsocket())) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Expands all function nodes in the multi-function network. Nodes that don't have an expand
+ * function, but do have data sockets, will get corresponding dummy nodes.
+ */
+static void insert_nodes(CommonMFNetworkBuilderData &common)
+{
+ for (const DNode *dnode : common.tree.nodes()) {
+ const bNodeType *node_type = dnode->node_ref().bnode()->typeinfo;
+ if (node_type->expand_in_mf_network != nullptr) {
+ NodeMFNetworkBuilder builder{common, *dnode};
+ node_type->expand_in_mf_network(builder);
+ }
+ else if (has_data_sockets(*dnode)) {
+ insert_dummy_node(common, *dnode);
+ }
+ }
+}
+
+static void insert_group_inputs(CommonMFNetworkBuilderData &common)
+{
+ for (const DGroupInput *group_input : common.tree.group_inputs()) {
+ bNodeSocket *bsocket = group_input->bsocket();
+ if (is_multi_function_data_socket(bsocket)) {
+ bNodeSocketType *socktype = bsocket->typeinfo;
+ BLI_assert(socktype->expand_in_mf_network != nullptr);
+
+ SocketMFNetworkBuilder builder{common, *group_input};
+ socktype->expand_in_mf_network(builder);
+
+ fn::MFOutputSocket *from_socket = builder.built_socket();
+ BLI_assert(from_socket != nullptr);
+ common.network_map.add(*group_input, *from_socket);
+ }
+ }
+}
+
+static fn::MFOutputSocket *try_find_origin(CommonMFNetworkBuilderData &common,
+ const DInputSocket &to_dsocket)
+{
+ Span<const DOutputSocket *> from_dsockets = to_dsocket.linked_sockets();
+ Span<const DGroupInput *> from_group_inputs = to_dsocket.linked_group_inputs();
+ int total_linked_amount = from_dsockets.size() + from_group_inputs.size();
+ BLI_assert(total_linked_amount <= 1);
+
+ if (total_linked_amount == 0) {
+ return nullptr;
+ }
+
+ if (from_dsockets.size() == 1) {
+ const DOutputSocket &from_dsocket = *from_dsockets[0];
+ if (!from_dsocket.is_available()) {
+ return nullptr;
+ }
+ if (is_multi_function_data_socket(from_dsocket.bsocket())) {
+ return &common.network_map.lookup(from_dsocket);
+ }
+ return nullptr;
+ }
+ else {
+ const DGroupInput &from_group_input = *from_group_inputs[0];
+ if (is_multi_function_data_socket(from_group_input.bsocket())) {
+ return &common.network_map.lookup(from_group_input);
+ }
+ return nullptr;
+ }
+}
+
+using ImplicitConversionsMap =
+ Map<std::pair<fn::MFDataType, fn::MFDataType>, const fn::MultiFunction *>;
+
+template<typename From, typename To>
+static void add_implicit_conversion(ImplicitConversionsMap &map)
+{
+ static fn::CustomMF_Convert<From, To> function;
+ map.add({fn::MFDataType::ForSingle<From>(), fn::MFDataType::ForSingle<To>()}, &function);
+}
+
+template<typename From, typename To, typename ConversionF>
+static void add_implicit_conversion(ImplicitConversionsMap &map,
+ StringRef name,
+ ConversionF conversion)
+{
+ static fn::CustomMF_SI_SO<From, To> function{name, conversion};
+ map.add({fn::MFDataType::ForSingle<From>(), fn::MFDataType::ForSingle<To>()}, &function);
+}
+
+static ImplicitConversionsMap get_implicit_conversions()
+{
+ ImplicitConversionsMap conversions;
+ add_implicit_conversion<float, int32_t>(conversions);
+ add_implicit_conversion<float, float3>(conversions);
+ add_implicit_conversion<int32_t, float>(conversions);
+ add_implicit_conversion<float3, float>(
+ conversions, "Vector Length", [](float3 a) { return a.length(); });
+ add_implicit_conversion<int32_t, float3>(
+ conversions, "int32 to float3", [](int32_t a) { return float3((float)a); });
+ add_implicit_conversion<float3, Color4f>(
+ conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
+ add_implicit_conversion<Color4f, float3>(
+ conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
+ return conversions;
+}
+
+static const fn::MultiFunction *try_get_conversion_function(fn::MFDataType from, fn::MFDataType to)
+{
+ static const ImplicitConversionsMap conversions = get_implicit_conversions();
+ const fn::MultiFunction *function = conversions.lookup_default({from, to}, nullptr);
+ return function;
+}
+
+static fn::MFOutputSocket &insert_default_value_for_type(CommonMFNetworkBuilderData &common,
+ fn::MFDataType type)
+{
+ const fn::MultiFunction *default_fn;
+ if (type.is_single()) {
+ default_fn = &common.resources.construct<fn::CustomMF_GenericConstant>(
+ AT, type.single_type(), type.single_type().default_value());
+ }
+ else {
+ default_fn = &common.resources.construct<fn::CustomMF_GenericConstantArray>(
+ AT, fn::GSpan(type.vector_base_type()));
+ }
+
+ fn::MFNode &node = common.network.add_function(*default_fn);
+ return node.output(0);
+}
+
+static void insert_links(CommonMFNetworkBuilderData &common)
+{
+ for (const DInputSocket *to_dsocket : common.tree.input_sockets()) {
+ if (!to_dsocket->is_available()) {
+ continue;
+ }
+ if (!to_dsocket->is_linked()) {
+ continue;
+ }
+ if (!is_multi_function_data_socket(to_dsocket->bsocket())) {
+ continue;
+ }
+
+ Span<fn::MFInputSocket *> to_sockets = common.network_map.lookup(*to_dsocket);
+ BLI_assert(to_sockets.size() >= 1);
+ fn::MFDataType to_type = to_sockets[0]->data_type();
+
+ fn::MFOutputSocket *from_socket = try_find_origin(common, *to_dsocket);
+ if (from_socket == nullptr) {
+ from_socket = &insert_default_value_for_type(common, to_type);
+ }
+
+ fn::MFDataType from_type = from_socket->data_type();
+
+ if (from_type != to_type) {
+ const fn::MultiFunction *conversion_fn = try_get_conversion_function(from_type, to_type);
+ if (conversion_fn != nullptr) {
+ fn::MFNode &node = common.network.add_function(*conversion_fn);
+ common.network.add_link(*from_socket, node.input(0));
+ from_socket = &node.output(0);
+ }
+ else {
+ from_socket = &insert_default_value_for_type(common, to_type);
+ }
+ }
+
+ for (fn::MFInputSocket *to_socket : to_sockets) {
+ common.network.add_link(*from_socket, *to_socket);
+ }
+ }
+}
+
+static void insert_unlinked_input(CommonMFNetworkBuilderData &common, const DInputSocket &dsocket)
+{
+ bNodeSocket *bsocket = dsocket.bsocket();
+ bNodeSocketType *socktype = bsocket->typeinfo;
+ BLI_assert(socktype->expand_in_mf_network != nullptr);
+
+ SocketMFNetworkBuilder builder{common, dsocket};
+ socktype->expand_in_mf_network(builder);
+
+ fn::MFOutputSocket *from_socket = builder.built_socket();
+ BLI_assert(from_socket != nullptr);
+
+ for (fn::MFInputSocket *to_socket : common.network_map.lookup(dsocket)) {
+ common.network.add_link(*from_socket, *to_socket);
+ }
+}
+
+static void insert_unlinked_inputs(CommonMFNetworkBuilderData &common)
+{
+ Vector<const DInputSocket *> unlinked_data_inputs;
+ for (const DInputSocket *dsocket : common.tree.input_sockets()) {
+ if (dsocket->is_available()) {
+ if (is_multi_function_data_socket(dsocket->bsocket())) {
+ if (!dsocket->is_linked()) {
+ insert_unlinked_input(common, *dsocket);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Expands all function nodes contained in the given node tree within the given multi-function
+ * network.
+ *
+ * Returns a mapping between the original node tree and the generated nodes/sockets for further
+ * processing.
+ */
+MFNetworkTreeMap insert_node_tree_into_mf_network(fn::MFNetwork &network,
+ const DerivedNodeTree &tree,
+ ResourceCollector &resources)
+{
+ MFNetworkTreeMap network_map{tree, network};
+
+ CommonMFNetworkBuilderData common{resources, network, network_map, tree};
+
+ insert_nodes(common);
+ insert_group_inputs(common);
+ insert_links(common);
+ insert_unlinked_inputs(common);
+
+ return network_map;
+}
+
+} // namespace blender::nodes
diff --git a/source/blender/blenkernel/intern/node_tree_ref.cc b/source/blender/nodes/intern/node_tree_ref.cc
index 54ea2d338db..47669bc5ca2 100644
--- a/source/blender/blenkernel/intern/node_tree_ref.cc
+++ b/source/blender/nodes/intern/node_tree_ref.cc
@@ -14,11 +14,11 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "BKE_node_tree_ref.hh"
+#include "NOD_node_tree_ref.hh"
#include "BLI_dot_export.hh"
-namespace blender::bke {
+namespace blender::nodes {
NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree)
{
@@ -52,8 +52,8 @@ NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree)
RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.rna_);
}
- input_sockets_.extend(node.inputs_);
- output_sockets_.extend(node.outputs_);
+ input_sockets_.extend(node.inputs_.as_span());
+ output_sockets_.extend(node.outputs_.as_span());
node_mapping.add_new(bnode, &node);
}
@@ -79,7 +79,7 @@ NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree)
for (NodeRef *node : nodes_by_id_) {
const bNodeType *nodetype = node->bnode_->typeinfo;
- nodes_by_type_.lookup_or_add_default(nodetype).append(node);
+ nodes_by_type_.add(nodetype, node);
}
}
@@ -174,4 +174,4 @@ std::string NodeTreeRef::to_dot() const
return digraph.to_dot_string();
}
-} // namespace blender::bke
+} // namespace blender::nodes
diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c
index 9efbdc079e6..b2309abe32e 100644
--- a/source/blender/nodes/intern/node_util.c
+++ b/source/blender/nodes/intern/node_util.c
@@ -73,7 +73,7 @@ void *node_initexec_curves(bNodeExecContext *UNUSED(context),
bNode *node,
bNodeInstanceKey UNUSED(key))
{
- BKE_curvemapping_initialize(node->storage);
+ BKE_curvemapping_init(node->storage);
return NULL; /* unused return */
}
diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h
index 61f8fe6809d..1b542a9420a 100644
--- a/source/blender/nodes/intern/node_util.h
+++ b/source/blender/nodes/intern/node_util.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NODE_UTIL_H__
-#define __NODE_UTIL_H__
+#pragma once
#include "DNA_listBase.h"
@@ -110,5 +109,3 @@ void node_socket_set_vector(struct bNodeTree *ntree,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 179a92ec7bd..758f7edfe49 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -344,15 +344,23 @@ static void ntree_shader_unlink_hidden_value_sockets(bNode *group_node, bNodeSoc
bool removed_link = false;
for (node = group_ntree->nodes.first; node; node = node->next) {
+ const bool is_group = ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && (node->id != NULL);
+
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
- if ((sock->flag & SOCK_HIDE_VALUE) == 0) {
+ if (!is_group && (sock->flag & SOCK_HIDE_VALUE) == 0) {
continue;
}
/* If socket is linked to a group input node and sockets id match. */
if (sock && sock->link && sock->link->fromnode->type == NODE_GROUP_INPUT) {
if (STREQ(isock->identifier, sock->link->fromsock->identifier)) {
- nodeRemLink(group_ntree, sock->link);
- removed_link = true;
+ if (is_group) {
+ /* Recursively unlink sockets within the nested group. */
+ ntree_shader_unlink_hidden_value_sockets(node, sock);
+ }
+ else {
+ nodeRemLink(group_ntree, sock->link);
+ removed_link = true;
+ }
}
}
}
diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.h
index fbb9979cdfa..de192f51a5f 100644
--- a/source/blender/nodes/shader/node_shader_util.h
+++ b/source/blender/nodes/shader/node_shader_util.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NODE_SHADER_UTIL_H__
-#define __NODE_SHADER_UTIL_H__
+#pragma once
#include <float.h>
#include <math.h>
@@ -42,6 +41,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_math_base_safe.h"
#include "BLI_rand.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@@ -70,6 +70,13 @@
#include "GPU_uniformbuffer.h"
#ifdef __cplusplus
+# include "FN_multi_function_builder.hh"
+
+# include "NOD_node_tree_multi_function.hh"
+
+# include "BLI_color.hh"
+# include "BLI_float3.hh"
+
extern "C" {
#endif
@@ -108,5 +115,3 @@ void ntreeExecGPUNodes(struct bNodeTreeExec *exec,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/nodes/shader/nodes/node_shader_clamp.c b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
index 808f9686f0a..1077f616a62 100644
--- a/source/blender/nodes/shader/nodes/node_shader_clamp.c
+++ b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
@@ -50,6 +50,30 @@ static int gpu_shader_clamp(GPUMaterial *mat,
GPU_stack_link(mat, node, "clamp_range", in, out);
}
+static void sh_node_clamp_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> minmax_fn{
+ "Clamp (Min Max)",
+ [](float value, float min, float max) { return std::min(std::max(value, min), max); }};
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> range_fn{
+ "Clamp (Range)", [](float value, float a, float b) {
+ if (a < b) {
+ return clamp_f(value, a, b);
+ }
+ else {
+ return clamp_f(value, b, a);
+ }
+ }};
+
+ int clamp_type = builder.bnode().custom1;
+ if (clamp_type == NODE_CLAMP_MINMAX) {
+ builder.set_matching_fn(minmax_fn);
+ }
+ else {
+ builder.set_matching_fn(range_fn);
+ }
+}
+
void register_node_type_sh_clamp(void)
{
static bNodeType ntype;
@@ -58,6 +82,7 @@ void register_node_type_sh_clamp(void)
node_type_socket_templates(&ntype, sh_node_clamp_in, sh_node_clamp_out);
node_type_init(&ntype, node_shader_init_clamp);
node_type_gpu(&ntype, gpu_shader_clamp);
+ ntype.expand_in_mf_network = sh_node_clamp_expand_in_mf_network;
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 68f252cb092..06aaf9e74cb 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -168,7 +168,7 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat,
CurveMapping *cumap = node->storage;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
BKE_curvemapping_table_RGBA(cumap, &array, &size);
GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer);
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c
index deb0ee9037c..30e376f8e09 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c
@@ -45,6 +45,9 @@ static int node_shader_gpu_geometry(GPUMaterial *mat,
float val[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPUNodeLink *bary_link = (!out[5].hasoutput) ? GPU_constant(val) :
GPU_builtin(GPU_BARYCENTRIC_TEXCO);
+ if (out[5].hasoutput) {
+ GPU_material_flag_set(mat, GPU_MATFLAG_BARYCENTRIC);
+ }
/* Opti: don't request orco if not needed. */
GPUNodeLink *orco_link = (!out[2].hasoutput) ? GPU_constant(val) :
GPU_attribute(mat, CD_ORCO, "");
diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.c b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
index 5db7983e752..4a6c9ec9a4d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_map_range.c
+++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
@@ -50,22 +50,33 @@ static void node_shader_init_map_range(bNodeTree *UNUSED(ntree), bNode *node)
node->custom2 = NODE_MAP_RANGE_LINEAR; /* interpolation */
}
+static const char *gpu_shader_get_name(int mode)
+{
+ switch (mode) {
+ case NODE_MAP_RANGE_LINEAR:
+ return "map_range_linear";
+ case NODE_MAP_RANGE_STEPPED:
+ return "map_range_stepped";
+ case NODE_MAP_RANGE_SMOOTHSTEP:
+ return "map_range_smoothstep";
+ case NODE_MAP_RANGE_SMOOTHERSTEP:
+ return "map_range_smootherstep";
+ }
+
+ return nullptr;
+}
+
static int gpu_shader_map_range(GPUMaterial *mat,
bNode *node,
bNodeExecData *UNUSED(execdata),
GPUNodeStack *in,
GPUNodeStack *out)
{
- static const char *names[] = {
- [NODE_MAP_RANGE_LINEAR] = "map_range_linear",
- [NODE_MAP_RANGE_STEPPED] = "map_range_stepped",
- [NODE_MAP_RANGE_SMOOTHSTEP] = "map_range_smoothstep",
- [NODE_MAP_RANGE_SMOOTHERSTEP] = "map_range_smootherstep",
- };
+ const char *name = gpu_shader_get_name(node->custom2);
int ret = 0;
- if (node->custom2 < ARRAY_SIZE(names) && names[node->custom2]) {
- ret = GPU_stack_link(mat, node, names[node->custom2], in, out);
+ if (name != nullptr) {
+ ret = GPU_stack_link(mat, node, name, in, out);
}
else {
ret = GPU_stack_link(mat, node, "map_range_linear", in, out);
@@ -77,6 +88,68 @@ static int gpu_shader_map_range(GPUMaterial *mat,
return ret;
}
+class MapRangeFunction : public blender::fn::MultiFunction {
+ private:
+ bool clamp_;
+
+ public:
+ MapRangeFunction(bool clamp) : clamp_(clamp)
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Map Range");
+ signature.single_input<float>("Value");
+ signature.single_input<float>("From Min");
+ signature.single_input<float>("From Max");
+ signature.single_input<float>("To Min");
+ signature.single_input<float>("To Max");
+ signature.single_output<float>("Result");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ blender::fn::VSpan<float> values = params.readonly_single_input<float>(0, "Value");
+ blender::fn::VSpan<float> from_min = params.readonly_single_input<float>(1, "From Min");
+ blender::fn::VSpan<float> from_max = params.readonly_single_input<float>(2, "From Max");
+ blender::fn::VSpan<float> to_min = params.readonly_single_input<float>(3, "To Min");
+ blender::fn::VSpan<float> to_max = params.readonly_single_input<float>(4, "To Max");
+ blender::MutableSpan<float> results = params.uninitialized_single_output<float>(5, "Result");
+
+ for (int64_t i : mask) {
+ float factor = safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]);
+ results[i] = to_min[i] + factor * (to_max[i] - to_min[i]);
+ }
+
+ if (clamp_) {
+ for (int64_t i : mask) {
+ CLAMP(results[i], 0.0f, 1.0f);
+ }
+ }
+ }
+};
+
+static void sh_node_map_range_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ bNode &bnode = builder.bnode();
+ bool clamp = bnode.custom1 != 0;
+ int interpolation_type = bnode.custom2;
+
+ if (interpolation_type == NODE_MAP_RANGE_LINEAR) {
+ static MapRangeFunction fn_with_clamp{true};
+ static MapRangeFunction fn_without_clamp{false};
+
+ if (clamp) {
+ builder.set_matching_fn(fn_with_clamp);
+ }
+ else {
+ builder.set_matching_fn(fn_without_clamp);
+ }
+ }
+ else {
+ builder.set_not_implemented();
+ }
+}
+
void register_node_type_sh_map_range(void)
{
static bNodeType ntype;
@@ -86,6 +159,7 @@ void register_node_type_sh_map_range(void)
node_type_init(&ntype, node_shader_init_map_range);
node_type_update(&ntype, node_shader_update_map_range);
node_type_gpu(&ntype, gpu_shader_map_range);
+ ntype.expand_in_mf_network = sh_node_map_range_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
deleted file mode 100644
index 8abebbf5081..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup shdnodes
- */
-
-#include "node_shader_util.h"
-
-/* **************** SCALAR MATH ******************** */
-static bNodeSocketTemplate sh_node_math_in[] = {
- {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
- {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
- {SOCK_FLOAT, N_("Value"), 0.0f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
- {-1, ""}};
-
-static bNodeSocketTemplate sh_node_math_out[] = {{SOCK_FLOAT, N_("Value")}, {-1, ""}};
-
-static int gpu_shader_math(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- static const char *names[] = {
- [NODE_MATH_ADD] = "math_add",
- [NODE_MATH_SUBTRACT] = "math_subtract",
- [NODE_MATH_MULTIPLY] = "math_multiply",
- [NODE_MATH_DIVIDE] = "math_divide",
- [NODE_MATH_MULTIPLY_ADD] = "math_multiply_add",
-
- [NODE_MATH_POWER] = "math_power",
- [NODE_MATH_LOGARITHM] = "math_logarithm",
- [NODE_MATH_EXPONENT] = "math_exponent",
- [NODE_MATH_SQRT] = "math_sqrt",
- [NODE_MATH_INV_SQRT] = "math_inversesqrt",
- [NODE_MATH_ABSOLUTE] = "math_absolute",
- [NODE_MATH_RADIANS] = "math_radians",
- [NODE_MATH_DEGREES] = "math_degrees",
-
- [NODE_MATH_MINIMUM] = "math_minimum",
- [NODE_MATH_MAXIMUM] = "math_maximum",
- [NODE_MATH_LESS_THAN] = "math_less_than",
- [NODE_MATH_GREATER_THAN] = "math_greater_than",
- [NODE_MATH_SIGN] = "math_sign",
- [NODE_MATH_COMPARE] = "math_compare",
- [NODE_MATH_SMOOTH_MIN] = "math_smoothmin",
- [NODE_MATH_SMOOTH_MAX] = "math_smoothmax",
-
- [NODE_MATH_ROUND] = "math_round",
- [NODE_MATH_FLOOR] = "math_floor",
- [NODE_MATH_CEIL] = "math_ceil",
- [NODE_MATH_FRACTION] = "math_fraction",
- [NODE_MATH_MODULO] = "math_modulo",
- [NODE_MATH_TRUNC] = "math_trunc",
- [NODE_MATH_SNAP] = "math_snap",
- [NODE_MATH_WRAP] = "math_wrap",
- [NODE_MATH_PINGPONG] = "math_pingpong",
-
- [NODE_MATH_SINE] = "math_sine",
- [NODE_MATH_COSINE] = "math_cosine",
- [NODE_MATH_TANGENT] = "math_tangent",
- [NODE_MATH_SINH] = "math_sinh",
- [NODE_MATH_COSH] = "math_cosh",
- [NODE_MATH_TANH] = "math_tanh",
- [NODE_MATH_ARCSINE] = "math_arcsine",
- [NODE_MATH_ARCCOSINE] = "math_arccosine",
- [NODE_MATH_ARCTANGENT] = "math_arctangent",
- [NODE_MATH_ARCTAN2] = "math_arctan2",
- };
-
- if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
- int ret = GPU_stack_link(mat, node, names[node->custom1], in, out);
-
- if (ret && node->custom2 & SHD_MATH_CLAMP) {
- float min[3] = {0.0f, 0.0f, 0.0f};
- float max[3] = {1.0f, 1.0f, 1.0f};
- GPU_link(
- mat, "clamp_value", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link);
- }
- return ret;
- }
- else {
- return 0;
- }
-}
-
-void register_node_type_sh_math(void)
-{
- static bNodeType ntype;
-
- sh_fn_node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, 0);
- node_type_socket_templates(&ntype, sh_node_math_in, sh_node_math_out);
- node_type_label(&ntype, node_math_label);
- node_type_gpu(&ntype, gpu_shader_math);
- node_type_update(&ntype, node_math_update);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc
new file mode 100644
index 00000000000..c7035da8c70
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_math.cc
@@ -0,0 +1,387 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.h"
+
+/* **************** SCALAR MATH ******************** */
+static bNodeSocketTemplate sh_node_math_in[] = {
+ {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {SOCK_FLOAT, N_("Value"), 0.0f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {-1, ""}};
+
+static bNodeSocketTemplate sh_node_math_out[] = {{SOCK_FLOAT, N_("Value")}, {-1, ""}};
+
+static const char *gpu_shader_get_name(int mode)
+{
+ switch (mode) {
+ case NODE_MATH_ADD:
+ return "math_add";
+ case NODE_MATH_SUBTRACT:
+ return "math_subtract";
+ case NODE_MATH_MULTIPLY:
+ return "math_multiply";
+ case NODE_MATH_DIVIDE:
+ return "math_divide";
+ case NODE_MATH_MULTIPLY_ADD:
+ return "math_multiply_add";
+
+ case NODE_MATH_POWER:
+ return "math_power";
+ case NODE_MATH_LOGARITHM:
+ return "math_logarithm";
+ case NODE_MATH_EXPONENT:
+ return "math_exponent";
+ case NODE_MATH_SQRT:
+ return "math_sqrt";
+ case NODE_MATH_INV_SQRT:
+ return "math_inversesqrt";
+ case NODE_MATH_ABSOLUTE:
+ return "math_absolute";
+ case NODE_MATH_RADIANS:
+ return "math_radians";
+ case NODE_MATH_DEGREES:
+ return "math_degrees";
+
+ case NODE_MATH_MINIMUM:
+ return "math_minimum";
+ case NODE_MATH_MAXIMUM:
+ return "math_maximum";
+ case NODE_MATH_LESS_THAN:
+ return "math_less_than";
+ case NODE_MATH_GREATER_THAN:
+ return "math_greater_than";
+ case NODE_MATH_SIGN:
+ return "math_sign";
+ case NODE_MATH_COMPARE:
+ return "math_compare";
+ case NODE_MATH_SMOOTH_MIN:
+ return "math_smoothmin";
+ case NODE_MATH_SMOOTH_MAX:
+ return "math_smoothmax";
+
+ case NODE_MATH_ROUND:
+ return "math_round";
+ case NODE_MATH_FLOOR:
+ return "math_floor";
+ case NODE_MATH_CEIL:
+ return "math_ceil";
+ case NODE_MATH_FRACTION:
+ return "math_fraction";
+ case NODE_MATH_MODULO:
+ return "math_modulo";
+ case NODE_MATH_TRUNC:
+ return "math_trunc";
+ case NODE_MATH_SNAP:
+ return "math_snap";
+ case NODE_MATH_WRAP:
+ return "math_wrap";
+ case NODE_MATH_PINGPONG:
+ return "math_pingpong";
+
+ case NODE_MATH_SINE:
+ return "math_sine";
+ case NODE_MATH_COSINE:
+ return "math_cosine";
+ case NODE_MATH_TANGENT:
+ return "math_tangent";
+ case NODE_MATH_SINH:
+ return "math_sinh";
+ case NODE_MATH_COSH:
+ return "math_cosh";
+ case NODE_MATH_TANH:
+ return "math_tanh";
+ case NODE_MATH_ARCSINE:
+ return "math_arcsine";
+ case NODE_MATH_ARCCOSINE:
+ return "math_arccosine";
+ case NODE_MATH_ARCTANGENT:
+ return "math_arctangent";
+ case NODE_MATH_ARCTAN2:
+ return "math_arctan2";
+ }
+ return nullptr;
+}
+
+static int gpu_shader_math(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ const char *name = gpu_shader_get_name(node->custom1);
+ if (name != nullptr) {
+ int ret = GPU_stack_link(mat, node, name, in, out);
+
+ if (ret && node->custom2 & SHD_MATH_CLAMP) {
+ float min[3] = {0.0f, 0.0f, 0.0f};
+ float max[3] = {1.0f, 1.0f, 1.0f};
+ GPU_link(
+ mat, "clamp_value", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link);
+ }
+ return ret;
+ }
+ else {
+ return 0;
+ }
+}
+
+static const blender::fn::MultiFunction &get_base_multi_function(
+ blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ const int mode = builder.bnode().custom1;
+ switch (mode) {
+ case NODE_MATH_ADD: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Add", [](float a, float b) { return a + b; }};
+ return fn;
+ }
+ case NODE_MATH_SUBTRACT: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Subtract", [](float a, float b) { return a - b; }};
+ return fn;
+ }
+ case NODE_MATH_MULTIPLY: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Multiply", [](float a, float b) { return a * b; }};
+ return fn;
+ }
+ case NODE_MATH_DIVIDE: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{"Divide", safe_divide};
+ return fn;
+ }
+ case NODE_MATH_MULTIPLY_ADD: {
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> fn{
+ "Multiply Add", [](float a, float b, float c) { return a * b + c; }};
+ return fn;
+ }
+
+ case NODE_MATH_POWER: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{"Power", safe_powf};
+ return fn;
+ }
+ case NODE_MATH_LOGARITHM: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{"Logarithm", safe_logf};
+ return fn;
+ }
+ case NODE_MATH_EXPONENT: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Exponent", expf};
+ return fn;
+ }
+ case NODE_MATH_SQRT: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Sqrt", safe_sqrtf};
+ return fn;
+ }
+ case NODE_MATH_INV_SQRT: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Inverse Sqrt", safe_inverse_sqrtf};
+ return fn;
+ };
+ case NODE_MATH_ABSOLUTE: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Absolute",
+ [](float a) { return fabs(a); }};
+ return fn;
+ }
+ case NODE_MATH_RADIANS: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Radians",
+ [](float a) { return DEG2RAD(a); }};
+ return fn;
+ }
+ case NODE_MATH_DEGREES: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Degrees",
+ [](float a) { return RAD2DEG(a); }};
+ return fn;
+ }
+
+ case NODE_MATH_MINIMUM: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Minimum", [](float a, float b) { return std::min(a, b); }};
+ return fn;
+ }
+ case NODE_MATH_MAXIMUM: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Maximum", [](float a, float b) { return std::max(a, b); }};
+ return fn;
+ }
+ case NODE_MATH_LESS_THAN: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Less Than", [](float a, float b) { return (float)(a < b); }};
+ return fn;
+ }
+ case NODE_MATH_GREATER_THAN: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Greater Than", [](float a, float b) { return (float)(a > b); }};
+ return fn;
+ }
+ case NODE_MATH_SIGN: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{
+ "Sign", [](float a) { return compatible_signf(a); }};
+ return fn;
+ }
+ case NODE_MATH_COMPARE: {
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> fn{
+ "Compare", [](float a, float b, float c) -> float {
+ return ((a == b) || (fabsf(a - b) <= fmaxf(c, FLT_EPSILON))) ? 1.0f : 0.0f;
+ }};
+ return fn;
+ }
+ case NODE_MATH_SMOOTH_MIN: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_MATH_SMOOTH_MAX: {
+ return builder.get_not_implemented_fn();
+ }
+
+ case NODE_MATH_ROUND: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{
+ "Round", [](float a) { return floorf(a + 0.5f); }};
+ return fn;
+ }
+ case NODE_MATH_FLOOR: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Floor",
+ [](float a) { return floorf(a); }};
+ return fn;
+ }
+ case NODE_MATH_CEIL: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Ceil",
+ [](float a) { return ceilf(a); }};
+ return fn;
+ }
+ case NODE_MATH_FRACTION: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Fraction",
+ [](float a) { return a - floorf(a); }};
+ return fn;
+ }
+ case NODE_MATH_MODULO: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Modulo", [](float a, float b) { return safe_modf(a, b); }};
+ return fn;
+ }
+ case NODE_MATH_TRUNC: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{
+ "Trunc", [](float a) { return a >= 0.0f ? floorf(a) : ceilf(a); }};
+ return fn;
+ }
+ case NODE_MATH_SNAP: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Snap", [](float a, float b) { return floorf(safe_divide(a, b)) * b; }};
+ return fn;
+ }
+ case NODE_MATH_WRAP: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_MATH_PINGPONG: {
+ return builder.get_not_implemented_fn();
+ }
+
+ case NODE_MATH_SINE: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Sine", [](float a) { return sinf(a); }};
+ return fn;
+ }
+ case NODE_MATH_COSINE: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Cosine",
+ [](float a) { return cosf(a); }};
+ return fn;
+ }
+ case NODE_MATH_TANGENT: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Tangent",
+ [](float a) { return tanf(a); }};
+ return fn;
+ }
+ case NODE_MATH_SINH: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Hyperbolic Sine",
+ [](float a) { return sinhf(a); }};
+ return fn;
+ }
+ case NODE_MATH_COSH: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Hyperbolic Cosine",
+ [](float a) { return coshf(a); }};
+ return fn;
+ }
+ case NODE_MATH_TANH: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Hyperbolic Tangent",
+ [](float a) { return tanhf(a); }};
+ return fn;
+ }
+ case NODE_MATH_ARCSINE: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Arc Sine", safe_asinf};
+ return fn;
+ }
+ case NODE_MATH_ARCCOSINE: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Arc Cosine", safe_acosf};
+ return fn;
+ }
+ case NODE_MATH_ARCTANGENT: {
+ static blender::fn::CustomMF_SI_SO<float, float> fn{"Arc Tangent",
+ [](float a) { return atanf(a); }};
+ return fn;
+ }
+ case NODE_MATH_ARCTAN2: {
+ static blender::fn::CustomMF_SI_SI_SO<float, float, float> fn{
+ "Arc Tangent 2", [](float a, float b) { return atan2f(a, b); }};
+ return fn;
+ }
+
+ default:
+ BLI_assert(false);
+ return builder.get_not_implemented_fn();
+ }
+}
+
+static void sh_node_math_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ const blender::fn::MultiFunction &base_function = get_base_multi_function(builder);
+
+ const blender::nodes::DNode &dnode = builder.dnode();
+ blender::fn::MFNetwork &network = builder.network();
+ blender::fn::MFFunctionNode &base_node = network.add_function(base_function);
+
+ builder.network_map().add_try_match(dnode.inputs(), base_node.inputs());
+
+ const bool clamp_output = builder.bnode().custom2 != 0;
+ if (clamp_output) {
+ static blender::fn::CustomMF_SI_SO<float, float> clamp_fn{"Clamp", [](float value) {
+ CLAMP(value, 0.0f, 1.0f);
+ return value;
+ }};
+ blender::fn::MFFunctionNode &clamp_node = network.add_function(clamp_fn);
+ network.add_link(base_node.output(0), clamp_node.input(0));
+ builder.network_map().add(dnode.output(0), clamp_node.output(0));
+ }
+ else {
+ builder.network_map().add(dnode.output(0), base_node.output(0));
+ }
+}
+
+void register_node_type_sh_math(void)
+{
+ static bNodeType ntype;
+
+ sh_fn_node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, 0);
+ node_type_socket_templates(&ntype, sh_node_math_in, sh_node_math_out);
+ node_type_label(&ntype, node_math_label);
+ node_type_gpu(&ntype, gpu_shader_math);
+ node_type_update(&ntype, node_math_update);
+ ntype.expand_in_mf_network = sh_node_math_expand_in_mf_network;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
index d0dc45dcedd..c1543f791f1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
@@ -59,6 +59,42 @@ static int gpu_shader_seprgb(GPUMaterial *mat,
return GPU_stack_link(mat, node, "separate_rgb", in, out);
}
+class SeparateRGBFunction : public blender::fn::MultiFunction {
+ public:
+ SeparateRGBFunction()
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Separate RGB");
+ signature.single_input<blender::Color4f>("Color");
+ signature.single_output<float>("R");
+ signature.single_output<float>("G");
+ signature.single_output<float>("B");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ blender::fn::VSpan<blender::Color4f> colors = params.readonly_single_input<blender::Color4f>(
+ 0, "Color");
+ blender::MutableSpan<float> rs = params.uninitialized_single_output<float>(1, "R");
+ blender::MutableSpan<float> gs = params.uninitialized_single_output<float>(2, "G");
+ blender::MutableSpan<float> bs = params.uninitialized_single_output<float>(3, "B");
+
+ for (int64_t i : mask) {
+ blender::Color4f color = colors[i];
+ rs[i] = color.r;
+ gs[i] = color.g;
+ bs[i] = color.b;
+ }
+ }
+};
+
+static void sh_node_seprgb_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ static SeparateRGBFunction fn;
+ builder.set_matching_fn(fn);
+}
+
void register_node_type_sh_seprgb(void)
{
static bNodeType ntype;
@@ -67,6 +103,7 @@ void register_node_type_sh_seprgb(void)
node_type_socket_templates(&ntype, sh_node_seprgb_in, sh_node_seprgb_out);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_seprgb);
node_type_gpu(&ntype, gpu_shader_seprgb);
+ ntype.expand_in_mf_network = sh_node_seprgb_expand_in_mf_network;
nodeRegisterType(&ntype);
}
@@ -109,6 +146,13 @@ static int gpu_shader_combrgb(GPUMaterial *mat,
return GPU_stack_link(mat, node, "combine_rgb", in, out);
}
+static void sh_node_combrgb_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, blender::Color4f> fn{
+ "Combine RGB", [](float r, float g, float b) { return blender::Color4f(r, g, b, 1.0f); }};
+ builder.set_matching_fn(fn);
+}
+
void register_node_type_sh_combrgb(void)
{
static bNodeType ntype;
@@ -117,6 +161,7 @@ void register_node_type_sh_combrgb(void)
node_type_socket_templates(&ntype, sh_node_combrgb_in, sh_node_combrgb_out);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_combrgb);
node_type_gpu(&ntype, gpu_shader_combrgb);
+ ntype.expand_in_mf_network = sh_node_combrgb_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc
index 429b1a3e818..8b23327460f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc
@@ -44,6 +44,42 @@ static int gpu_shader_sepxyz(GPUMaterial *mat,
return GPU_stack_link(mat, node, "separate_xyz", in, out);
}
+class MF_SeparateXYZ : public blender::fn::MultiFunction {
+ public:
+ MF_SeparateXYZ()
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Separate XYZ");
+ signature.single_input<blender::float3>("XYZ");
+ signature.single_output<float>("X");
+ signature.single_output<float>("Y");
+ signature.single_output<float>("Z");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ blender::fn::VSpan<blender::float3> vectors = params.readonly_single_input<blender::float3>(
+ 0, "XYZ");
+ blender::MutableSpan<float> xs = params.uninitialized_single_output<float>(1, "X");
+ blender::MutableSpan<float> ys = params.uninitialized_single_output<float>(2, "Y");
+ blender::MutableSpan<float> zs = params.uninitialized_single_output<float>(3, "Z");
+
+ for (int64_t i : mask) {
+ blender::float3 xyz = vectors[i];
+ xs[i] = xyz.x;
+ ys[i] = xyz.y;
+ zs[i] = xyz.z;
+ }
+ }
+};
+
+static void sh_node_sepxyz_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ static MF_SeparateXYZ separate_fn;
+ builder.set_matching_fn(separate_fn);
+}
+
void register_node_type_sh_sepxyz(void)
{
static bNodeType ntype;
@@ -51,6 +87,7 @@ void register_node_type_sh_sepxyz(void)
sh_fn_node_type_base(&ntype, SH_NODE_SEPXYZ, "Separate XYZ", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, sh_node_sepxyz_in, sh_node_sepxyz_out);
node_type_gpu(&ntype, gpu_shader_sepxyz);
+ ntype.expand_in_mf_network = sh_node_sepxyz_expand_in_mf_network;
nodeRegisterType(&ntype);
}
@@ -76,6 +113,13 @@ static int gpu_shader_combxyz(GPUMaterial *mat,
return GPU_stack_link(mat, node, "combine_xyz", in, out);
}
+static void sh_node_combxyz_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, blender::float3> fn{
+ "Combine Vector", [](float x, float y, float z) { return blender::float3(x, y, z); }};
+ builder.set_matching_fn(fn);
+}
+
void register_node_type_sh_combxyz(void)
{
static bNodeType ntype;
@@ -83,6 +127,7 @@ void register_node_type_sh_combxyz(void)
sh_fn_node_type_base(&ntype, SH_NODE_COMBXYZ, "Combine XYZ", NODE_CLASS_CONVERTOR, 0);
node_type_socket_templates(&ntype, sh_node_combxyz_in, sh_node_combxyz_out);
node_type_gpu(&ntype, gpu_shader_combxyz);
+ ntype.expand_in_mf_network = sh_node_combxyz_expand_in_mf_network;
nodeRegisterType(&ntype);
}
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 0cf4b51f307..38e79ebe94d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -19,8 +19,6 @@
#include "../node_shader_util.h"
-#include "GPU_draw.h"
-
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_tex_environment_in[] = {
@@ -59,7 +57,8 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
NodeTexImage *tex_original = node_original->storage;
ImageUser *iuser = &tex_original->iuser;
eGPUSamplerState sampler = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER;
- if (GPU_get_mipmap()) {
+ /* TODO(fclem) For now assume mipmap is always enabled. */
+ if (true) {
sampler |= GPU_SAMPLER_MIPMAP;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index cbda72cd228..1a78d2f5bf2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -19,8 +19,6 @@
#include "../node_shader_util.h"
-#include "GPU_draw.h"
-
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_tex_image_in[] = {
@@ -95,7 +93,8 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
if (tex->interpolation != SHD_INTERP_CLOSEST) {
sampler_state |= GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER;
- sampler_state |= GPU_get_mipmap() ? GPU_SAMPLER_MIPMAP : 0;
+ /* TODO(fclem) For now assume mipmap is always enabled. */
+ sampler_state |= true ? GPU_SAMPLER_MIPMAP : 0;
}
const bool use_cubic = ELEM(tex->interpolation, SHD_INTERP_CUBIC, SHD_INTERP_SMART);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
index 0daa948c139..94ffbbe0c55 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
@@ -18,6 +18,7 @@
*/
#include "../node_shader_util.h"
+#include "sky_model.h"
/* **************** OUTPUT ******************** */
@@ -42,10 +43,11 @@ static void node_shader_init_tex_sky(bNodeTree *UNUSED(ntree), bNode *node)
tex->turbidity = 2.2f;
tex->ground_albedo = 0.3f;
tex->sun_disc = true;
- tex->sun_size = DEG2RADF(0.545);
- tex->sun_elevation = M_PI_2;
+ tex->sun_size = DEG2RADF(0.545f);
+ tex->sun_intensity = 1.0f;
+ tex->sun_elevation = DEG2RADF(15.0f);
tex->sun_rotation = 0.0f;
- tex->altitude = 0;
+ tex->altitude = 0.0f;
tex->air_density = 1.0f;
tex->dust_density = 1.0f;
tex->ozone_density = 1.0f;
@@ -53,19 +55,172 @@ static void node_shader_init_tex_sky(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = tex;
}
+typedef struct SkyModelPreetham {
+ float config_Y[5], config_x[5], config_y[5]; /* named after xyY color space */
+ float radiance[3];
+} SkyModelPreetham;
+
+typedef struct XYZ_to_RGB /* transposed imbuf_xyz_to_rgb, passed as 3x vec3 */
+{
+ float r[3], g[3], b[3];
+} XYZ_to_RGB;
+
+static float sky_perez_function(const float *lam, float theta, float gamma)
+{
+ float ctheta = cosf(theta);
+ float cgamma = cosf(gamma);
+
+ return (1.0 + lam[0] * expf(lam[1] / ctheta)) *
+ (1.0 + lam[2] * expf(lam[3] * gamma) + lam[4] * cgamma * cgamma);
+}
+
+static void sky_precompute_old(SkyModelPreetham *sunsky, const float sun_angles[], float turbidity)
+{
+ float theta = sun_angles[0];
+ float theta2 = theta * theta;
+ float theta3 = theta2 * theta;
+ float T = turbidity;
+ float T2 = T * T;
+ float chi = (4.0f / 9.0f - T / 120.0f) * (M_PI - 2.0f * theta);
+
+ sunsky->radiance[0] = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f;
+ sunsky->radiance[0] *= 0.06f;
+
+ sunsky->radiance[1] = (0.00166f * theta3 - 0.00375f * theta2 + 0.00209f * theta) * T2 +
+ (-0.02903f * theta3 + 0.06377f * theta2 - 0.03202f * theta + 0.00394f) *
+ T +
+ (0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * theta + 0.25886f);
+
+ sunsky->radiance[2] = (0.00275f * theta3 - 0.00610f * theta2 + 0.00317f * theta) * T2 +
+ (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * theta + 0.00516f) *
+ T +
+ (0.15346f * theta3 - 0.26756f * theta2 + 0.06670f * theta + 0.26688f);
+
+ sunsky->config_Y[0] = (0.1787f * T - 1.4630f);
+ sunsky->config_Y[1] = (-0.3554f * T + 0.4275f);
+ sunsky->config_Y[2] = (-0.0227f * T + 5.3251f);
+ sunsky->config_Y[3] = (0.1206f * T - 2.5771f);
+ sunsky->config_Y[4] = (-0.0670f * T + 0.3703f);
+
+ sunsky->config_x[0] = (-0.0193f * T - 0.2592f);
+ sunsky->config_x[1] = (-0.0665f * T + 0.0008f);
+ sunsky->config_x[2] = (-0.0004f * T + 0.2125f);
+ sunsky->config_x[3] = (-0.0641f * T - 0.8989f);
+ sunsky->config_x[4] = (-0.0033f * T + 0.0452f);
+
+ sunsky->config_y[0] = (-0.0167f * T - 0.2608f);
+ sunsky->config_y[1] = (-0.0950f * T + 0.0092f);
+ sunsky->config_y[2] = (-0.0079f * T + 0.2102f);
+ sunsky->config_y[3] = (-0.0441f * T - 1.6537f);
+ sunsky->config_y[4] = (-0.0109f * T + 0.0529f);
+
+ sunsky->radiance[0] /= sky_perez_function(sunsky->config_Y, 0, theta);
+ sunsky->radiance[1] /= sky_perez_function(sunsky->config_x, 0, theta);
+ sunsky->radiance[2] /= sky_perez_function(sunsky->config_y, 0, theta);
+}
+
+static void get_XYZ_to_RGB_for_gpu(XYZ_to_RGB *data)
+{
+ const float *xyz_to_rgb = IMB_colormangement_get_xyz_to_rgb();
+ data->r[0] = xyz_to_rgb[0];
+ data->r[1] = xyz_to_rgb[3];
+ data->r[2] = xyz_to_rgb[6];
+ data->g[0] = xyz_to_rgb[1];
+ data->g[1] = xyz_to_rgb[4];
+ data->g[2] = xyz_to_rgb[7];
+ data->b[0] = xyz_to_rgb[2];
+ data->b[1] = xyz_to_rgb[5];
+ data->b[2] = xyz_to_rgb[8];
+}
+
static int node_shader_gpu_tex_sky(GPUMaterial *mat,
bNode *node,
bNodeExecData *UNUSED(execdata),
GPUNodeStack *in,
GPUNodeStack *out)
{
- if (!in[0].link) {
- in[0].link = GPU_attribute(mat, CD_ORCO, "");
+ node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
+ node_shader_gpu_tex_mapping(mat, node, in, out);
+ NodeTexSky *tex = (NodeTexSky *)node->storage;
+ float sun_angles[2]; /* [0]=theta=zenith angle [1]=phi=azimuth */
+ sun_angles[0] = acosf(tex->sun_direction[2]);
+ sun_angles[1] = atan2f(tex->sun_direction[0], tex->sun_direction[1]);
+
+ if (tex->sky_model == 0) {
+ /* Preetham */
+ SkyModelPreetham sunsky;
+ sky_precompute_old(&sunsky, sun_angles, tex->turbidity);
+ XYZ_to_RGB xyz_to_rgb;
+ get_XYZ_to_RGB_for_gpu(&xyz_to_rgb);
+ return GPU_stack_link(mat,
+ node,
+ "node_tex_sky_preetham",
+ in,
+ out,
+ /* Pass config_Y/x/y as 3x(vec4+float) */
+ GPU_uniform(&sunsky.config_Y[0]),
+ GPU_uniform(&sunsky.config_Y[4]),
+ GPU_uniform(&sunsky.config_x[0]),
+ GPU_uniform(&sunsky.config_x[4]),
+ GPU_uniform(&sunsky.config_y[0]),
+ GPU_uniform(&sunsky.config_y[4]),
+ GPU_uniform(sun_angles),
+ GPU_uniform(sunsky.radiance),
+ GPU_uniform(xyz_to_rgb.r),
+ GPU_uniform(xyz_to_rgb.g),
+ GPU_uniform(xyz_to_rgb.b));
+ }
+ else if (tex->sky_model == 1) {
+ /* Hosek / Wilkie */
+ sun_angles[0] = fmin(M_PI_2, sun_angles[0]); /* clamp to horizon */
+ SKY_ArHosekSkyModelState *sky_state = SKY_arhosek_xyz_skymodelstate_alloc_init(
+ tex->turbidity, tex->ground_albedo, fmax(0.0, M_PI_2 - sun_angles[0]));
+ /* Pass sky_state->configs[3][9] as 3*(vec4+vec4)+vec3 */
+ float config_x07[8], config_y07[8], config_z07[8], config_xyz8[3];
+ for (int i = 0; i < 8; ++i) {
+ config_x07[i] = (float)sky_state->configs[0][i];
+ config_y07[i] = (float)sky_state->configs[1][i];
+ config_z07[i] = (float)sky_state->configs[2][i];
+ }
+ for (int i = 0; i < 3; ++i) {
+ config_xyz8[i] = (float)sky_state->configs[i][8];
+ }
+ float radiance[3];
+ for (int i = 0; i < 3; i++) {
+ radiance[i] = sky_state->radiances[i] * (2 * M_PI / 683);
+ }
+ SKY_arhosekskymodelstate_free(sky_state);
+ XYZ_to_RGB xyz_to_rgb;
+ get_XYZ_to_RGB_for_gpu(&xyz_to_rgb);
+ return GPU_stack_link(mat,
+ node,
+ "node_tex_sky_hosekwilkie",
+ in,
+ out,
+ GPU_uniform(&config_x07[0]),
+ GPU_uniform(&config_x07[4]),
+ GPU_uniform(&config_y07[0]),
+ GPU_uniform(&config_y07[4]),
+ GPU_uniform(&config_z07[0]),
+ GPU_uniform(&config_z07[4]),
+ GPU_uniform(config_xyz8),
+ GPU_uniform(sun_angles),
+ GPU_uniform(radiance),
+ GPU_uniform(xyz_to_rgb.r),
+ GPU_uniform(xyz_to_rgb.g),
+ GPU_uniform(xyz_to_rgb.b));
+ }
+ else {
+ return GPU_stack_link(mat, node, "node_tex_sky_nishita", in, out);
}
+}
- node_shader_gpu_tex_mapping(mat, node, in, out);
+static void node_shader_update_sky(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ bNodeSocket *sockVector = nodeFindSocket(node, SOCK_IN, "Vector");
- return GPU_stack_link(mat, node, "node_tex_sky", in, out);
+ NodeTexSky *tex = (NodeTexSky *)node->storage;
+ nodeSetSocketAvailability(sockVector, !(tex->sky_model == 2 && tex->sun_disc == 1));
}
/* node type definition */
@@ -79,6 +234,8 @@ void register_node_type_sh_tex_sky(void)
node_type_init(&ntype, node_shader_init_tex_sky);
node_type_storage(&ntype, "NodeTexSky", node_free_standard_storage, node_copy_standard_storage);
node_type_gpu(&ntype, node_shader_gpu_tex_sky);
+ /* remove Vector input for Nishita */
+ node_type_update(&ntype, node_shader_update_sky);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
index 20f280d00c3..7f712b0db40 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
@@ -22,6 +22,11 @@
*/
#include "IMB_colormanagement.h"
+
+#include "DNA_texture_types.h"
+
+#include "BLI_color.hh"
+
#include "node_shader_util.h"
/* **************** VALTORGB ******************** */
@@ -49,7 +54,7 @@ static void node_shader_exec_valtorgb(void *UNUSED(data),
float fac;
nodestack_get_vec(&fac, SOCK_FLOAT, in[0]);
- BKE_colorband_evaluate(node->storage, fac, out[0]->vec);
+ BKE_colorband_evaluate((ColorBand *)node->storage, fac, out[0]->vec);
out[1]->vec[0] = out[0]->vec[3];
}
}
@@ -65,7 +70,7 @@ static int gpu_shader_valtorgb(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
- struct ColorBand *coba = node->storage;
+ struct ColorBand *coba = (ColorBand *)node->storage;
float *array, layer;
int size;
@@ -121,6 +126,44 @@ static int gpu_shader_valtorgb(GPUMaterial *mat,
}
}
+class ColorBandFunction : public blender::fn::MultiFunction {
+ private:
+ const ColorBand &color_band_;
+
+ public:
+ ColorBandFunction(const ColorBand &color_band) : color_band_(color_band)
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Color Band");
+ signature.single_input<float>("Value");
+ signature.single_output<blender::Color4f>("Color");
+ signature.single_output<float>("Alpha");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ blender::fn::VSpan<float> values = params.readonly_single_input<float>(0, "Value");
+ blender::MutableSpan<blender::Color4f> colors =
+ params.uninitialized_single_output<blender::Color4f>(1, "Color");
+ blender::MutableSpan<float> alphas = params.uninitialized_single_output<float>(2, "Alpha");
+
+ for (int64_t i : mask) {
+ blender::Color4f color;
+ BKE_colorband_evaluate(&color_band_, values[i], color);
+ colors[i] = color;
+ alphas[i] = color.a;
+ }
+ }
+};
+
+static void sh_node_valtorgb_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ bNode &bnode = builder.bnode();
+ const ColorBand *color_band = (const ColorBand *)bnode.storage;
+ builder.construct_and_set_matching_fn<ColorBandFunction>(*color_band);
+}
+
void register_node_type_sh_valtorgb(void)
{
static bNodeType ntype;
@@ -132,6 +175,7 @@ void register_node_type_sh_valtorgb(void)
node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage);
node_type_exec(&ntype, NULL, NULL, node_shader_exec_valtorgb);
node_type_gpu(&ntype, gpu_shader_valtorgb);
+ ntype.expand_in_mf_network = sh_node_valtorgb_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_value.c b/source/blender/nodes/shader/nodes/node_shader_value.cc
index c32e9e1d581..1d7c3f47233 100644
--- a/source/blender/nodes/shader/nodes/node_shader_value.c
+++ b/source/blender/nodes/shader/nodes/node_shader_value.cc
@@ -39,13 +39,21 @@ static int gpu_shader_value(GPUMaterial *mat,
return GPU_stack_link(mat, node, "set_value", in, out, link);
}
+static void sh_node_value_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ const bNodeSocket *bsocket = builder.dnode().output(0).bsocket();
+ const bNodeSocketValueFloat *value = (const bNodeSocketValueFloat *)bsocket->default_value;
+ builder.construct_and_set_matching_fn<blender::fn::CustomMF_Constant<float>>(value->value);
+}
+
void register_node_type_sh_value(void)
{
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_VALUE, "Value", NODE_CLASS_INPUT, 0);
+ sh_fn_node_type_base(&ntype, SH_NODE_VALUE, "Value", NODE_CLASS_INPUT, 0);
node_type_socket_templates(&ntype, NULL, sh_node_value_out);
node_type_gpu(&ntype, gpu_shader_value);
+ ntype.expand_in_mf_network = sh_node_value_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.c b/source/blender/nodes/shader/nodes/node_shader_vector_math.c
deleted file mode 100644
index b719fe03d9b..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_vector_math.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup shdnodes
- */
-
-#include "node_shader_util.h"
-
-/* **************** VECTOR MATH ******************** */
-static bNodeSocketTemplate sh_node_vector_math_in[] = {
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
- {SOCK_FLOAT, N_("Scale"), 1.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
- {-1, ""}};
-
-static bNodeSocketTemplate sh_node_vector_math_out[] = {
- {SOCK_VECTOR, N_("Vector")}, {SOCK_FLOAT, N_("Value")}, {-1, ""}};
-
-static int gpu_shader_vector_math(GPUMaterial *mat,
- bNode *node,
- bNodeExecData *UNUSED(execdata),
- GPUNodeStack *in,
- GPUNodeStack *out)
-{
- static const char *names[] = {
- [NODE_VECTOR_MATH_ADD] = "vector_math_add",
- [NODE_VECTOR_MATH_SUBTRACT] = "vector_math_subtract",
- [NODE_VECTOR_MATH_MULTIPLY] = "vector_math_multiply",
- [NODE_VECTOR_MATH_DIVIDE] = "vector_math_divide",
-
- [NODE_VECTOR_MATH_CROSS_PRODUCT] = "vector_math_cross",
- [NODE_VECTOR_MATH_PROJECT] = "vector_math_project",
- [NODE_VECTOR_MATH_REFLECT] = "vector_math_reflect",
- [NODE_VECTOR_MATH_DOT_PRODUCT] = "vector_math_dot",
-
- [NODE_VECTOR_MATH_DISTANCE] = "vector_math_distance",
- [NODE_VECTOR_MATH_LENGTH] = "vector_math_length",
- [NODE_VECTOR_MATH_SCALE] = "vector_math_scale",
- [NODE_VECTOR_MATH_NORMALIZE] = "vector_math_normalize",
-
- [NODE_VECTOR_MATH_SNAP] = "vector_math_snap",
- [NODE_VECTOR_MATH_FLOOR] = "vector_math_floor",
- [NODE_VECTOR_MATH_CEIL] = "vector_math_ceil",
- [NODE_VECTOR_MATH_MODULO] = "vector_math_modulo",
- [NODE_VECTOR_MATH_FRACTION] = "vector_math_fraction",
- [NODE_VECTOR_MATH_ABSOLUTE] = "vector_math_absolute",
- [NODE_VECTOR_MATH_MINIMUM] = "vector_math_minimum",
- [NODE_VECTOR_MATH_MAXIMUM] = "vector_math_maximum",
- [NODE_VECTOR_MATH_WRAP] = "vector_math_wrap",
- [NODE_VECTOR_MATH_SINE] = "vector_math_sine",
- [NODE_VECTOR_MATH_COSINE] = "vector_math_cosine",
- [NODE_VECTOR_MATH_TANGENT] = "vector_math_tangent",
- };
-
- if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
- return GPU_stack_link(mat, node, names[node->custom1], in, out);
- }
- else {
- return 0;
- }
-}
-
-static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node)
-{
- bNodeSocket *sockB = BLI_findlink(&node->inputs, 1);
- bNodeSocket *sockC = BLI_findlink(&node->inputs, 2);
- bNodeSocket *sockScale = nodeFindSocket(node, SOCK_IN, "Scale");
-
- bNodeSocket *sockVector = nodeFindSocket(node, SOCK_OUT, "Vector");
- bNodeSocket *sockValue = nodeFindSocket(node, SOCK_OUT, "Value");
-
- nodeSetSocketAvailability(sockB,
- !ELEM(node->custom1,
- NODE_VECTOR_MATH_SINE,
- NODE_VECTOR_MATH_COSINE,
- NODE_VECTOR_MATH_TANGENT,
- NODE_VECTOR_MATH_CEIL,
- NODE_VECTOR_MATH_SCALE,
- NODE_VECTOR_MATH_FLOOR,
- NODE_VECTOR_MATH_LENGTH,
- NODE_VECTOR_MATH_ABSOLUTE,
- NODE_VECTOR_MATH_FRACTION,
- NODE_VECTOR_MATH_NORMALIZE));
- nodeSetSocketAvailability(sockC, ELEM(node->custom1, NODE_VECTOR_MATH_WRAP));
- nodeSetSocketAvailability(sockScale, node->custom1 == NODE_VECTOR_MATH_SCALE);
- nodeSetSocketAvailability(sockVector,
- !ELEM(node->custom1,
- NODE_VECTOR_MATH_LENGTH,
- NODE_VECTOR_MATH_DISTANCE,
- NODE_VECTOR_MATH_DOT_PRODUCT));
- nodeSetSocketAvailability(sockValue,
- ELEM(node->custom1,
- NODE_VECTOR_MATH_LENGTH,
- NODE_VECTOR_MATH_DISTANCE,
- NODE_VECTOR_MATH_DOT_PRODUCT));
-
- /* Labels */
- if (sockB->label[0] != '\0') {
- sockB->label[0] = '\0';
- }
- if (sockC->label[0] != '\0') {
- sockC->label[0] = '\0';
- }
- switch (node->custom1) {
- case NODE_VECTOR_MATH_WRAP:
- node_sock_label(sockB, "Max");
- node_sock_label(sockC, "Min");
- break;
- case NODE_VECTOR_MATH_SNAP:
- node_sock_label(sockB, "Increment");
- break;
- }
-}
-
-void register_node_type_sh_vect_math(void)
-{
- static bNodeType ntype;
-
- sh_fn_node_type_base(&ntype, SH_NODE_VECTOR_MATH, "Vector Math", NODE_CLASS_OP_VECTOR, 0);
- node_type_socket_templates(&ntype, sh_node_vector_math_in, sh_node_vector_math_out);
- node_type_label(&ntype, node_vector_math_label);
- node_type_gpu(&ntype, gpu_shader_vector_math);
- node_type_update(&ntype, node_shader_update_vector_math);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
new file mode 100644
index 00000000000..c18ad8bb244
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
@@ -0,0 +1,292 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup shdnodes
+ */
+
+#include "node_shader_util.h"
+
+/* **************** VECTOR MATH ******************** */
+static bNodeSocketTemplate sh_node_vector_math_in[] = {
+ {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {SOCK_FLOAT, N_("Scale"), 1.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {-1, ""}};
+
+static bNodeSocketTemplate sh_node_vector_math_out[] = {
+ {SOCK_VECTOR, N_("Vector")}, {SOCK_FLOAT, N_("Value")}, {-1, ""}};
+
+static const char *gpu_shader_get_name(int mode)
+{
+ switch (mode) {
+ case NODE_VECTOR_MATH_ADD:
+ return "vector_math_add";
+ case NODE_VECTOR_MATH_SUBTRACT:
+ return "vector_math_subtract";
+ case NODE_VECTOR_MATH_MULTIPLY:
+ return "vector_math_multiply";
+ case NODE_VECTOR_MATH_DIVIDE:
+ return "vector_math_divide";
+
+ case NODE_VECTOR_MATH_CROSS_PRODUCT:
+ return "vector_math_cross";
+ case NODE_VECTOR_MATH_PROJECT:
+ return "vector_math_project";
+ case NODE_VECTOR_MATH_REFLECT:
+ return "vector_math_reflect";
+ case NODE_VECTOR_MATH_DOT_PRODUCT:
+ return "vector_math_dot";
+
+ case NODE_VECTOR_MATH_DISTANCE:
+ return "vector_math_distance";
+ case NODE_VECTOR_MATH_LENGTH:
+ return "vector_math_length";
+ case NODE_VECTOR_MATH_SCALE:
+ return "vector_math_scale";
+ case NODE_VECTOR_MATH_NORMALIZE:
+ return "vector_math_normalize";
+
+ case NODE_VECTOR_MATH_SNAP:
+ return "vector_math_snap";
+ case NODE_VECTOR_MATH_FLOOR:
+ return "vector_math_floor";
+ case NODE_VECTOR_MATH_CEIL:
+ return "vector_math_ceil";
+ case NODE_VECTOR_MATH_MODULO:
+ return "vector_math_modulo";
+ case NODE_VECTOR_MATH_FRACTION:
+ return "vector_math_fraction";
+ case NODE_VECTOR_MATH_ABSOLUTE:
+ return "vector_math_absolute";
+ case NODE_VECTOR_MATH_MINIMUM:
+ return "vector_math_minimum";
+ case NODE_VECTOR_MATH_MAXIMUM:
+ return "vector_math_maximum";
+ case NODE_VECTOR_MATH_WRAP:
+ return "vector_math_wrap";
+ case NODE_VECTOR_MATH_SINE:
+ return "vector_math_sine";
+ case NODE_VECTOR_MATH_COSINE:
+ return "vector_math_cosine";
+ case NODE_VECTOR_MATH_TANGENT:
+ return "vector_math_tangent";
+ }
+
+ return nullptr;
+}
+
+static int gpu_shader_vector_math(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ const char *name = gpu_shader_get_name(node->custom1);
+ if (name != nullptr) {
+ return GPU_stack_link(mat, node, name, in, out);
+ }
+ else {
+ return 0;
+ }
+}
+
+static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ bNodeSocket *sockB = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
+ bNodeSocket *sockC = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
+ bNodeSocket *sockScale = nodeFindSocket(node, SOCK_IN, "Scale");
+
+ bNodeSocket *sockVector = nodeFindSocket(node, SOCK_OUT, "Vector");
+ bNodeSocket *sockValue = nodeFindSocket(node, SOCK_OUT, "Value");
+
+ nodeSetSocketAvailability(sockB,
+ !ELEM(node->custom1,
+ NODE_VECTOR_MATH_SINE,
+ NODE_VECTOR_MATH_COSINE,
+ NODE_VECTOR_MATH_TANGENT,
+ NODE_VECTOR_MATH_CEIL,
+ NODE_VECTOR_MATH_SCALE,
+ NODE_VECTOR_MATH_FLOOR,
+ NODE_VECTOR_MATH_LENGTH,
+ NODE_VECTOR_MATH_ABSOLUTE,
+ NODE_VECTOR_MATH_FRACTION,
+ NODE_VECTOR_MATH_NORMALIZE));
+ nodeSetSocketAvailability(sockC, ELEM(node->custom1, NODE_VECTOR_MATH_WRAP));
+ nodeSetSocketAvailability(sockScale, node->custom1 == NODE_VECTOR_MATH_SCALE);
+ nodeSetSocketAvailability(sockVector,
+ !ELEM(node->custom1,
+ NODE_VECTOR_MATH_LENGTH,
+ NODE_VECTOR_MATH_DISTANCE,
+ NODE_VECTOR_MATH_DOT_PRODUCT));
+ nodeSetSocketAvailability(sockValue,
+ ELEM(node->custom1,
+ NODE_VECTOR_MATH_LENGTH,
+ NODE_VECTOR_MATH_DISTANCE,
+ NODE_VECTOR_MATH_DOT_PRODUCT));
+
+ /* Labels */
+ if (sockB->label[0] != '\0') {
+ sockB->label[0] = '\0';
+ }
+ if (sockC->label[0] != '\0') {
+ sockC->label[0] = '\0';
+ }
+ switch (node->custom1) {
+ case NODE_VECTOR_MATH_WRAP:
+ node_sock_label(sockB, "Max");
+ node_sock_label(sockC, "Min");
+ break;
+ case NODE_VECTOR_MATH_SNAP:
+ node_sock_label(sockB, "Increment");
+ break;
+ }
+}
+
+static const blender::fn::MultiFunction &get_multi_function(
+ blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ using blender::float3;
+
+ const int mode = builder.bnode().custom1;
+ switch (mode) {
+ case NODE_VECTOR_MATH_ADD: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
+ "Add", [](float3 a, float3 b) { return a + b; }};
+ return fn;
+ }
+ case NODE_VECTOR_MATH_SUBTRACT: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
+ "Subtract", [](float3 a, float3 b) { return a - b; }};
+ return fn;
+ }
+ case NODE_VECTOR_MATH_MULTIPLY: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
+ "Multiply", [](float3 a, float3 b) { return a * b; }};
+ return fn;
+ }
+ case NODE_VECTOR_MATH_DIVIDE: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
+ "Divide", [](float3 a, float3 b) { return float3::safe_divide(a, b); }};
+ return fn;
+ }
+
+ case NODE_VECTOR_MATH_CROSS_PRODUCT: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
+ "Cross Product", float3::cross_high_precision};
+ return fn;
+ }
+ case NODE_VECTOR_MATH_PROJECT: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{"Project", float3::project};
+ return fn;
+ }
+ case NODE_VECTOR_MATH_REFLECT: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{
+ "Reflect", [](float3 a, float3 b) { return a.reflected(b); }};
+ return fn;
+ }
+ case NODE_VECTOR_MATH_DOT_PRODUCT: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{"Dot Product", float3::dot};
+ return fn;
+ }
+
+ case NODE_VECTOR_MATH_DISTANCE: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{"Distance",
+ float3::distance};
+ return fn;
+ }
+ case NODE_VECTOR_MATH_LENGTH: {
+ static blender::fn::CustomMF_SI_SO<float3, float> fn{"Length",
+ [](float3 a) { return a.length(); }};
+ return fn;
+ }
+ case NODE_VECTOR_MATH_SCALE: {
+ static blender::fn::CustomMF_SI_SI_SO<float3, float, float3> fn{
+ "Scale", [](float3 a, float factor) { return a * factor; }};
+ return fn;
+ }
+ case NODE_VECTOR_MATH_NORMALIZE: {
+ static blender::fn::CustomMF_SI_SO<float3, float3> fn{
+ "Normalize", [](float3 a) { return a.normalized(); }};
+ return fn;
+ }
+
+ case NODE_VECTOR_MATH_SNAP: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_FLOOR: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_CEIL: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_MODULO: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_FRACTION: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_ABSOLUTE: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_MINIMUM: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_MAXIMUM: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_WRAP: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_SINE: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_COSINE: {
+ return builder.get_not_implemented_fn();
+ }
+ case NODE_VECTOR_MATH_TANGENT: {
+ return builder.get_not_implemented_fn();
+ }
+
+ default:
+ BLI_assert(false);
+ return builder.get_not_implemented_fn();
+ };
+}
+
+static void sh_node_vector_math_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ const blender::fn::MultiFunction &fn = get_multi_function(builder);
+ builder.set_matching_fn(fn);
+}
+
+void register_node_type_sh_vect_math(void)
+{
+ static bNodeType ntype;
+
+ sh_fn_node_type_base(&ntype, SH_NODE_VECTOR_MATH, "Vector Math", NODE_CLASS_OP_VECTOR, 0);
+ node_type_socket_templates(&ntype, sh_node_vector_math_in, sh_node_vector_math_out);
+ node_type_label(&ntype, node_vector_math_label);
+ node_type_gpu(&ntype, gpu_shader_vector_math);
+ node_type_update(&ntype, node_shader_update_vector_math);
+ ntype.expand_in_mf_network = sh_node_vector_math_expand_in_mf_network;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
index 70c924a7f85..40576b68dd5 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.c
@@ -39,6 +39,10 @@ static int node_shader_gpu_vertex_color(GPUMaterial *mat,
GPUNodeStack *out)
{
NodeShaderVertexColor *vertexColor = (NodeShaderVertexColor *)node->storage;
+ if (U.experimental.use_sculpt_vertex_colors) {
+ GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_PROP_COLOR, vertexColor->layer_name);
+ return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
+ }
GPUNodeLink *vertexColorLink = GPU_attribute(mat, CD_MCOL, vertexColor->layer_name);
return GPU_stack_link(mat, node, "node_vertex_color", in, out, vertexColorLink);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_wireframe.c b/source/blender/nodes/shader/nodes/node_shader_wireframe.c
index e1da1cd34e4..d1ed13e1ffd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_wireframe.c
+++ b/source/blender/nodes/shader/nodes/node_shader_wireframe.c
@@ -36,6 +36,7 @@ static int node_shader_gpu_wireframe(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
+ GPU_material_flag_set(mat, GPU_MATFLAG_BARYCENTRIC);
/* node->custom1 is use_pixel_size */
if (node->custom1) {
return GPU_stack_link(
diff --git a/source/blender/nodes/simulation/node_simulation_util.h b/source/blender/nodes/simulation/node_simulation_util.h
index adbe2ad5e8f..76a10715cff 100644
--- a/source/blender/nodes/simulation/node_simulation_util.h
+++ b/source/blender/nodes/simulation/node_simulation_util.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __NODE_SIM_UTIL_H__
-#define __NODE_SIM_UTIL_H__
+#pragma once
#include <string.h>
@@ -36,5 +35,3 @@
void sim_node_type_base(
struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
bool sim_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
-
-#endif /* __NODE_SIM_UTIL_H__ */
diff --git a/source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc b/source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc
new file mode 100644
index 00000000000..add8c4eba4d
--- /dev/null
+++ b/source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_simulation_util.h"
+
+static bNodeSocketTemplate sim_node_age_reached_event_in[] = {
+ {SOCK_FLOAT, N_("Age"), 3, 0, 0, 0, 0, 10000000},
+ {SOCK_CONTROL_FLOW, N_("Execute")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate sim_node_age_reached_event_out[] = {
+ {SOCK_EVENTS, N_("Event")},
+ {-1, ""},
+};
+
+void register_node_type_sim_age_reached_event()
+{
+ static bNodeType ntype;
+
+ sim_node_type_base(&ntype, SIM_NODE_AGE_REACHED_EVENT, "Age Reached Event", 0, 0);
+ node_type_socket_templates(
+ &ntype, sim_node_age_reached_event_in, sim_node_age_reached_event_out);
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc b/source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc
new file mode 100644
index 00000000000..793b40d9365
--- /dev/null
+++ b/source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc
@@ -0,0 +1,36 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_simulation_util.h"
+
+static bNodeSocketTemplate sim_node_kill_particle_in[] = {
+ {SOCK_CONTROL_FLOW, N_("Execute")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate sim_node_kill_particle_out[] = {
+ {SOCK_CONTROL_FLOW, N_("Execute")},
+ {-1, ""},
+};
+
+void register_node_type_sim_kill_particle()
+{
+ static bNodeType ntype;
+
+ sim_node_type_base(&ntype, SIM_NODE_KILL_PARTICLE, "Kill Particle", 0, 0);
+ node_type_socket_templates(&ntype, sim_node_kill_particle_in, sim_node_kill_particle_out);
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc
index 2de7be2d3eb..5e1a6c35d52 100644
--- a/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc
+++ b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc
@@ -20,7 +20,8 @@
static bNodeSocketTemplate sim_node_particle_mesh_emitter_in[] = {
{SOCK_OBJECT, N_("Object")},
- {SOCK_FLOAT, N_("Rate"), 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {SOCK_FLOAT, N_("Rate"), 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {SOCK_CONTROL_FLOW, N_("Execute")},
{-1, ""},
};
diff --git a/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc b/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc
index 8696dbe340c..8f5c6818cb4 100644
--- a/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc
+++ b/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc
@@ -18,6 +18,7 @@
#include "node_simulation_util.h"
static bNodeSocketTemplate sim_node_set_particle_attribute_in[] = {
+ {SOCK_CONTROL_FLOW, N_("Execute")},
{SOCK_STRING, N_("Name")},
{SOCK_FLOAT, N_("Float"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
{SOCK_INT, N_("Int"), 0, 0, 0, 0, -10000, 10000},
@@ -38,7 +39,7 @@ static void sim_node_set_particle_attribute_update(bNodeTree *UNUSED(ntree), bNo
{
int index = 0;
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
- if (index >= 1) {
+ if (index >= 2) {
nodeSetSocketAvailability(sock, sock->type == node->custom1);
}
index++;
diff --git a/source/blender/nodes/texture/node_texture_util.h b/source/blender/nodes/texture/node_texture_util.h
index 7b8581c1f89..17a88ddaf5b 100644
--- a/source/blender/nodes/texture/node_texture_util.h
+++ b/source/blender/nodes/texture/node_texture_util.h
@@ -21,8 +21,7 @@
* \ingroup nodes
*/
-#ifndef __NODE_TEXTURE_UTIL_H__
-#define __NODE_TEXTURE_UTIL_H__
+#pragma once
#include <math.h>
#include <string.h>
@@ -131,5 +130,3 @@ void params_from_cdata(TexParams *out, TexCallData *in);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/nodes/texture/nodes/node_texture_curves.c b/source/blender/nodes/texture/nodes/node_texture_curves.c
index d42985ba041..70f7e731720 100644
--- a/source/blender/nodes/texture/nodes/node_texture_curves.c
+++ b/source/blender/nodes/texture/nodes/node_texture_curves.c
@@ -39,7 +39,7 @@ static void time_colorfn(
fac = (p->cfra - node->custom1) / (float)(node->custom2 - node->custom1);
}
- BKE_curvemapping_initialize(node->storage);
+ BKE_curvemapping_init(node->storage);
fac = BKE_curvemapping_evaluateF(node->storage, 0, fac);
out[0] = CLAMPIS(fac, 0.0f, 1.0f);
}
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 18d4c7da534..7bcf96116b9 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -18,9 +18,9 @@
* \ingroup python
*/
-#ifndef __BPY_EXTERN_H__
-#define __BPY_EXTERN_H__
+#pragma once
+struct AnimationEvalContext;
struct ChannelDriver; /* DNA_anim_types.h */
struct ID; /* DNA_ID.h */
struct ListBase; /* DNA_listBase.h */
@@ -54,6 +54,7 @@ void BPY_python_start(int argc, const char **argv);
void BPY_python_end(void);
void BPY_python_reset(struct bContext *C);
void BPY_python_use_system_env(void);
+void BPY_python_backtrace(/* FILE */ void *file);
/* global interpreter lock */
@@ -81,23 +82,23 @@ bool BPY_execute_text(struct bContext *C,
bool BPY_execute_string_as_number(struct bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
double *r_value);
bool BPY_execute_string_as_intptr(struct bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
intptr_t *r_value);
bool BPY_execute_string_as_string_and_size(struct bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
char **r_value,
size_t *r_value_size);
bool BPY_execute_string_as_string(struct bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
char **r_value);
bool BPY_execute_string_ex(struct bContext *C,
@@ -117,7 +118,7 @@ void BPY_driver_reset(void);
float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
struct ChannelDriver *driver,
struct ChannelDriver *driver_orig,
- const float evaltime);
+ const struct AnimationEvalContext *anim_eval_context);
void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr);
@@ -139,5 +140,3 @@ const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *ms
#ifdef __cplusplus
} /* extern "C" */
#endif
-
-#endif /* __BPY_EXTERN_H__ */
diff --git a/source/blender/python/BPY_extern_clog.h b/source/blender/python/BPY_extern_clog.h
index d610dc1c7ba..14b57b4cc5c 100644
--- a/source/blender/python/BPY_extern_clog.h
+++ b/source/blender/python/BPY_extern_clog.h
@@ -20,11 +20,8 @@
* Logging defines.
*/
-#ifndef __BPY_EXTERN_CLOG_H__
-#define __BPY_EXTERN_CLOG_H__
+#pragma once
/* bpy_interface.c */
extern struct CLG_LogRef *BPY_LOG_RNA;
extern struct CLG_LogRef *BPY_LOG_CONTEXT;
-
-#endif /* __BPY_EXTERN_CLOG_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_api.h b/source/blender/python/bmesh/bmesh_py_api.h
index 9f227b21440..357f416f266 100644
--- a/source/blender/python/bmesh/bmesh_py_api.h
+++ b/source/blender/python/bmesh/bmesh_py_api.h
@@ -21,9 +21,6 @@
* \ingroup pybmesh
*/
-#ifndef __BMESH_PY_API_H__
-#define __BMESH_PY_API_H__
+#pragma once
PyObject *BPyInit_bmesh(void);
-
-#endif /* __BMESH_PY_API_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_geometry.h b/source/blender/python/bmesh/bmesh_py_geometry.h
index 98d336828dc..dcb8c59f68b 100644
--- a/source/blender/python/bmesh/bmesh_py_geometry.h
+++ b/source/blender/python/bmesh/bmesh_py_geometry.h
@@ -21,9 +21,6 @@
* \ingroup pybmesh
*/
-#ifndef __BMESH_PY_GEOMETRY_H__
-#define __BMESH_PY_GEOMETRY_H__
+#pragma once
PyObject *BPyInit_bmesh_geometry(void);
-
-#endif /* __BMESH_PY_GEOMETRY_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_ops.h b/source/blender/python/bmesh/bmesh_py_ops.h
index a4a12bbef61..442af51fd17 100644
--- a/source/blender/python/bmesh/bmesh_py_ops.h
+++ b/source/blender/python/bmesh/bmesh_py_ops.h
@@ -21,9 +21,6 @@
* \ingroup pybmesh
*/
-#ifndef __BMESH_PY_OPS_H__
-#define __BMESH_PY_OPS_H__
+#pragma once
PyObject *BPyInit_bmesh_ops(void);
-
-#endif /* __BMESH_PY_OPS_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.h b/source/blender/python/bmesh/bmesh_py_ops_call.h
index 7b6611cd61d..6d9ceec73f6 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.h
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.h
@@ -21,8 +21,7 @@
* \ingroup pybmesh
*/
-#ifndef __BMESH_PY_OPS_CALL_H__
-#define __BMESH_PY_OPS_CALL_H__
+#pragma once
typedef struct {
PyObject_HEAD /* required python macro */
@@ -30,5 +29,3 @@ typedef struct {
} BPy_BMeshOpFunc;
PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw);
-
-#endif /* __BMESH_PY_OPS_CALL_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h
index 74bfbcec3c7..7ac3c4bf3cc 100644
--- a/source/blender/python/bmesh/bmesh_py_types.h
+++ b/source/blender/python/bmesh/bmesh_py_types.h
@@ -21,8 +21,7 @@
* \ingroup pybmesh
*/
-#ifndef __BMESH_PY_TYPES_H__
-#define __BMESH_PY_TYPES_H__
+#pragma once
extern PyTypeObject BPy_BMesh_Type;
extern PyTypeObject BPy_BMVert_Type;
@@ -228,5 +227,3 @@ extern struct PyC_FlagSet bpy_bm_htype_vert_edge_face_flags[];
extern struct PyC_FlagSet bpy_bm_htype_all_flags[];
extern struct PyC_FlagSet bpy_bm_hflag_all_flags[];
#endif
-
-#endif /* __BMESH_PY_TYPES_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.h b/source/blender/python/bmesh/bmesh_py_types_customdata.h
index 95836707e3d..3173813a912 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.h
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.h
@@ -21,8 +21,7 @@
* \ingroup pybmesh
*/
-#ifndef __BMESH_PY_TYPES_CUSTOMDATA_H__
-#define __BMESH_PY_TYPES_CUSTOMDATA_H__
+#pragma once
/* all use BPy_BMLayerAccess struct */
extern PyTypeObject BPy_BMLayerAccessVert_Type;
@@ -67,5 +66,3 @@ void BPy_BM_init_types_customdata(void);
/* __getitem__ / __setitem__ */
PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer);
int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObject *value);
-
-#endif /* __BMESH_PY_TYPES_CUSTOMDATA_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.h b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
index 5211c30ec7e..58f31a9807e 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.h
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
@@ -21,8 +21,7 @@
* \ingroup pybmesh
*/
-#ifndef __BMESH_PY_TYPES_MESHDATA_H__
-#define __BMESH_PY_TYPES_MESHDATA_H__
+#pragma once
extern PyTypeObject BPy_BMLoopUV_Type;
extern PyTypeObject BPy_BMDeformVert_Type;
@@ -51,5 +50,3 @@ int BPy_BMDeformVert_AssignPyObject(struct MDeformVert *dvert, PyObject *value);
PyObject *BPy_BMDeformVert_CreatePyObject(struct MDeformVert *dvert);
void BPy_BM_init_types_meshdata(void);
-
-#endif /* __BMESH_PY_TYPES_MESHDATA_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_types_select.h b/source/blender/python/bmesh/bmesh_py_types_select.h
index 593857a5083..c33aa3675c5 100644
--- a/source/blender/python/bmesh/bmesh_py_types_select.h
+++ b/source/blender/python/bmesh/bmesh_py_types_select.h
@@ -21,8 +21,7 @@
* \ingroup pybmesh
*/
-#ifndef __BMESH_PY_TYPES_SELECT_H__
-#define __BMESH_PY_TYPES_SELECT_H__
+#pragma once
struct BPy_BMesh;
@@ -46,5 +45,3 @@ void BPy_BM_init_types_select(void);
PyObject *BPy_BMEditSel_CreatePyObject(BMesh *bm);
PyObject *BPy_BMEditSelIter_CreatePyObject(BMesh *bm);
int BPy_BMEditSel_Assign(struct BPy_BMesh *self, PyObject *value);
-
-#endif /* __BMESH_PY_SELECT_H__ */
diff --git a/source/blender/python/bmesh/bmesh_py_utils.h b/source/blender/python/bmesh/bmesh_py_utils.h
index a6f4f22bf8b..27eccca4535 100644
--- a/source/blender/python/bmesh/bmesh_py_utils.h
+++ b/source/blender/python/bmesh/bmesh_py_utils.h
@@ -21,9 +21,6 @@
* \ingroup pybmesh
*/
-#ifndef __BMESH_PY_UTILS_H__
-#define __BMESH_PY_UTILS_H__
+#pragma once
PyObject *BPyInit_bmesh_utils(void);
-
-#endif /* __BMESH_PY_UTILS_H__ */
diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt
index 822f05bad90..785c1d66407 100644
--- a/source/blender/python/generic/CMakeLists.txt
+++ b/source/blender/python/generic/CMakeLists.txt
@@ -36,12 +36,14 @@ set(SRC
bpy_threads.c
idprop_py_api.c
imbuf_py_api.c
+ bl_math_py_api.c
py_capi_utils.c
bgl.h
blf_py_api.h
idprop_py_api.h
imbuf_py_api.h
+ bl_math_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 5471fc25f37..2ad2794c76f 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -487,7 +487,7 @@ static int gl_buffer_type_from_py_buffer(Py_buffer *pybuffer)
return -1; /* UNKNOWN */
}
-static bool compare_dimensions(int ndim, int *dim1, Py_ssize_t *dim2)
+static bool compare_dimensions(int ndim, const int *dim1, const Py_ssize_t *dim2)
{
for (int i = 0; i < ndim; i++) {
if (dim1[i] != dim2[i]) {
diff --git a/source/blender/python/generic/bgl.h b/source/blender/python/generic/bgl.h
index 8c81dc48340..ee8c293945a 100644
--- a/source/blender/python/generic/bgl.h
+++ b/source/blender/python/generic/bgl.h
@@ -18,8 +18,7 @@
* \ingroup pygen
*/
-#ifndef __BGL_H__
-#define __BGL_H__
+#pragma once
PyObject *BPyInit_bgl(void);
@@ -52,5 +51,3 @@ typedef struct _Buffer {
/** The type object */
extern PyTypeObject BGL_bufferType;
-
-#endif /* __BGL_H__ */
diff --git a/source/blender/python/generic/bl_math_py_api.c b/source/blender/python/generic/bl_math_py_api.c
new file mode 100644
index 00000000000..f17aaa4ca5d
--- /dev/null
+++ b/source/blender/python/generic/bl_math_py_api.c
@@ -0,0 +1,162 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * \file
+ * \ingroup pygen
+ *
+ * This file defines the 'bl_math' module, a module for math utilities.
+ */
+
+#include <Python.h>
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "py_capi_utils.h"
+
+#include "bl_math_py_api.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Module Doc String
+ * \{ */
+
+PyDoc_STRVAR(M_bl_math_doc, "Miscellaneous math utilities module");
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Python Functions
+ * \{ */
+
+PyDoc_STRVAR(py_bl_math_clamp_doc,
+ ".. function:: clamp(value, min=0, max=1)\n"
+ "\n"
+ " Clamps the float value between minimum and maximum. To avoid\n"
+ " confusion, any call must use either one or all three arguments.\n"
+ "\n"
+ " :arg value: The value to clamp.\n"
+ " :type value: float\n"
+ " :arg min: The minimum value, defaults to 0.\n"
+ " :type min: float\n"
+ " :arg max: The maximum value, defaults to 1.\n"
+ " :type max: float\n"
+ " :return: The clamped value.\n"
+ " :rtype: float\n");
+static PyObject *py_bl_math_clamp(PyObject *UNUSED(self), PyObject *args)
+{
+ double x, minv = 0.0, maxv = 1.0;
+
+ if (PyTuple_Size(args) <= 1) {
+ if (!PyArg_ParseTuple(args, "d:clamp", &x)) {
+ return NULL;
+ }
+ }
+ else {
+ if (!PyArg_ParseTuple(args, "ddd:clamp", &x, &minv, &maxv)) {
+ return NULL;
+ }
+ }
+
+ CLAMP(x, minv, maxv);
+
+ return PyFloat_FromDouble(x);
+}
+
+PyDoc_STRVAR(py_bl_math_lerp_doc,
+ ".. function:: lerp(from, to, factor)\n"
+ "\n"
+ " Linearly interpolate between two float values based on factor.\n"
+ "\n"
+ " :arg from: The value to return when factor is 0.\n"
+ " :type from: float\n"
+ " :arg to: The value to return when factor is 1.\n"
+ " :type to: float\n"
+ " :arg factor: The interpolation value, normally in [0.0, 1.0].\n"
+ " :type factor: float\n"
+ " :return: The interpolated value.\n"
+ " :rtype: float\n");
+static PyObject *py_bl_math_lerp(PyObject *UNUSED(self), PyObject *args)
+{
+ double a, b, x;
+ if (!PyArg_ParseTuple(args, "ddd:lerp", &a, &b, &x)) {
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(a * (1.0 - x) + b * x);
+}
+
+PyDoc_STRVAR(
+ py_bl_math_smoothstep_doc,
+ ".. function:: smoothstep(from, to, value)\n"
+ "\n"
+ " Performs smooth interpolation between 0 and 1 as value changes between from and to.\n"
+ " Outside the range the function returns the same value as the nearest edge.\n"
+ "\n"
+ " :arg from: The edge value where the result is 0.\n"
+ " :type from: float\n"
+ " :arg to: The edge value where the result is 1.\n"
+ " :type to: float\n"
+ " :arg factor: The interpolation value.\n"
+ " :type factor: float\n"
+ " :return: The interpolated value in [0.0, 1.0].\n"
+ " :rtype: float\n");
+static PyObject *py_bl_math_smoothstep(PyObject *UNUSED(self), PyObject *args)
+{
+ double a, b, x;
+ if (!PyArg_ParseTuple(args, "ddd:smoothstep", &a, &b, &x)) {
+ return NULL;
+ }
+
+ double t = (x - a) / (b - a);
+
+ CLAMP(t, 0.0, 1.0);
+
+ return PyFloat_FromDouble(t * t * (3.0 - 2.0 * t));
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Module Definition
+ * \{ */
+
+static PyMethodDef M_bl_math_methods[] = {
+ {"clamp", (PyCFunction)py_bl_math_clamp, METH_VARARGS, py_bl_math_clamp_doc},
+ {"lerp", (PyCFunction)py_bl_math_lerp, METH_VARARGS, py_bl_math_lerp_doc},
+ {"smoothstep", (PyCFunction)py_bl_math_smoothstep, METH_VARARGS, py_bl_math_smoothstep_doc},
+ {NULL, NULL, 0, NULL},
+};
+
+static struct PyModuleDef M_bl_math_module_def = {
+ PyModuleDef_HEAD_INIT,
+ "bl_math", /* m_name */
+ M_bl_math_doc, /* m_doc */
+ 0, /* m_size */
+ M_bl_math_methods, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+PyMODINIT_FUNC BPyInit_bl_math(void)
+{
+ PyObject *submodule = PyModule_Create(&M_bl_math_module_def);
+ return submodule;
+}
+
+/** \} */
diff --git a/source/blender/editors/include/ED_logic.h b/source/blender/python/generic/bl_math_py_api.h
index ae2d5038321..484304948f3 100644
--- a/source/blender/editors/include/ED_logic.h
+++ b/source/blender/python/generic/bl_math_py_api.h
@@ -12,27 +12,13 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
*/
-/** \file
- * \ingroup editors
+/**
+ * \file
+ * \ingroup pygen
*/
-#ifndef __ED_LOGIC_H__
-#define __ED_LOGIC_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* logic_ops.c */
-void ED_operatortypes_logic(void);
-
-#ifdef __cplusplus
-}
-#endif
+#pragma once
-#endif /* __ED_LOGIC_H__ */
+PyMODINIT_FUNC BPyInit_bl_math(void);
diff --git a/source/blender/python/generic/blf_py_api.h b/source/blender/python/generic/blf_py_api.h
index 919272df942..c47edd1eaab 100644
--- a/source/blender/python/generic/blf_py_api.h
+++ b/source/blender/python/generic/blf_py_api.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BLF_PY_API_H__
-#define __BLF_PY_API_H__
+#pragma once
/** \file
* \ingroup pygen
@@ -24,5 +23,3 @@
#include <Python.h>
PyObject *BPyInit_blf(void);
-
-#endif /* __BLF_PY_API_H__ */
diff --git a/source/blender/python/generic/idprop_py_api.h b/source/blender/python/generic/idprop_py_api.h
index 49094f95ecb..478dc99f73d 100644
--- a/source/blender/python/generic/idprop_py_api.h
+++ b/source/blender/python/generic/idprop_py_api.h
@@ -18,8 +18,7 @@
* \ingroup pygen
*/
-#ifndef __IDPROP_PY_API_H__
-#define __IDPROP_PY_API_H__
+#pragma once
struct BPy_IDGroup_Iter;
struct ID;
@@ -68,5 +67,3 @@ PyObject *BPyInit_idprop(void);
#define IDPROP_ITER_KEYS 0
#define IDPROP_ITER_ITEMS 1
-
-#endif /* __IDPROP_PY_API_H__ */
diff --git a/source/blender/python/generic/imbuf_py_api.h b/source/blender/python/generic/imbuf_py_api.h
index 2dea925a9f2..897423415b3 100644
--- a/source/blender/python/generic/imbuf_py_api.h
+++ b/source/blender/python/generic/imbuf_py_api.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __IMBUF_PY_API_H__
-#define __IMBUF_PY_API_H__
+#pragma once
/** \file
* \ingroup pygen
@@ -24,5 +23,3 @@
PyObject *BPyInit_imbuf(void);
extern PyTypeObject Py_ImBuf_Type;
-
-#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 9c84a4bb824..543cd3b4214 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -51,6 +51,10 @@
# include "BLI_math_base.h" /* isfinite() */
#endif
+/* -------------------------------------------------------------------- */
+/** \name Fast Python to C Array Conversion for Primitive Types
+ * \{ */
+
/* array utility function */
int PyC_AsArray_FAST(void *array,
PyObject *value_fast,
@@ -137,11 +141,12 @@ int PyC_AsArray(void *array,
return ret;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Typed Tuple Packing
*
* \note See #PyC_Tuple_Pack_* macros that take multiple arguments.
- *
* \{ */
/* array utility function */
@@ -192,6 +197,10 @@ PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Tuple/List Filling
+ * \{ */
+
/**
* Caller needs to ensure tuple is uninitialized.
* Handy for filling a tuple with None for eg.
@@ -218,6 +227,12 @@ void PyC_List_Fill(PyObject *list, PyObject *value)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Bool/Enum Argument Parsing
+ * \{ */
+
/**
* Use with PyArg_ParseTuple's "O&" formatting.
*
@@ -274,8 +289,16 @@ int PyC_CheckArgs_DeepCopy(PyObject *args)
return PyArg_ParseTuple(args, "|O!:__deepcopy__", &PyDict_Type, &dummy_pydict) != 0;
}
+/** \} */
+
#ifndef MATH_STANDALONE
+/* -------------------------------------------------------------------- */
+/** \name Simple Printing (for debugging)
+ *
+ * These are useful to run directly from a debugger to be able to inspect the state.
+ * \{ */
+
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var)
{
@@ -360,6 +383,26 @@ void PyC_StackSpit(void)
}
}
+void PyC_StackPrint(/* FILE */ void *fp)
+{
+ PyThreadState *tstate = PyGILState_GetThisThreadState();
+ if (tstate != NULL && tstate->frame != NULL) {
+ PyFrameObject *frame = tstate->frame;
+ do {
+ const int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
+ const char *filename = _PyUnicode_AsString(frame->f_code->co_filename);
+ const char *funcname = _PyUnicode_AsString(frame->f_code->co_name);
+ fprintf(fp, " File \"%s\", line %d in %s\n", filename, line, funcname);
+ } while ((frame = frame->f_back));
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Access Current Frame File Name & Line Number
+ * \{ */
+
void PyC_FileAndNum(const char **r_filename, int *r_lineno)
{
PyFrameObject *frame;
@@ -419,6 +462,12 @@ void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno)
PyC_FileAndNum(r_filename, r_lineno);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Object Access Utilities
+ * \{ */
+
/* Would be nice if python had this built in */
PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
{
@@ -447,6 +496,12 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
return item;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Frozen Set Creation
+ * \{ */
+
PyObject *PyC_FrozenSetFromStrings(const char **strings)
{
const char **str;
@@ -463,6 +518,12 @@ PyObject *PyC_FrozenSetFromStrings(const char **strings)
return ret;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exception Utilities
+ * \{ */
+
/**
* Similar to #PyErr_Format(),
*
@@ -528,6 +589,12 @@ void PyC_Err_PrintWithFunc(PyObject *py_func)
_PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exception Buffer Access
+ * \{ */
+
/* returns the exception string as a new PyUnicode object, depends on external traceback module */
# if 0
@@ -634,7 +701,7 @@ error_cleanup:
PyObject *PyC_ExceptionBuffer_Simple(void)
{
- PyObject *string_io_buf;
+ PyObject *string_io_buf = NULL;
PyObject *error_type, *error_value, *error_traceback;
@@ -648,7 +715,19 @@ PyObject *PyC_ExceptionBuffer_Simple(void)
return NULL;
}
- string_io_buf = PyObject_Str(error_value);
+ if (PyErr_GivenExceptionMatches(error_type, PyExc_SyntaxError)) {
+ /* Special exception for syntax errors,
+ * in these cases the full error is verbose and not very useful,
+ * just use the initial text so we know what the error is. */
+ if (PyTuple_CheckExact(error_value) && PyTuple_GET_SIZE(error_value) >= 1) {
+ string_io_buf = PyObject_Str(PyTuple_GET_ITEM(error_value, 0));
+ }
+ }
+
+ if (string_io_buf == NULL) {
+ string_io_buf = PyObject_Str(error_value);
+ }
+
/* Python does this too */
if (UNLIKELY(string_io_buf == NULL)) {
string_io_buf = PyUnicode_FromFormat("<unprintable %s object>", Py_TYPE(error_value)->tp_name);
@@ -661,6 +740,14 @@ PyObject *PyC_ExceptionBuffer_Simple(void)
return string_io_buf;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Unicode Conversion
+ *
+ * In some cases we need to coerce strings, avoid doing this inline.
+ * \{ */
+
/* string conversion, escape non-unicode chars, coerce must be set to NULL */
const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce)
{
@@ -739,6 +826,12 @@ PyObject *PyC_UnicodeFromByte(const char *str)
return PyC_UnicodeFromByteAndSize(str, strlen(str));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Name Space Creation/Manipulation
+ * \{ */
+
/*****************************************************************************
* Description: This function creates a new Python dictionary object.
* note: dict is owned by sys.modules["__main__"] module, reference is borrowed
@@ -804,8 +897,18 @@ void PyC_MainModule_Restore(PyObject *main_mod)
Py_XDECREF(main_mod);
}
-/* Must be called before Py_Initialize,
- * expects output of BKE_appdir_folder_id(BLENDER_PYTHON, NULL). */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #Py_SetPythonHome Wrapper
+ * \{ */
+
+/**
+ * - Must be called before #Py_Initialize.
+ * - Expects output of `BKE_appdir_folder_id(BLENDER_PYTHON, NULL)`.
+ * - Note that the `PYTHONPATH` environment variable isn't reliable, see T31506.
+ Use #Py_SetPythonHome instead.
+ */
void PyC_SetHomePath(const char *py_path_bundle)
{
if (py_path_bundle == NULL) {
@@ -824,24 +927,14 @@ void PyC_SetHomePath(const char *py_path_bundle)
/* OSX allow file/directory names to contain : character (represented as / in the Finder)
* but current Python lib (release 3.1.1) doesn't handle these correctly */
if (strchr(py_path_bundle, ':')) {
- printf(
- "Warning : Blender application is located in a path containing : or / chars\
- \nThis may make python import function fail\n");
- }
-# endif
-
-# if 0 /* disable for now [#31506] - campbell */
-# ifdef _WIN32
- /* cmake/MSVC debug build crashes without this, why only
- * in this case is unknown.. */
- {
- /*BLI_setenv("PYTHONPATH", py_path_bundle)*/;
+ fprintf(stderr,
+ "Warning! Blender application is located in a path containing ':' or '/' chars\n"
+ "This may make python import function fail\n");
}
-# endif
# endif
{
- static wchar_t py_path_bundle_wchar[1024];
+ wchar_t py_path_bundle_wchar[1024];
/* Can't use this, on linux gives bug: #23018,
* TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 2008 */
@@ -861,6 +954,12 @@ bool PyC_IsInterpreterActive(void)
return (PyThreadState_GetDict() != NULL);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #Py_SetPythonHome Wrapper
+ * \{ */
+
/* Would be nice if python had this built in
* See: https://wiki.blender.org/wiki/Tools/Debugging/PyFromC
*/
@@ -1046,6 +1145,14 @@ void *PyC_RNA_AsPointer(PyObject *value, const char *type_name)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Flag Set Utilities (#PyC_FlagSet)
+ *
+ * Convert to/from Python set of strings to an int flag.
+ * \{ */
+
PyObject *PyC_FlagSet_AsString(PyC_FlagSet *item)
{
PyObject *py_items = PyList_New(0);
@@ -1146,6 +1253,12 @@ PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
return ret;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Run String (Evaluate to Primitive Types)
+ * \{ */
+
/**
* \return success
*
@@ -1309,6 +1422,8 @@ bool PyC_RunString_AsString(const char *imports[],
return PyC_RunString_AsStringAndSize(imports, expr, filename, r_value, &value_size);
}
+/** \} */
+
#endif /* #ifndef MATH_STANDALONE */
/* -------------------------------------------------------------------- */
@@ -1396,6 +1511,12 @@ uint32_t PyC_Long_AsU32(PyObject *value)
* PyC_Long_AsU64
*/
+#ifdef __GNUC__
+# pragma warning(pop)
+#endif
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Py_buffer Utils
*
@@ -1472,9 +1593,3 @@ bool PyC_StructFmt_type_is_bool(char format)
}
/** \} */
-
-#ifdef __GNUC__
-# pragma warning(pop)
-#endif
-
-/** \} */
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index e8b2e8ff502..dde450012d0 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -28,6 +28,7 @@ void PyC_ObSpit(const char *name, PyObject *var);
void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var);
void PyC_LineSpit(void);
void PyC_StackSpit(void);
+void PyC_StackPrint(/* FILE */ void *fp);
PyObject *PyC_ExceptionBuffer(void);
PyObject *PyC_ExceptionBuffer_Simple(void);
PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
diff --git a/source/blender/python/generic/python_utildefines.h b/source/blender/python/generic/python_utildefines.h
index 653122c9c33..1f093e633e4 100644
--- a/source/blender/python/generic/python_utildefines.h
+++ b/source/blender/python/generic/python_utildefines.h
@@ -20,8 +20,7 @@
* \note light addition to Python.h, use py_capi_utils.h for larger features.
*/
-#ifndef __PYTHON_UTILDEFINES_H__
-#define __PYTHON_UTILDEFINES_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -57,5 +56,3 @@ Py_LOCAL_INLINE(int) PyList_APPEND(PyObject *op, PyObject *v)
#ifdef __cplusplus
}
#endif
-
-#endif /* __PYTHON_UTILDEFINES_H__ */
diff --git a/source/blender/python/gpu/gpu_py_api.c b/source/blender/python/gpu/gpu_py_api.c
index 1379c0e557a..da7674eb7f9 100644
--- a/source/blender/python/gpu/gpu_py_api.c
+++ b/source/blender/python/gpu/gpu_py_api.c
@@ -43,9 +43,9 @@
/** \name Utils to invalidate functions
* \{ */
-bool bpygpu_is_initialized_or_error(void)
+bool bpygpu_is_init_or_error(void)
{
- if (!GPU_is_initialized()) {
+ if (!GPU_is_init()) {
PyErr_SetString(PyExc_SystemError,
"GPU functions for drawing are not available in background mode");
diff --git a/source/blender/python/gpu/gpu_py_api.h b/source/blender/python/gpu/gpu_py_api.h
index e278bb63a49..b8f0cde129f 100644
--- a/source/blender/python/gpu/gpu_py_api.h
+++ b/source/blender/python/gpu/gpu_py_api.h
@@ -18,23 +18,20 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_API_H__
-#define __GPU_PY_API_H__
+#pragma once
int bpygpu_ParsePrimType(PyObject *o, void *p);
PyObject *BPyInit_gpu(void);
-bool bpygpu_is_initialized_or_error(void);
+bool bpygpu_is_init_or_error(void);
#define BPYGPU_IS_INIT_OR_ERROR_OBJ \
- if (UNLIKELY(!bpygpu_is_initialized_or_error())) { \
+ if (UNLIKELY(!bpygpu_is_init_or_error())) { \
return NULL; \
} \
((void)0)
#define BPYGPU_IS_INIT_OR_ERROR_INT \
- if (UNLIKELY(!bpygpu_is_initialized_or_error())) { \
+ if (UNLIKELY(!bpygpu_is_init_or_error())) { \
return -1; \
} \
((void)0)
-
-#endif /* __GPU_PY_API_H__ */
diff --git a/source/blender/python/gpu/gpu_py_batch.c b/source/blender/python/gpu/gpu_py_batch.c
index b3df991cf12..f9fe1654db0 100644
--- a/source/blender/python/gpu/gpu_py_batch.c
+++ b/source/blender/python/gpu/gpu_py_batch.c
@@ -184,8 +184,7 @@ static PyObject *bpygpu_Batch_program_set(BPyGPUBatch *self, BPyGPUShader *py_sh
}
GPUShader *shader = py_shader->shader;
- GPU_batch_program_set(
- self->batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
+ GPU_batch_set_shader(self->batch, shader);
#ifdef USE_GPU_PY_REFERENCES
/* Remove existing user (if any), hold new user. */
@@ -229,9 +228,7 @@ static PyObject *bpygpu_Batch_draw(BPyGPUBatch *self, PyObject *args)
}
}
else if (self->batch->program != GPU_shader_get_program(py_program->shader)) {
- GPU_batch_program_set(self->batch,
- GPU_shader_get_program(py_program->shader),
- GPU_shader_get_interface(py_program->shader));
+ GPU_batch_set_shader(self->batch, py_program->shader);
}
GPU_batch_draw(self->batch);
diff --git a/source/blender/python/gpu/gpu_py_batch.h b/source/blender/python/gpu/gpu_py_batch.h
index 1e916afcc2e..7c882eab8fc 100644
--- a/source/blender/python/gpu/gpu_py_batch.h
+++ b/source/blender/python/gpu/gpu_py_batch.h
@@ -18,8 +18,7 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_BATCH_H__
-#define __GPU_PY_BATCH_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -40,5 +39,3 @@ typedef struct BPyGPUBatch {
} BPyGPUBatch;
PyObject *BPyGPUBatch_CreatePyObject(struct GPUBatch *batch) ATTR_NONNULL(1);
-
-#endif /* __GPU_PY_BATCH_H__ */
diff --git a/source/blender/python/gpu/gpu_py_element.h b/source/blender/python/gpu/gpu_py_element.h
index 055c9d54ecf..a8e22aae15a 100644
--- a/source/blender/python/gpu/gpu_py_element.h
+++ b/source/blender/python/gpu/gpu_py_element.h
@@ -18,8 +18,7 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_ELEMENT_H__
-#define __GPU_PY_ELEMENT_H__
+#pragma once
extern PyTypeObject BPyGPUIndexBuf_Type;
@@ -30,5 +29,3 @@ typedef struct BPyGPUIndexBuf {
} BPyGPUIndexBuf;
PyObject *BPyGPUIndexBuf_CreatePyObject(struct GPUIndexBuf *elem);
-
-#endif /* __GPU_PY_ELEMENT_H__ */
diff --git a/source/blender/python/gpu/gpu_py_matrix.h b/source/blender/python/gpu/gpu_py_matrix.h
index cf187dee002..38a7f398b30 100644
--- a/source/blender/python/gpu/gpu_py_matrix.h
+++ b/source/blender/python/gpu/gpu_py_matrix.h
@@ -18,9 +18,6 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_MATRIX_H__
-#define __GPU_PY_MATRIX_H__
+#pragma once
PyObject *BPyInit_gpu_matrix(void);
-
-#endif /* __GPU_PY_MATRIX_H__ */
diff --git a/source/blender/python/gpu/gpu_py_offscreen.h b/source/blender/python/gpu/gpu_py_offscreen.h
index 61d7bd82abc..efe5b57b22e 100644
--- a/source/blender/python/gpu/gpu_py_offscreen.h
+++ b/source/blender/python/gpu/gpu_py_offscreen.h
@@ -18,8 +18,7 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_OFFSCREEN_H__
-#define __GPU_PY_OFFSCREEN_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -33,5 +32,3 @@ typedef struct BPyGPUOffScreen {
} BPyGPUOffScreen;
PyObject *BPyGPUOffScreen_CreatePyObject(struct GPUOffScreen *ofs) ATTR_NONNULL(1);
-
-#endif /* __GPU_PY_OFFSCREEN_H__ */
diff --git a/source/blender/python/gpu/gpu_py_select.h b/source/blender/python/gpu/gpu_py_select.h
index 814b6028da1..857cd7bb7f8 100644
--- a/source/blender/python/gpu/gpu_py_select.h
+++ b/source/blender/python/gpu/gpu_py_select.h
@@ -18,9 +18,6 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_SELECT_H__
-#define __GPU_PY_SELECT_H__
+#pragma once
PyObject *BPyInit_gpu_select(void);
-
-#endif /* __GPU_PY_SELECT_H__ */
diff --git a/source/blender/python/gpu/gpu_py_shader.h b/source/blender/python/gpu/gpu_py_shader.h
index 92873753039..ee26c26acd4 100644
--- a/source/blender/python/gpu/gpu_py_shader.h
+++ b/source/blender/python/gpu/gpu_py_shader.h
@@ -18,8 +18,7 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_SHADER_H__
-#define __GPU_PY_SHADER_H__
+#pragma once
extern PyTypeObject BPyGPUShader_Type;
@@ -32,5 +31,3 @@ typedef struct BPyGPUShader {
PyObject *BPyGPUShader_CreatePyObject(struct GPUShader *shader, bool is_builtin);
PyObject *BPyInit_gpu_shader(void);
-
-#endif /* __GPU_PY_SHADER_H__ */
diff --git a/source/blender/python/gpu/gpu_py_types.h b/source/blender/python/gpu/gpu_py_types.h
index d8048225604..56f73b8a504 100644
--- a/source/blender/python/gpu/gpu_py_types.h
+++ b/source/blender/python/gpu/gpu_py_types.h
@@ -18,8 +18,7 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_TYPES_H__
-#define __GPU_PY_TYPES_H__
+#pragma once
#include "gpu_py_batch.h"
#include "gpu_py_element.h"
@@ -29,5 +28,3 @@
#include "gpu_py_vertex_format.h"
PyObject *BPyInit_gpu_types(void);
-
-#endif /* __GPU_PY_TYPES_H__ */
diff --git a/source/blender/python/gpu/gpu_py_vertex_buffer.h b/source/blender/python/gpu/gpu_py_vertex_buffer.h
index b7124d245a9..41791a35e6e 100644
--- a/source/blender/python/gpu/gpu_py_vertex_buffer.h
+++ b/source/blender/python/gpu/gpu_py_vertex_buffer.h
@@ -18,8 +18,7 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_VERTEX_BUFFER_H__
-#define __GPU_PY_VERTEX_BUFFER_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -34,5 +33,3 @@ typedef struct BPyGPUVertBuf {
} BPyGPUVertBuf;
PyObject *BPyGPUVertBuf_CreatePyObject(struct GPUVertBuf *vbo) ATTR_NONNULL(1);
-
-#endif /* __GPU_PY_VERTEX_BUFFER_H__ */
diff --git a/source/blender/python/gpu/gpu_py_vertex_format.h b/source/blender/python/gpu/gpu_py_vertex_format.h
index 8ef466aa918..54d090e2923 100644
--- a/source/blender/python/gpu/gpu_py_vertex_format.h
+++ b/source/blender/python/gpu/gpu_py_vertex_format.h
@@ -18,8 +18,7 @@
* \ingroup bpygpu
*/
-#ifndef __GPU_PY_VERTEX_FORMAT_H__
-#define __GPU_PY_VERTEX_FORMAT_H__
+#pragma once
#include "GPU_vertex_format.h"
@@ -32,5 +31,3 @@ typedef struct BPyGPUVertFormat {
} BPyGPUVertFormat;
PyObject *BPyGPUVertFormat_CreatePyObject(struct GPUVertFormat *fmt);
-
-#endif /* __GPU_PY_VERTEX_FORMAT_H__ */
diff --git a/source/blender/python/intern/bpy.h b/source/blender/python/intern/bpy.h
index 88d1db6f8bc..744bf903443 100644
--- a/source/blender/python/intern/bpy.h
+++ b/source/blender/python/intern/bpy.h
@@ -18,8 +18,11 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_H__
-#define __BPY_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
void BPy_init_modules(void);
extern PyObject *bpy_package_py;
@@ -31,4 +34,6 @@ void BPY_atexit_unregister(void);
extern struct CLG_LogRef *BPY_LOG_CONTEXT;
extern struct CLG_LogRef *BPY_LOG_RNA;
-#endif /* __BPY_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index 957d49eb04e..4ee936aff91 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -50,7 +50,6 @@
#include "BKE_appdir.h"
#include "BKE_blender_version.h"
#include "BKE_global.h"
-#include "BKE_lib_override.h"
#include "DNA_ID.h"
@@ -392,29 +391,6 @@ static PyObject *bpy_app_autoexec_fail_message_get(PyObject *UNUSED(self), void
return PyC_UnicodeFromByte(G.autoexec_fail);
}
-PyDoc_STRVAR(bpy_app_use_override_library_doc,
- "Boolean, whether library override is exposed in UI or not.");
-static PyObject *bpy_app_use_override_library_get(PyObject *UNUSED(self), void *UNUSED(closure))
-{
- return PyBool_FromLong((long)BKE_lib_override_library_is_enabled());
-}
-
-static int bpy_app_use_override_library_set(PyObject *UNUSED(self),
- PyObject *value,
- void *UNUSED(closure))
-{
- const int param = PyC_Long_AsBool(value);
-
- if (param == -1 && PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError, "bpy.app.use_override_library must be a boolean");
- return -1;
- }
-
- BKE_lib_override_library_enable((const bool)param);
-
- return 0;
-}
-
static PyGetSetDef bpy_app_getsets[] = {
{"debug", bpy_app_debug_get, bpy_app_debug_set, bpy_app_debug_doc, (void *)G_DEBUG},
{"debug_ffmpeg",
@@ -485,11 +461,6 @@ static PyGetSetDef bpy_app_getsets[] = {
(void *)G_DEBUG_GPU_MEM},
{"debug_io", bpy_app_debug_get, bpy_app_debug_set, bpy_app_debug_doc, (void *)G_DEBUG_IO},
- {"use_override_library",
- bpy_app_use_override_library_get,
- bpy_app_use_override_library_set,
- bpy_app_use_override_library_doc,
- NULL},
{"use_event_simulate",
bpy_app_global_flag_get,
bpy_app_global_flag_set__only_disable,
diff --git a/source/blender/python/intern/bpy_app.h b/source/blender/python/intern/bpy_app.h
index b46de025599..0e5b6747543 100644
--- a/source/blender/python/intern/bpy_app.h
+++ b/source/blender/python/intern/bpy_app.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_H__
-#define __BPY_APP_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_struct(void);
-#endif /* __BPY_APP_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_alembic.h b/source/blender/python/intern/bpy_app_alembic.h
index 4cc890ec64d..4288b556172 100644
--- a/source/blender/python/intern/bpy_app_alembic.h
+++ b/source/blender/python/intern/bpy_app_alembic.h
@@ -21,9 +21,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_ALEMBIC_H__
-#define __BPY_APP_ALEMBIC_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_alembic_struct(void);
-#endif /* __BPY_APP_ALEMBIC_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_build_options.h b/source/blender/python/intern/bpy_app_build_options.h
index 52c2e57c12a..390e3409fb8 100644
--- a/source/blender/python/intern/bpy_app_build_options.h
+++ b/source/blender/python/intern/bpy_app_build_options.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_BUILD_OPTIONS_H__
-#define __BPY_APP_BUILD_OPTIONS_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_build_options_struct(void);
-#endif /* __BPY_APP_BUILD_OPTIONS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_ffmpeg.h b/source/blender/python/intern/bpy_app_ffmpeg.h
index 63fff2b1b4b..b189592e03e 100644
--- a/source/blender/python/intern/bpy_app_ffmpeg.h
+++ b/source/blender/python/intern/bpy_app_ffmpeg.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_FFMPEG_H__
-#define __BPY_APP_FFMPEG_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_ffmpeg_struct(void);
-#endif /* __BPY_APP_FFMPEG_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_handlers.h b/source/blender/python/intern/bpy_app_handlers.h
index 426fe376b55..eb8e85fc96e 100644
--- a/source/blender/python/intern/bpy_app_handlers.h
+++ b/source/blender/python/intern/bpy_app_handlers.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_HANDLERS_H__
-#define __BPY_APP_HANDLERS_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_handlers_struct(void);
-#endif /* __BPY_APP_HANDLERS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_icons.h b/source/blender/python/intern/bpy_app_icons.h
index 2d7cb96aae7..b0dcbe4b0ea 100644
--- a/source/blender/python/intern/bpy_app_icons.h
+++ b/source/blender/python/intern/bpy_app_icons.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_ICONS_H__
-#define __BPY_APP_ICONS_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_icons_module(void);
-#endif /* __BPY_APP_ICONS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_ocio.h b/source/blender/python/intern/bpy_app_ocio.h
index 66fc03657c1..bc4529a962c 100644
--- a/source/blender/python/intern/bpy_app_ocio.h
+++ b/source/blender/python/intern/bpy_app_ocio.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_OCIO_H__
-#define __BPY_APP_OCIO_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_ocio_struct(void);
-#endif /* __BPY_APP_OCIO_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_oiio.h b/source/blender/python/intern/bpy_app_oiio.h
index 4b08652dff5..47092899eec 100644
--- a/source/blender/python/intern/bpy_app_oiio.h
+++ b/source/blender/python/intern/bpy_app_oiio.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_OIIO_H__
-#define __BPY_APP_OIIO_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_oiio_struct(void);
-#endif /* __BPY_APP_OIIO_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_opensubdiv.h b/source/blender/python/intern/bpy_app_opensubdiv.h
index f04fa6fb44d..e18c827e6d8 100644
--- a/source/blender/python/intern/bpy_app_opensubdiv.h
+++ b/source/blender/python/intern/bpy_app_opensubdiv.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_OPENSUBDIV_H__
-#define __BPY_APP_OPENSUBDIV_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_opensubdiv_struct(void);
-#endif /* __BPY_APP_OPENSUBDIV_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_openvdb.h b/source/blender/python/intern/bpy_app_openvdb.h
index 333d79142f7..ab73d561412 100644
--- a/source/blender/python/intern/bpy_app_openvdb.h
+++ b/source/blender/python/intern/bpy_app_openvdb.h
@@ -21,9 +21,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_OPENVDB_H__
-#define __BPY_APP_OPENVDB_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_openvdb_struct(void);
-#endif /* __BPY_APP_OPENVDB_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_sdl.h b/source/blender/python/intern/bpy_app_sdl.h
index 453c1c0c1a3..b1d349c2a59 100644
--- a/source/blender/python/intern/bpy_app_sdl.h
+++ b/source/blender/python/intern/bpy_app_sdl.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_SDL_H__
-#define __BPY_APP_SDL_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_sdl_struct(void);
-#endif /* __BPY_APP_SDL_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_timers.h b/source/blender/python/intern/bpy_app_timers.h
index bc70e85ae12..9e62541c83a 100644
--- a/source/blender/python/intern/bpy_app_timers.h
+++ b/source/blender/python/intern/bpy_app_timers.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_TIMERS_H__
-#define __BPY_APP_TIMERS_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_timers_module(void);
-#endif /* __BPY_APP_TIMERS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
index 190d4eb1855..c152c920453 100644
--- a/source/blender/python/intern/bpy_app_translations.c
+++ b/source/blender/python/intern/bpy_app_translations.c
@@ -566,7 +566,7 @@ static PyObject *_py_pgettext(PyObject *args,
PyDoc_STRVAR(
app_translations_pgettext_doc,
- ".. method:: pgettext(msgid, msgctxt)\n"
+ ".. method:: pgettext(msgid, msgctxt=None)\n"
"\n"
" Try to translate the given msgid (with optional msgctxt).\n"
"\n"
@@ -600,7 +600,7 @@ static PyObject *app_translations_pgettext(BlenderAppTranslations *UNUSED(self),
}
PyDoc_STRVAR(app_translations_pgettext_iface_doc,
- ".. method:: pgettext_iface(msgid, msgctxt)\n"
+ ".. method:: pgettext_iface(msgid, msgctxt=None)\n"
"\n"
" Try to translate the given msgid (with optional msgctxt), if labels' translation "
"is enabled.\n"
@@ -622,7 +622,7 @@ static PyObject *app_translations_pgettext_iface(BlenderAppTranslations *UNUSED(
}
PyDoc_STRVAR(app_translations_pgettext_tip_doc,
- ".. method:: pgettext_tip(msgid, msgctxt)\n"
+ ".. method:: pgettext_tip(msgid, msgctxt=None)\n"
"\n"
" Try to translate the given msgid (with optional msgctxt), if tooltips' "
"translation is enabled.\n"
@@ -644,7 +644,7 @@ static PyObject *app_translations_pgettext_tip(BlenderAppTranslations *UNUSED(se
}
PyDoc_STRVAR(app_translations_pgettext_data_doc,
- ".. method:: pgettext_data(msgid, msgctxt)\n"
+ ".. method:: pgettext_data(msgid, msgctxt=None)\n"
"\n"
" Try to translate the given msgid (with optional msgctxt), if new data name's "
"translation is enabled.\n"
diff --git a/source/blender/python/intern/bpy_app_translations.h b/source/blender/python/intern/bpy_app_translations.h
index e1e82480b49..090cab5917c 100644
--- a/source/blender/python/intern/bpy_app_translations.h
+++ b/source/blender/python/intern/bpy_app_translations.h
@@ -18,10 +18,15 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_TRANSLATIONS_H__
-#define __BPY_APP_TRANSLATIONS_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_translations_struct(void);
void BPY_app_translations_end(void);
-#endif /* __BPY_APP_TRANSLATIONS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_app_usd.h b/source/blender/python/intern/bpy_app_usd.h
index e3e1d72b366..2801408c2aa 100644
--- a/source/blender/python/intern/bpy_app_usd.h
+++ b/source/blender/python/intern/bpy_app_usd.h
@@ -21,9 +21,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_APP_USD_H__
-#define __BPY_APP_USD_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_app_usd_struct(void);
-#endif /* __BPY_APP_USD_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_capi_utils.c b/source/blender/python/intern/bpy_capi_utils.c
index 89ef2f40a30..27eea80f1f6 100644
--- a/source/blender/python/intern/bpy_capi_utils.c
+++ b/source/blender/python/intern/bpy_capi_utils.c
@@ -97,7 +97,10 @@ void BPy_reports_write_stdout(const ReportList *reports, const char *header)
}
}
-bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const bool use_location)
+bool BPy_errors_to_report_ex(ReportList *reports,
+ const char *error_prefix,
+ const bool use_full,
+ const bool use_location)
{
PyObject *pystring;
@@ -124,40 +127,38 @@ bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const boo
return 0;
}
+ if (error_prefix == NULL) {
+ /* Not very helpful, better than nothing. */
+ error_prefix = "Python";
+ }
+
if (use_location) {
const char *filename;
int lineno;
- PyObject *pystring_format; /* workaround, see below */
- const char *cstring;
-
PyC_FileAndNum(&filename, &lineno);
if (filename == NULL) {
filename = "<unknown location>";
}
-#if 0 /* ARG!. workaround for a bug in blenders use of vsnprintf */
BKE_reportf(reports,
RPT_ERROR,
- "%s\nlocation: %s:%d\n",
+ TIP_("%s: %s\nlocation: %s:%d\n"),
+ error_prefix,
_PyUnicode_AsString(pystring),
filename,
lineno);
-#else
- pystring_format = PyUnicode_FromFormat(
- TIP_("%s\nlocation: %s:%d\n"), _PyUnicode_AsString(pystring), filename, lineno);
-
- cstring = _PyUnicode_AsString(pystring_format);
- BKE_report(reports, RPT_ERROR, cstring);
-
- /* not exactly needed. just for testing */
- fprintf(stderr, TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
- Py_DECREF(pystring_format); /* workaround */
-#endif
+ /* Not exactly needed. Useful for developers tracking down issues. */
+ fprintf(stderr,
+ TIP_("%s: %s\nlocation: %s:%d\n"),
+ error_prefix,
+ _PyUnicode_AsString(pystring),
+ filename,
+ lineno);
}
else {
- BKE_report(reports, RPT_ERROR, _PyUnicode_AsString(pystring));
+ BKE_reportf(reports, RPT_ERROR, "%s: %s", error_prefix, _PyUnicode_AsString(pystring));
}
Py_DECREF(pystring);
@@ -166,5 +167,5 @@ bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const boo
bool BPy_errors_to_report(ReportList *reports)
{
- return BPy_errors_to_report_ex(reports, true, true);
+ return BPy_errors_to_report_ex(reports, NULL, true, true);
}
diff --git a/source/blender/python/intern/bpy_capi_utils.h b/source/blender/python/intern/bpy_capi_utils.h
index fe086b61097..861b23190a2 100644
--- a/source/blender/python/intern/bpy_capi_utils.h
+++ b/source/blender/python/intern/bpy_capi_utils.h
@@ -18,13 +18,16 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_CAPI_UTILS_H__
-#define __BPY_CAPI_UTILS_H__
+#pragma once
#if PY_VERSION_HEX < 0x03070000
# error "Python 3.7 or greater is required, you'll need to update your Python."
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct EnumPropertyItem;
struct ReportList;
@@ -39,8 +42,10 @@ char *BPy_enum_as_string(const struct EnumPropertyItem *item);
short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear);
void BPy_reports_write_stdout(const struct ReportList *reports, const char *header);
bool BPy_errors_to_report_ex(struct ReportList *reports,
+ const char *error_prefix,
const bool use_full,
const bool use_location);
+bool BPy_errors_to_report_brief_with_prefix(struct ReportList *reports, const char *error_prefix);
bool BPy_errors_to_report(struct ReportList *reports);
/* TODO - find a better solution! */
@@ -48,6 +53,8 @@ struct bContext *BPy_GetContext(void);
void BPy_SetContext(struct bContext *C);
extern void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate);
-extern void bpy_context_clear(struct bContext *C, PyGILState_STATE *gilstate);
+extern void bpy_context_clear(struct bContext *C, const PyGILState_STATE *gilstate);
-#endif /* __BPY_CAPI_UTILS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 50ae05694eb..d48ad2b197c 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -33,19 +33,22 @@
#include "BLI_math_base.h"
#include "BLI_string.h"
+#include "BKE_animsys.h"
#include "BKE_fcurve_driver.h"
#include "BKE_global.h"
+#include "RNA_access.h"
+#include "RNA_types.h"
+
#include "bpy_rna_driver.h" /* for pyrna_driver_get_variable_value */
#include "bpy_intern_string.h"
#include "bpy_driver.h"
+#include "bpy_rna.h"
#include "BPY_extern.h"
-extern void BPY_update_rna_module(void);
-
#define USE_RNA_AS_PYOBJECT
#define USE_BYTECODE_WHITELIST
@@ -111,6 +114,19 @@ int bpy_pydriver_create_dict(void)
Py_DECREF(mod);
}
+ /* Add math utility functions. */
+ mod = PyImport_ImportModuleLevel("bl_math", NULL, NULL, NULL, 0);
+ if (mod) {
+ static const char *names[] = {"clamp", "lerp", "smoothstep", NULL};
+
+ for (const char **pname = names; *pname; ++pname) {
+ PyObject *func = PyDict_GetItemString(PyModule_GetDict(mod), *pname);
+ PyDict_SetItemString(bpy_pydriver_Dict, *pname, func);
+ }
+
+ Py_DECREF(mod);
+ }
+
#ifdef USE_BYTECODE_WHITELIST
/* setup the whitelist */
{
@@ -130,6 +146,10 @@ int bpy_pydriver_create_dict(void)
"bool",
"float",
"int",
+ /* bl_math */
+ "clamp",
+ "lerp",
+ "smoothstep",
NULL,
};
@@ -237,8 +257,6 @@ void BPY_driver_reset(void)
if (use_gil) {
PyGILState_Release(gilstate);
}
-
- return;
}
/* error return function for BPY_eval_pydriver */
@@ -379,17 +397,51 @@ static bool bpy_driver_secure_bytecode_validate(PyObject *expr_code, PyObject *d
#endif /* USE_BYTECODE_WHITELIST */
-/* This evals py driver expressions, 'expr' is a Python expression that
- * should evaluate to a float number, which is returned.
+static PyObject *bpy_pydriver_depsgraph_as_pyobject(struct Depsgraph *depsgraph)
+{
+ /* This should never happen, but it's probably better to have None in Python
+ * than a NULL-wrapping Depsgraph py struct. */
+ BLI_assert(depsgraph != NULL);
+ if (depsgraph == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ struct PointerRNA depsgraph_ptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, depsgraph, &depsgraph_ptr);
+ return pyrna_struct_CreatePyObject(&depsgraph_ptr);
+}
+
+/**
+ * Adds a variable 'depsgraph' to the driver variables. This can then be used to obtain evaluated
+ * data-blocks, and the current view layer and scene. See T75553.
+ */
+static void bpy_pydriver_namespace_add_depsgraph(PyObject *driver_vars,
+ struct Depsgraph *depsgraph)
+{
+ PyObject *py_depsgraph = bpy_pydriver_depsgraph_as_pyobject(depsgraph);
+ const char *depsgraph_variable_name = "depsgraph";
+
+ if (PyDict_SetItemString(driver_vars, depsgraph_variable_name, py_depsgraph) == -1) {
+ fprintf(stderr,
+ "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n",
+ depsgraph_variable_name);
+ PyErr_Print();
+ PyErr_Clear();
+ }
+}
+
+/**
+ * This evaluates Python driver expressions, `driver_orig->expression`
+ * is a Python expression that should evaluate to a float number, which is returned.
*
* (old)note: PyGILState_Ensure() isn't always called because python can call
* the bake operator which intern starts a thread which calls scene update
- * which does a driver update. to avoid a deadlock check PyC_IsInterpreterActive()
- * if PyGILState_Ensure() is needed - see [#27683]
+ * which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive()
+ * if #PyGILState_Ensure() is needed, see T27683.
*
- * (new)note: checking if python is running is not threadsafe [#28114]
+ * (new)note: checking if python is running is not thread-safe T28114
* now release the GIL on python operator execution instead, using
- * PyEval_SaveThread() / PyEval_RestoreThread() so we don't lock up blender.
+ * #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender.
*
* For copy-on-write we always cache expressions and write errors in the
* original driver, otherwise these would get freed while editing. Due to
@@ -398,7 +450,7 @@ static bool bpy_driver_secure_bytecode_validate(PyObject *expr_code, PyObject *d
float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
- const float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
PyObject *driver_vars = NULL;
PyObject *retval = NULL;
@@ -458,7 +510,7 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
}
/* update global namespace */
- bpy_pydriver_namespace_update_frame(evaltime);
+ bpy_pydriver_namespace_update_frame(anim_eval_context->eval_time);
if (driver_orig->flag & DRIVER_FLAG_USE_SELF) {
bpy_pydriver_namespace_update_self(anim_rna);
@@ -591,6 +643,8 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
}
#endif /* USE_BYTECODE_WHITELIST */
+ bpy_pydriver_namespace_add_depsgraph(driver_vars, anim_eval_context->depsgraph);
+
#if 0 /* slow, with this can avoid all Py_CompileString above. */
/* execute expression to get a value */
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
diff --git a/source/blender/python/intern/bpy_driver.h b/source/blender/python/intern/bpy_driver.h
index c77815c7e0e..d5064d9fa56 100644
--- a/source/blender/python/intern/bpy_driver.h
+++ b/source/blender/python/intern/bpy_driver.h
@@ -18,10 +18,15 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_DRIVER_H__
-#define __BPY_DRIVER_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
int bpy_pydriver_create_dict(void);
extern PyObject *bpy_pydriver_Dict;
-#endif /* __BPY_DRIVER_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_gizmo_wrap.h b/source/blender/python/intern/bpy_gizmo_wrap.h
index d9031282c40..86b56ab2bd9 100644
--- a/source/blender/python/intern/bpy_gizmo_wrap.h
+++ b/source/blender/python/intern/bpy_gizmo_wrap.h
@@ -18,14 +18,19 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_GIZMO_WRAP_H__
-#define __BPY_GIZMO_WRAP_H__
+#pragma once
struct wmGizmoGroupType;
struct wmGizmoType;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* exposed to rna/wm api */
void BPY_RNA_gizmo_wrapper(struct wmGizmoType *gzt, void *userdata);
void BPY_RNA_gizmogroup_wrapper(struct wmGizmoGroupType *gzgt, void *userdata);
-#endif /* __BPY_GIZMO_WRAP_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 6da1715b02d..c311041e4cb 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -68,6 +68,7 @@
/* inittab initialization functions */
#include "../bmesh/bmesh_py_api.h"
#include "../generic/bgl.h"
+#include "../generic/bl_math_py_api.h"
#include "../generic/blf_py_api.h"
#include "../generic/idprop_py_api.h"
#include "../generic/imbuf_py_api.h"
@@ -136,7 +137,7 @@ void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
}
/* context should be used but not now because it causes some bugs */
-void bpy_context_clear(bContext *UNUSED(C), PyGILState_STATE *gilstate)
+void bpy_context_clear(bContext *UNUSED(C), const PyGILState_STATE *gilstate)
{
py_call_level--;
@@ -228,6 +229,7 @@ static struct _inittab bpy_internal_modules[] = {
{"_bpy_path", BPyInit__bpy_path},
{"bgl", BPyInit_bgl},
{"blf", BPyInit_blf},
+ {"bl_math", BPyInit_bl_math},
{"imbuf", BPyInit_imbuf},
{"bmesh", BPyInit_bmesh},
#if 0
@@ -256,11 +258,13 @@ void BPY_python_start(int argc, const char **argv)
PyThreadState *py_tstate = NULL;
const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL);
- /* not essential but nice to set our name */
- static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */
- BLI_strncpy_wchar_from_utf8(
- program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar));
- Py_SetProgramName(program_path_wchar);
+ /* Not essential but nice to set our name. */
+ {
+ const char *program_path = BKE_appdir_program_path();
+ wchar_t program_path_wchar[FILE_MAX];
+ BLI_strncpy_wchar_from_utf8(program_path_wchar, program_path, ARRAY_SIZE(program_path_wchar));
+ Py_SetProgramName(program_path_wchar);
+ }
/* must run before python initializes */
PyImport_ExtendInittab(bpy_internal_modules);
@@ -268,11 +272,11 @@ void BPY_python_start(int argc, const char **argv)
/* allow to use our own included python */
PyC_SetHomePath(py_path_bundle);
- /* without this the sys.stdout may be set to 'ascii'
+ /* Without this the `sys.stdout` may be set to 'ascii'
* (it is on my system at least), where printing unicode values will raise
- * an error, this is highly annoying, another stumbling block for devs,
+ * an error, this is highly annoying, another stumbling block for developers,
* so use a more relaxed error handler and enforce utf-8 since the rest of
- * blender is utf-8 too - campbell */
+ * Blender is utf-8 too - campbell */
Py_SetStandardStreamEncoding("utf-8", "surrogateescape");
/* Suppress error messages when calculating the module search path.
@@ -434,6 +438,12 @@ static void python_script_error_jump_text(struct Text *text)
}
}
+void BPY_python_backtrace(/* FILE */ void *fp)
+{
+ fputs("\n# Python backtrace\n", fp);
+ PyC_StackPrint(fp);
+}
+
/* super annoying, undo _PyModule_Clear(), bug [#23871] */
#define PYMODULE_CLEAR_WORKAROUND
@@ -613,8 +623,11 @@ void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
/**
* \return success
*/
-bool BPY_execute_string_as_number(
- bContext *C, const char *imports[], const char *expr, const bool verbose, double *r_value)
+bool BPY_execute_string_as_number(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ double *r_value)
{
PyGILState_STATE gilstate;
bool ok = true;
@@ -633,8 +646,8 @@ bool BPY_execute_string_as_number(
ok = PyC_RunString_AsNumber(imports, expr, "<expr as number>", r_value);
if (ok == false) {
- if (verbose) {
- BPy_errors_to_report_ex(CTX_wm_reports(C), false, false);
+ if (report_prefix != NULL) {
+ BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
}
else {
PyErr_Clear();
@@ -652,7 +665,7 @@ bool BPY_execute_string_as_number(
bool BPY_execute_string_as_string_and_size(bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
char **r_value,
size_t *r_value_size)
{
@@ -670,8 +683,8 @@ bool BPY_execute_string_as_string_and_size(bContext *C,
ok = PyC_RunString_AsStringAndSize(imports, expr, "<expr as str>", r_value, r_value_size);
if (ok == false) {
- if (verbose) {
- BPy_errors_to_report_ex(CTX_wm_reports(C), false, false);
+ if (report_prefix != NULL) {
+ BPy_errors_to_report_ex(CTX_wm_reports(C), false, false, report_prefix);
}
else {
PyErr_Clear();
@@ -683,12 +696,15 @@ bool BPY_execute_string_as_string_and_size(bContext *C,
return ok;
}
-bool BPY_execute_string_as_string(
- bContext *C, const char *imports[], const char *expr, const bool verbose, char **r_value)
+bool BPY_execute_string_as_string(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ char **r_value)
{
size_t value_dummy_size;
return BPY_execute_string_as_string_and_size(
- C, imports, expr, verbose, r_value, &value_dummy_size);
+ C, imports, expr, report_prefix, r_value, &value_dummy_size);
}
/**
@@ -696,8 +712,11 @@ bool BPY_execute_string_as_string(
*
* \return success
*/
-bool BPY_execute_string_as_intptr(
- bContext *C, const char *imports[], const char *expr, const bool verbose, intptr_t *r_value)
+bool BPY_execute_string_as_intptr(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ intptr_t *r_value)
{
BLI_assert(r_value && expr);
PyGILState_STATE gilstate;
@@ -713,8 +732,8 @@ bool BPY_execute_string_as_intptr(
ok = PyC_RunString_AsIntPtr(imports, expr, "<expr as intptr>", r_value);
if (ok == false) {
- if (verbose) {
- BPy_errors_to_report_ex(CTX_wm_reports(C), false, false);
+ if (report_prefix != NULL) {
+ BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
}
else {
PyErr_Clear();
@@ -908,8 +927,11 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
/* TODO, reloading the module isn't functional at the moment. */
static void bpy_module_free(void *mod);
+
+/* Defined in 'creator.c' when building as a Python module. */
extern int main_python_enter(int argc, const char **argv);
extern void main_python_exit(void);
+
static struct PyModuleDef bpy_proxy_def = {
PyModuleDef_HEAD_INIT,
"bpy", /* m_name */
diff --git a/source/blender/python/intern/bpy_intern_string.h b/source/blender/python/intern/bpy_intern_string.h
index 14f9607f3b4..0c75b723fb8 100644
--- a/source/blender/python/intern/bpy_intern_string.h
+++ b/source/blender/python/intern/bpy_intern_string.h
@@ -14,13 +14,16 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BPY_INTERN_STRING_H__
-#define __BPY_INTERN_STRING_H__
+#pragma once
/** \file
* \ingroup pythonintern
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void bpy_intern_string_init(void);
void bpy_intern_string_exit(void);
@@ -41,4 +44,6 @@ extern PyObject *bpy_intern_str_register;
extern PyObject *bpy_intern_str_self;
extern PyObject *bpy_intern_str_unregister;
-#endif /* __BPY_INTERN_STRING_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_library.h b/source/blender/python/intern/bpy_library.h
index 6840807d2b0..fbcf111e37d 100644
--- a/source/blender/python/intern/bpy_library.h
+++ b/source/blender/python/intern/bpy_library.h
@@ -18,12 +18,17 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_LIBRARY_H__
-#define __BPY_LIBRARY_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
int BPY_library_load_type_ready(void);
extern PyMethodDef BPY_library_load_method_def;
extern PyMethodDef BPY_library_write_method_def;
-#endif /* __BPY_LIBRARY_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_msgbus.h b/source/blender/python/intern/bpy_msgbus.h
index 2b3cc4cfaf4..8d4846fd707 100644
--- a/source/blender/python/intern/bpy_msgbus.h
+++ b/source/blender/python/intern/bpy_msgbus.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_MSGBUS_H__
-#define __BPY_MSGBUS_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_msgbus_module(void);
-#endif /* __BPY_MSGBUS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_operator.h b/source/blender/python/intern/bpy_operator.h
index 37f6b90fbdb..3cb335d5d9a 100644
--- a/source/blender/python/intern/bpy_operator.h
+++ b/source/blender/python/intern/bpy_operator.h
@@ -18,8 +18,11 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_OPERATOR_H__
-#define __BPY_OPERATOR_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
extern PyTypeObject pyop_base_Type;
@@ -31,4 +34,6 @@ typedef struct {
PyObject *BPY_operator_module(void);
+#ifdef __cplusplus
+}
#endif
diff --git a/source/blender/python/intern/bpy_operator_wrap.h b/source/blender/python/intern/bpy_operator_wrap.h
index 5bb087540cc..9e496cd8d26 100644
--- a/source/blender/python/intern/bpy_operator_wrap.h
+++ b/source/blender/python/intern/bpy_operator_wrap.h
@@ -18,11 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_OPERATOR_WRAP_H__
-#define __BPY_OPERATOR_WRAP_H__
+#pragma once
struct wmOperatorType;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* these are used for operator methods, used by bpy_operator.c */
PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args);
@@ -30,4 +33,6 @@ PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args);
void BPY_RNA_operator_wrapper(struct wmOperatorType *ot, void *userdata);
void BPY_RNA_operator_macro_wrapper(struct wmOperatorType *ot, void *userdata);
+#ifdef __cplusplus
+}
#endif
diff --git a/source/blender/python/intern/bpy_path.h b/source/blender/python/intern/bpy_path.h
index 3f102ae2bb9..3e25cb26288 100644
--- a/source/blender/python/intern/bpy_path.h
+++ b/source/blender/python/intern/bpy_path.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_PATH_H__
-#define __BPY_PATH_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPyInit__bpy_path(void);
+#ifdef __cplusplus
+}
#endif
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 3df0d805c5b..830acd987d9 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -88,6 +88,37 @@ static const EnumPropertyItem property_flag_enum_items[] = {
"'LIBRARY_EDITABLE'].\n" \
" :type options: set\n"
+static const EnumPropertyItem property_flag_override_items[] = {
+ {PROPOVERRIDE_OVERRIDABLE_LIBRARY,
+ "LIBRARY_OVERRIDABLE",
+ 0,
+ "Library Overridable",
+ "Allow that property to be overridable from library linked data-blocks"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+#define BPY_PROPDEF_OPTIONS_OVERRIDE_DOC \
+ " :arg options: Enumerator in ['LIBRARY_OVERRIDE'].\n" \
+ " :type options: set\n"
+
+static const EnumPropertyItem property_flag_override_collection_items[] = {
+ {PROPOVERRIDE_OVERRIDABLE_LIBRARY,
+ "LIBRARY_OVERRIDABLE",
+ 0,
+ "Library Overridable",
+ "Make that property editable in library overrides of linked data-blocks"},
+ {PROPOVERRIDE_NO_PROP_NAME,
+ "NO_PROPERTY_NAME",
+ 0,
+ "No Name",
+ "Do not use the names of the items, only their indices in the collection"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+#define BPY_PROPDEF_OPTIONS_OVERRIDE_COLLECTION_DOC \
+ " :arg options: Enumerator in ['LIBRARY_OVERRIDE', 'NO_PROPERTY_NAME'].\n" \
+ " :type options: set\n"
+
/* subtypes */
/* XXX Keep in sync with rna_rna.c's rna_enum_property_subtype_items ???
* Currently it is not...
@@ -202,6 +233,11 @@ static void bpy_prop_assign_flag(PropertyRNA *prop, const int flag)
}
}
+static void bpy_prop_assign_flag_override(PropertyRNA *prop, const int flag_override)
+{
+ RNA_def_property_override_flag(prop, flag_override);
+}
+
/* operators and classes use this so it can store the args given but defer
* running it until the operator runs where these values are used to setup
* the default args for that operator instance */
@@ -1959,7 +1995,7 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop,
/* terse macros for error checks shared between all funcs cant use function
* calls because of static strings passed to pyrna_set_to_enum_bitfield */
-#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
+#define BPY_PROPDEF_CHECK(_func, _property_flag_items, _property_flag_override_items) \
if (UNLIKELY(id_len >= MAX_IDPROP_NAME)) { \
PyErr_Format(PyExc_TypeError, \
#_func "(): '%.200s' too long, max length is %d", \
@@ -1975,6 +2011,12 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop,
_property_flag_items, pyopts, &opts, #_func "(options={ ...}):"))) { \
return NULL; \
} \
+ if (UNLIKELY(pyopts_override && pyrna_set_to_enum_bitfield(_property_flag_override_items, \
+ pyopts_override, \
+ &opts_override, \
+ #_func "(override={ ...}):"))) { \
+ return NULL; \
+ } \
{ \
const EnumPropertyItem *tag_defines = RNA_struct_property_tag_defines(srna); \
if (py_tags && !tag_defines) { \
@@ -1990,8 +2032,9 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop,
} \
(void)0
-#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
- BPY_PROPDEF_CHECK(_func, _property_flag_items); \
+#define BPY_PROPDEF_SUBTYPE_CHECK( \
+ _func, _property_flag_items, _property_flag_override_items, _subtype) \
+ BPY_PROPDEF_CHECK(_func, _property_flag_items, _property_flag_override_items); \
if (UNLIKELY(pysubtype && RNA_enum_value_from_id(_subtype, pysubtype, &subtype) == 0)) { \
const char *enum_str = BPy_enum_as_string(_subtype); \
PyErr_Format(PyExc_TypeError, \
@@ -2099,7 +2142,8 @@ PyDoc_STRVAR(BPy_BoolProperty_doc,
"description=\"\", "
"default=False, "
"options={'ANIMATABLE'}, "
- "tags={}, "
+ "override=set(), "
+ "tags=set(), "
"subtype='NONE', "
"update=None, "
"get=None, "
@@ -2107,8 +2151,9 @@ PyDoc_STRVAR(BPy_BoolProperty_doc,
"\n"
" Returns a new boolean property definition.\n"
"\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_OPTIONS_DOC
- BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_NUMBER_DOC BPY_PROPDEF_UPDATE_DOC
- BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
+ BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC
+ BPY_PROPDEF_SUBTYPE_NUMBER_DOC BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC
+ BPY_PROPDEF_SET_DOC);
static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -2121,7 +2166,9 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
bool def = false;
PropertyRNA *prop;
PyObject *pyopts = NULL;
+ PyObject *pyopts_override = NULL;
int opts = 0;
+ int opts_override = 0;
int prop_tags = 0;
const char *pysubtype = NULL;
int subtype = PROP_NONE;
@@ -2136,6 +2183,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
"description",
"default",
"options",
+ "override",
"tags",
"subtype",
"update",
@@ -2143,7 +2191,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
"set",
NULL,
};
- static _PyArg_Parser _parser = {"s#|ssO&O!O!sOOO:BoolProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#|ssO&O!O!O!sOOO:BoolProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -2156,6 +2204,8 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags,
&pysubtype,
&update_cb,
@@ -2164,7 +2214,10 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items);
+ BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty,
+ property_flag_items,
+ property_flag_override_items,
+ property_subtype_number_items);
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
return NULL;
@@ -2186,6 +2239,9 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_boolean(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
@@ -2194,24 +2250,26 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
Py_RETURN_NONE;
}
-PyDoc_STRVAR(BPy_BoolVectorProperty_doc,
- ".. function:: BoolVectorProperty(name=\"\", "
- "description=\"\", "
- "default=(False, False, False), "
- "options={'ANIMATABLE'}, "
- "tags={}, "
- "subtype='NONE', "
- "size=3, "
- "update=None, "
- "get=None, "
- "set=None)\n"
- "\n"
- " Returns a new vector boolean property definition.\n"
- "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC
- " :arg default: sequence of booleans the length of *size*.\n"
- " :type default: sequence\n" BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_TAGS_DOC
- BPY_PROPDEF_SUBTYPE_ARRAY_DOC BPY_PROPDEF_VECSIZE_DOC BPY_PROPDEF_UPDATE_DOC
- BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
+PyDoc_STRVAR(
+ BPy_BoolVectorProperty_doc,
+ ".. function:: BoolVectorProperty(name=\"\", "
+ "description=\"\", "
+ "default=(False, False, False), "
+ "options={'ANIMATABLE'}, "
+ "override=set(), "
+ "tags=set(), "
+ "subtype='NONE', "
+ "size=3, "
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
+ "\n"
+ " Returns a new vector boolean property definition.\n"
+ "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC
+ " :arg default: sequence of booleans the length of *size*.\n"
+ " :type default: sequence\n" BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC
+ BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_ARRAY_DOC BPY_PROPDEF_VECSIZE_DOC
+ BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -2226,7 +2284,9 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
PropertyRNA *prop;
PyObject *pydef = NULL;
PyObject *pyopts = NULL;
+ PyObject *pyopts_override = NULL;
int opts = 0;
+ int opts_override = 0;
int prop_tags = 0;
const char *pysubtype = NULL;
int subtype = PROP_NONE;
@@ -2241,6 +2301,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
"description",
"default",
"options",
+ "override",
"tags",
"subtype",
"size",
@@ -2249,7 +2310,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
"set",
NULL,
};
- static _PyArg_Parser _parser = {"s#|ssOO!O!siOOO:BoolVectorProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#|ssOO!O!O!siOOO:BoolVectorProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -2261,6 +2322,8 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags,
&pysubtype,
&size,
@@ -2270,8 +2333,10 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
return NULL;
}
- BPY_PROPDEF_SUBTYPE_CHECK(
- BoolVectorProperty, property_flag_items, property_subtype_array_items);
+ BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty,
+ property_flag_items,
+ property_flag_override_items,
+ property_subtype_array_items);
if (size < 1 || size > PYRNA_STACK_ARRAY) {
PyErr_Format(
@@ -2314,6 +2379,9 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
@@ -2322,28 +2390,29 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
Py_RETURN_NONE;
}
-PyDoc_STRVAR(BPy_IntProperty_doc,
- ".. function:: IntProperty(name=\"\", "
- "description=\"\", "
- "default=0, "
- "min=-2**31, max=2**31-1, "
- "soft_min=-2**31, soft_max=2**31-1, "
- "step=1, "
- "options={'ANIMATABLE'}, "
- "tags={}, "
- "subtype='NONE', "
- "update=None, "
- "get=None, "
- "set=None)\n"
- "\n"
- " Returns a new int property definition.\n"
- "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_NUM_MIN_DOC
- " :type min: int\n" BPY_PROPDEF_NUM_MAX_DOC
- " :type max: int\n" BPY_PROPDEF_NUM_SOFTMAX_DOC
- " :type soft_min: int\n" BPY_PROPDEF_NUM_SOFTMIN_DOC
- " :type soft_max: int\n" BPY_PROPDEF_INT_STEP_DOC BPY_PROPDEF_OPTIONS_DOC
- BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_NUMBER_DOC BPY_PROPDEF_UPDATE_DOC
- BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
+PyDoc_STRVAR(
+ BPy_IntProperty_doc,
+ ".. function:: IntProperty(name=\"\", "
+ "description=\"\", "
+ "default=0, "
+ "min=-2**31, max=2**31-1, "
+ "soft_min=-2**31, soft_max=2**31-1, "
+ "step=1, "
+ "options={'ANIMATABLE'}, "
+ "override=set(), "
+ "tags=set(), "
+ "subtype='NONE', "
+ "update=None, "
+ "get=None, "
+ "set=None)\n"
+ "\n"
+ " Returns a new int property definition.\n"
+ "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_NUM_MIN_DOC
+ " :type min: int\n" BPY_PROPDEF_NUM_MAX_DOC " :type max: int\n" BPY_PROPDEF_NUM_SOFTMAX_DOC
+ " :type soft_min: int\n" BPY_PROPDEF_NUM_SOFTMIN_DOC
+ " :type soft_max: int\n" BPY_PROPDEF_INT_STEP_DOC BPY_PROPDEF_OPTIONS_DOC
+ BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_NUMBER_DOC
+ BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -2357,6 +2426,8 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
+ PyObject *pyopts_override = NULL;
+ int opts_override = 0;
int prop_tags = 0;
const char *pysubtype = NULL;
int subtype = PROP_NONE;
@@ -2376,6 +2447,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
"soft_max",
"step",
"options",
+ "override",
"tags",
"subtype",
"update",
@@ -2383,7 +2455,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
"set",
NULL,
};
- static _PyArg_Parser _parser = {"s#|ssiiiiiiO!O!sOOO:IntProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#|ssiiiiiiO!O!O!sOOO:IntProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -2400,6 +2472,8 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags,
&pysubtype,
&update_cb,
@@ -2408,7 +2482,10 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items);
+ BPY_PROPDEF_SUBTYPE_CHECK(IntProperty,
+ property_flag_items,
+ property_flag_override_items,
+ property_subtype_number_items);
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
return NULL;
@@ -2432,6 +2509,9 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_int(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
@@ -2447,7 +2527,8 @@ PyDoc_STRVAR(BPy_IntVectorProperty_doc,
"soft_max=2**31-1, "
"step=1, "
"options={'ANIMATABLE'}, "
- "tags={}, "
+ "override=set(), "
+ "tags=set(), "
"subtype='NONE', "
"size=3, "
"update=None, "
@@ -2462,8 +2543,9 @@ PyDoc_STRVAR(BPy_IntVectorProperty_doc,
" :type max: int\n" BPY_PROPDEF_NUM_SOFTMIN_DOC
" :type soft_min: int\n" BPY_PROPDEF_NUM_SOFTMAX_DOC
" :type soft_max: int\n" BPY_PROPDEF_INT_STEP_DOC BPY_PROPDEF_OPTIONS_DOC
- BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_ARRAY_DOC BPY_PROPDEF_VECSIZE_DOC
- BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
+ BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC
+ BPY_PROPDEF_SUBTYPE_ARRAY_DOC BPY_PROPDEF_VECSIZE_DOC BPY_PROPDEF_UPDATE_DOC
+ BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -2480,6 +2562,8 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
PyObject *pydef = NULL;
PyObject *pyopts = NULL;
int opts = 0;
+ PyObject *pyopts_override = NULL;
+ int opts_override = 0;
int prop_tags = 0;
const char *pysubtype = NULL;
int subtype = PROP_NONE;
@@ -2499,6 +2583,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
"soft_max",
"step",
"options",
+ "override",
"tags",
"subtype",
"size",
@@ -2507,7 +2592,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
"set",
NULL,
};
- static _PyArg_Parser _parser = {"s#|ssOiiiiiO!O!siOOO:IntVectorProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#|ssOiiiiiO!O!O!siOOO:IntVectorProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -2524,6 +2609,8 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags,
&pysubtype,
&size,
@@ -2533,8 +2620,10 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
return NULL;
}
- BPY_PROPDEF_SUBTYPE_CHECK(
- IntVectorProperty, property_flag_items, property_subtype_array_items);
+ BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty,
+ property_flag_items,
+ property_flag_override_items,
+ property_subtype_array_items);
if (size < 1 || size > PYRNA_STACK_ARRAY) {
PyErr_Format(
@@ -2575,6 +2664,9 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_int_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
@@ -2591,7 +2683,8 @@ PyDoc_STRVAR(BPy_FloatProperty_doc,
"step=3, "
"precision=2, "
"options={'ANIMATABLE'}, "
- "tags={}, "
+ "override=set(), "
+ "tags=set(), "
"subtype='NONE', "
"unit='NONE', "
"update=None, "
@@ -2604,9 +2697,9 @@ PyDoc_STRVAR(BPy_FloatProperty_doc,
" :type max: float\n" BPY_PROPDEF_NUM_SOFTMIN_DOC
" :type soft_min: float\n" BPY_PROPDEF_NUM_SOFTMAX_DOC
" :type soft_max: float\n" BPY_PROPDEF_FLOAT_STEP_DOC BPY_PROPDEF_FLOAT_PREC_DOC
- BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_NUMBER_DOC
- BPY_PROPDEF_UNIT_DOC BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC
- BPY_PROPDEF_SET_DOC);
+ BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC
+ BPY_PROPDEF_SUBTYPE_NUMBER_DOC BPY_PROPDEF_UNIT_DOC BPY_PROPDEF_UPDATE_DOC
+ BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -2622,6 +2715,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
+ PyObject *pyopts_override = NULL;
+ int opts_override = 0;
int prop_tags = 0;
const char *pysubtype = NULL;
int subtype = PROP_NONE;
@@ -2633,26 +2728,11 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject *py_tags = NULL;
static const char *_keywords[] = {
- "attr",
- "name",
- "description",
- "default",
- "min",
- "max",
- "soft_min",
- "soft_max",
- "step",
- "precision",
- "options",
- "tags",
- "subtype",
- "unit",
- "update",
- "get",
- "set",
- NULL,
+ "attr", "name", "description", "default", "min", "max", "soft_min",
+ "soft_max", "step", "precision", "options", "override", "tags", "subtype",
+ "unit", "update", "get", "set", NULL,
};
- static _PyArg_Parser _parser = {"s#|ssffffffiO!O!ssOOO:FloatProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#|ssffffffiO!O!O!ssOOO:FloatProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -2670,6 +2750,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags,
&pysubtype,
&pyunit,
@@ -2679,7 +2761,10 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items);
+ BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty,
+ property_flag_items,
+ property_flag_override_items,
+ property_subtype_number_items);
if (pyunit && RNA_enum_value_from_id(rna_enum_property_unit_items, pyunit, &unit) == 0) {
PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit);
@@ -2708,6 +2793,9 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_float(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
@@ -2724,7 +2812,8 @@ PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
"step=3, "
"precision=2, "
"options={'ANIMATABLE'}, "
- "tags={}, "
+ "override=set(), "
+ "tags=set(), "
"subtype='NONE', "
"unit='NONE', "
"size=3, "
@@ -2739,8 +2828,8 @@ PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
" :type min: float\n" BPY_PROPDEF_NUM_MAX_DOC
" :type max: float\n" BPY_PROPDEF_NUM_SOFTMIN_DOC
" :type soft_min: float\n" BPY_PROPDEF_NUM_SOFTMAX_DOC
- " :type soft_max: float\n" BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_TAGS_DOC
- BPY_PROPDEF_FLOAT_STEP_DOC BPY_PROPDEF_FLOAT_PREC_DOC
+ " :type soft_max: float\n" BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC
+ BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_FLOAT_STEP_DOC BPY_PROPDEF_FLOAT_PREC_DOC
BPY_PROPDEF_SUBTYPE_ARRAY_DOC BPY_PROPDEF_UNIT_DOC BPY_PROPDEF_VECSIZE_DOC
BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
@@ -2759,6 +2848,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
PyObject *pydef = NULL;
PyObject *pyopts = NULL;
int opts = 0;
+ PyObject *pyopts_override = NULL;
+ int opts_override = 0;
int prop_tags = 0;
const char *pysubtype = NULL;
int subtype = PROP_NONE;
@@ -2770,11 +2861,11 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
PyObject *py_tags = NULL;
static const char *_keywords[] = {
- "attr", "name", "description", "default", "min", "max", "soft_min",
- "soft_max", "step", "precision", "options", "tags", "subtype", "unit",
- "size", "update", "get", "set", NULL,
+ "attr", "name", "description", "default", "min", "max", "soft_min",
+ "soft_max", "step", "precision", "options", "override", "tags", "subtype",
+ "unit", "size", "update", "get", "set", NULL,
};
- static _PyArg_Parser _parser = {"s#|ssOfffffiO!O!ssiOOO:FloatVectorProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#|ssOfffffiO!O!O!ssiOOO:FloatVectorProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -2792,6 +2883,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags,
&pysubtype,
&pyunit,
@@ -2802,8 +2895,10 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
return NULL;
}
- BPY_PROPDEF_SUBTYPE_CHECK(
- FloatVectorProperty, property_flag_items, property_subtype_array_items);
+ BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty,
+ property_flag_items,
+ property_flag_override_items,
+ property_subtype_array_items);
if (pyunit && RNA_enum_value_from_id(rna_enum_property_unit_items, pyunit, &unit) == 0) {
PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit);
@@ -2850,6 +2945,9 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_float_array(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
@@ -2863,7 +2961,8 @@ PyDoc_STRVAR(BPy_StringProperty_doc,
"default=\"\", "
"maxlen=0, "
"options={'ANIMATABLE'}, "
- "tags={}, "
+ "override=set(), "
+ "tags=set(), "
"subtype='NONE', "
"update=None, "
"get=None, "
@@ -2874,9 +2973,9 @@ PyDoc_STRVAR(BPy_StringProperty_doc,
" :arg default: initializer string.\n"
" :type default: string\n"
" :arg maxlen: maximum length of the string.\n"
- " :type maxlen: int\n" BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_TAGS_DOC
- BPY_PROPDEF_SUBTYPE_STRING_DOC BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC
- BPY_PROPDEF_SET_DOC);
+ " :type maxlen: int\n" BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC
+ BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_STRING_DOC BPY_PROPDEF_UPDATE_DOC
+ BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -2890,6 +2989,8 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
+ PyObject *pyopts_override = NULL;
+ int opts_override = 0;
int prop_tags = 0;
const char *pysubtype = NULL;
int subtype = PROP_NONE;
@@ -2905,6 +3006,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
"default",
"maxlen",
"options",
+ "override",
"tags",
"subtype",
"update",
@@ -2912,7 +3014,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
"set",
NULL,
};
- static _PyArg_Parser _parser = {"s#|sssiO!O!sOOO:StringProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#|sssiO!O!O!sOOO:StringProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -2925,6 +3027,8 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags,
&pysubtype,
&update_cb,
@@ -2933,7 +3037,10 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
return NULL;
}
- BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items);
+ BPY_PROPDEF_SUBTYPE_CHECK(StringProperty,
+ property_flag_items,
+ property_flag_override_items,
+ property_subtype_string_items);
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
return NULL;
@@ -2961,6 +3068,9 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_string(prop, get_cb, set_cb);
RNA_def_property_duplicate_pointers(srna, prop);
@@ -2975,7 +3085,8 @@ PyDoc_STRVAR(
"description=\"\", "
"default=None, "
"options={'ANIMATABLE'}, "
- "tags={}, "
+ "override=set(), "
+ "tags=set(), "
"update=None, "
"get=None, "
"set=None)\n"
@@ -3019,8 +3130,9 @@ PyDoc_STRVAR(
"instead.\n"
" WARNING: Strings can not be specified for dynamic enums\n"
" (i.e. if a callback function is given as *items* parameter).\n"
- " :type default: string, integer or set\n" BPY_PROPDEF_OPTIONS_ENUM_DOC BPY_PROPDEF_TAGS_DOC
- BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
+ " :type default: string, integer or set\n" BPY_PROPDEF_OPTIONS_ENUM_DOC
+ BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_UPDATE_DOC
+ BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC);
static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -3037,6 +3149,8 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
PropertyRNA *prop;
PyObject *pyopts = NULL;
int opts = 0;
+ PyObject *pyopts_override = NULL;
+ int opts_override = 0;
int prop_tags = 0;
bool is_itemf = false;
PyObject *update_cb = NULL;
@@ -3051,13 +3165,14 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
"description",
"default",
"options",
+ "override",
"tags",
"update",
"get",
"set",
NULL,
};
- static _PyArg_Parser _parser = {"s#O|ssOO!O!OOO:EnumProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#O|ssOO!O!O!OOO:EnumProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -3070,6 +3185,8 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags,
&update_cb,
&get_cb,
@@ -3077,7 +3194,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items);
+ BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items, property_flag_override_items);
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
return NULL;
@@ -3149,6 +3266,9 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL));
RNA_def_property_duplicate_pointers(srna, prop);
@@ -3194,14 +3314,15 @@ PyDoc_STRVAR(BPy_PointerProperty_doc,
"name=\"\", "
"description=\"\", "
"options={'ANIMATABLE'}, "
- "tags={}, "
+ "override=set(), "
+ "tags=set(), "
"poll=None, "
"update=None)\n"
"\n"
" Returns a new pointer property definition.\n"
"\n" BPY_PROPDEF_TYPE_DOC BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC
- BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_POLL_DOC
- BPY_PROPDEF_UPDATE_DOC);
+ BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC
+ BPY_PROPDEF_POLL_DOC BPY_PROPDEF_UPDATE_DOC);
PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -3215,8 +3336,10 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
StructRNA *ptype;
PyObject *type = Py_None;
PyObject *pyopts = NULL;
+ PyObject *pyopts_override = NULL;
PyObject *py_tags = NULL;
int opts = 0;
+ int opts_override = 0;
int prop_tags = 0;
PyObject *update_cb = NULL, *poll_cb = NULL;
@@ -3226,12 +3349,13 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
"name",
"description",
"options",
+ "override",
"tags",
"poll",
"update",
NULL,
};
- static _PyArg_Parser _parser = {"s#O|ssO!O!OO:PointerProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#O|ssO!O!O!OO:PointerProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -3243,13 +3367,15 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags,
&poll_cb,
&update_cb)) {
return NULL;
}
- BPY_PROPDEF_CHECK(PointerProperty, property_flag_items);
+ BPY_PROPDEF_CHECK(PointerProperty, property_flag_items, property_flag_override_items);
ptype = pointer_type_from_py(type, "PointerProperty(...)");
if (!ptype) {
@@ -3275,6 +3401,9 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
if (RNA_struct_idprops_contains_datablock(ptype)) {
if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
@@ -3293,11 +3422,13 @@ PyDoc_STRVAR(BPy_CollectionProperty_doc,
"name=\"\", "
"description=\"\", "
"options={'ANIMATABLE'}, "
- "tags={})\n"
+ "override=set(), "
+ "tags=set())\n"
"\n"
" Returns a new collection property definition.\n"
"\n" BPY_PROPDEF_TYPE_DOC BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC
- BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_TAGS_DOC);
+ BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_COLLECTION_DOC
+ BPY_PROPDEF_TAGS_DOC);
PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -3311,8 +3442,10 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
StructRNA *ptype;
PyObject *type = Py_None;
PyObject *pyopts = NULL;
+ PyObject *pyopts_override = NULL;
PyObject *py_tags = NULL;
int opts = 0;
+ int opts_override = 0;
int prop_tags = 0;
static const char *_keywords[] = {
@@ -3321,10 +3454,11 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
"name",
"description",
"options",
+ "override",
"tags",
NULL,
};
- static _PyArg_Parser _parser = {"s#O|ssO!O!:CollectionProperty", _keywords, 0};
+ static _PyArg_Parser _parser = {"s#O|ssO!O!O!:CollectionProperty", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(args,
kw,
&_parser,
@@ -3336,11 +3470,14 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
&PySet_Type,
&pyopts,
&PySet_Type,
+ &pyopts_override,
+ &PySet_Type,
&py_tags)) {
return NULL;
}
- BPY_PROPDEF_CHECK(CollectionProperty, property_flag_items);
+ BPY_PROPDEF_CHECK(
+ CollectionProperty, property_flag_items, property_flag_override_collection_items);
ptype = pointer_type_from_py(type, "CollectionProperty(...):");
if (!ptype) {
@@ -3362,6 +3499,9 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+ if (pyopts_override) {
+ bpy_prop_assign_flag_override(prop, opts_override);
+ }
if (RNA_struct_idprops_contains_datablock(ptype)) {
if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
diff --git a/source/blender/python/intern/bpy_props.h b/source/blender/python/intern/bpy_props.h
index d559a3493b4..3d7860dcdd8 100644
--- a/source/blender/python/intern/bpy_props.h
+++ b/source/blender/python/intern/bpy_props.h
@@ -18,8 +18,11 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_PROPS_H__
-#define __BPY_PROPS_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_rna_props(void);
@@ -29,4 +32,6 @@ StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix);
#define PYRNA_STACK_ARRAY RNA_STACK_ARRAY
+#ifdef __cplusplus
+}
#endif
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index ebbbc8f3140..893832b61b6 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -7660,8 +7660,8 @@ void BPY_update_rna_module(void)
}
#if 0
-/* This is a way we can access docstrings for RNA types
- * without having the datatypes in blender */
+/* This is a way we can access doc-strings for RNA types
+ * without having the data-types in Blender. */
PyObject *BPY_rna_doc(void)
{
PointerRNA ptr;
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 652d65fe64c..a2c2171d151 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -18,8 +18,7 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_RNA_H__
-#define __BPY_RNA_H__
+#pragma once
/* --- bpy build options --- */
#ifdef WITH_PYTHON_SAFETY
@@ -67,6 +66,10 @@
struct ID;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern PyTypeObject pyrna_struct_meta_idprop_Type;
extern PyTypeObject pyrna_struct_Type;
extern PyTypeObject pyrna_prop_Type;
@@ -265,4 +268,6 @@ extern PyMethodDef meth_bpy_owner_id_get;
extern BPy_StructRNA *bpy_context_module;
+#ifdef __cplusplus
+}
#endif
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index d792b2032b5..8aba2ae8598 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -36,6 +36,7 @@
#include "ED_keyframing.h"
#include "BKE_anim_data.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
@@ -332,7 +333,20 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
&options) == -1) {
return NULL;
}
- else if (self->ptr.type == &RNA_NlaStrip) {
+
+ /* This assumes that keyframes are only added on original data & using the active depsgraph. If
+ * it turns out to be necessary for some reason to insert keyframes on evaluated objects, we can
+ * revisit this and add an explicit `depsgraph` keyword argument to the function call.
+ *
+ * It is unlikely that driver code (which is the reason this depsgraph pointer is obtained) will
+ * be executed from this function call, as this only happens when `options` has
+ * `INSERTKEY_DRIVER`, which is not exposed to Python. */
+ bContext *C = BPy_GetContext();
+ struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+
+ if (self->ptr.type == &RNA_NlaStrip) {
/* Handle special properties for NLA Strips, whose F-Curves are stored on the
* strips themselves. These are stored separately or else the properties will
* not have any effect.
@@ -355,8 +369,8 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
if (prop) {
NlaStrip *strip = ptr.data;
FCurve *fcu = BKE_fcurve_find(&strip->fcurves, RNA_property_identifier(prop), index);
-
- result = insert_keyframe_direct(&reports, ptr, prop, fcu, cfra, keytype, NULL, options);
+ result = insert_keyframe_direct(
+ &reports, ptr, prop, fcu, &anim_eval_context, keytype, NULL, options);
}
else {
BKE_reportf(&reports, RPT_ERROR, "Could not resolve path (%s)", path_full);
@@ -384,7 +398,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
group_name,
path_full,
index,
- cfra,
+ &anim_eval_context,
keytype,
NULL,
options) != 0);
@@ -415,7 +429,7 @@ char pyrna_struct_keyframe_delete_doc[] =
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist "
"yet.\n"
" :type group: str\n"
- " :return: Success of keyframe deleation.\n"
+ " :return: Success of keyframe deletion.\n"
" :rtype: boolean\n";
PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
{
diff --git a/source/blender/python/intern/bpy_rna_anim.h b/source/blender/python/intern/bpy_rna_anim.h
index 7630c268bbe..7c840e616b1 100644
--- a/source/blender/python/intern/bpy_rna_anim.h
+++ b/source/blender/python/intern/bpy_rna_anim.h
@@ -14,13 +14,16 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BPY_RNA_ANIM_H__
-#define __BPY_RNA_ANIM_H__
+#pragma once
/** \file
* \ingroup pythonintern
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern char pyrna_struct_keyframe_insert_doc[];
extern char pyrna_struct_keyframe_delete_doc[];
extern char pyrna_struct_driver_add_doc[];
@@ -31,4 +34,6 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args);
PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args);
-#endif /* __BPY_RNA_ANIM_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_rna_callback.h b/source/blender/python/intern/bpy_rna_callback.h
index 71e1f71f8af..ae42c4cb1a4 100644
--- a/source/blender/python/intern/bpy_rna_callback.h
+++ b/source/blender/python/intern/bpy_rna_callback.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BPY_RNA_CALLBACK_H__
-#define __BPY_RNA_CALLBACK_H__
+#pragma once
/** \file
* \ingroup pythonintern
@@ -24,6 +23,10 @@
struct BPy_StructRNA;
struct PyObject;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if 0
PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args);
PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args);
@@ -32,4 +35,6 @@ PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args);
PyObject *pyrna_callback_classmethod_add(PyObject *cls, PyObject *args);
PyObject *pyrna_callback_classmethod_remove(PyObject *cls, PyObject *args);
-#endif /* __BPY_RNA_CALLBACK_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_rna_driver.h b/source/blender/python/intern/bpy_rna_driver.h
index 36160d7c867..cc2c4550870 100644
--- a/source/blender/python/intern/bpy_rna_driver.h
+++ b/source/blender/python/intern/bpy_rna_driver.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __BPY_RNA_DRIVER_H__
-#define __BPY_RNA_DRIVER_H__
+#pragma once
/** \file
* \ingroup pythonintern
@@ -25,10 +24,16 @@ struct ChannelDriver;
struct DriverTarget;
struct PathResolvedRNA;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
PyObject *pyrna_driver_get_variable_value(struct ChannelDriver *driver, struct DriverTarget *dtar);
PyObject *pyrna_driver_self_from_anim_rna(struct PathResolvedRNA *anim_rna);
bool pyrna_driver_is_equal_anim_rna(const struct PathResolvedRNA *anim_rna,
const PyObject *py_anim_rna);
-#endif /* __BPY_RNA_DRIVER_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_rna_gizmo.h b/source/blender/python/intern/bpy_rna_gizmo.h
index 293ab38a6ab..307b694338c 100644
--- a/source/blender/python/intern/bpy_rna_gizmo.h
+++ b/source/blender/python/intern/bpy_rna_gizmo.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_RNA_GIZMO_H__
-#define __BPY_RNA_GIZMO_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
int BPY_rna_gizmo_module(PyObject *);
-#endif /* __BPY_RNA_GIZMO_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_rna_id_collection.c b/source/blender/python/intern/bpy_rna_id_collection.c
index b607f1635e6..a4df8c3aef1 100644
--- a/source/blender/python/intern/bpy_rna_id_collection.c
+++ b/source/blender/python/intern/bpy_rna_id_collection.c
@@ -132,7 +132,7 @@ static int foreach_libblock_id_user_map_callback(LibraryIDLinkCallbackData *cb_d
PyDoc_STRVAR(bpy_user_map_doc,
".. method:: user_map([subset=(id1, id2, ...)], key_types={..}, value_types={..})\n"
"\n"
- " Returns a mapping of all ID datablocks in current ``bpy.data`` to a set of all "
+ " Returns a mapping of all ID data-blocks in current ``bpy.data`` to a set of all "
"datablocks using them.\n"
"\n"
" For list of valid set members for key_types & value_types, see: "
diff --git a/source/blender/python/intern/bpy_rna_id_collection.h b/source/blender/python/intern/bpy_rna_id_collection.h
index ee8f4c666a8..320a9e66ff8 100644
--- a/source/blender/python/intern/bpy_rna_id_collection.h
+++ b/source/blender/python/intern/bpy_rna_id_collection.h
@@ -18,11 +18,16 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_RNA_ID_COLLECTION_H__
-#define __BPY_RNA_ID_COLLECTION_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
extern PyMethodDef BPY_rna_id_collection_user_map_method_def;
extern PyMethodDef BPY_rna_id_collection_batch_remove_method_def;
extern PyMethodDef BPY_rna_id_collection_orphans_purge_method_def;
-#endif /* __BPY_RNA_ID_COLLECTION_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_rna_types_capi.h b/source/blender/python/intern/bpy_rna_types_capi.h
index 1049122e468..eb8dd14d888 100644
--- a/source/blender/python/intern/bpy_rna_types_capi.h
+++ b/source/blender/python/intern/bpy_rna_types_capi.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_RNA_TYPES_CAPI_H__
-#define __BPY_RNA_TYPES_CAPI_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
void BPY_rna_types_extend_capi(void);
-#endif /* __BPY_RNA_TYPES_CAPI_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c
index e92a0b788ea..e2c894e90f8 100644
--- a/source/blender/python/intern/bpy_traceback.c
+++ b/source/blender/python/intern/bpy_traceback.c
@@ -34,8 +34,8 @@
static const char *traceback_filepath(PyTracebackObject *tb, PyObject **coerce)
{
- return PyBytes_AS_STRING(
- (*coerce = PyUnicode_EncodeFSDefault(tb->tb_frame->f_code->co_filename)));
+ *coerce = PyUnicode_EncodeFSDefault(tb->tb_frame->f_code->co_filename);
+ return PyBytes_AS_STRING(*coerce);
}
/* copied from pythonrun.c, 3.4.0 */
@@ -140,8 +140,8 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset)
PyErr_Fetch(&exception, &value, (PyObject **)&tb);
if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
- /* no traceback available when SyntaxError.
- * python has no api's to this. reference parse_syntax_error() from pythonrun.c */
+ /* no trace-back available when `SyntaxError`.
+ * python has no API's to this. reference #parse_syntax_error() from pythonrun.c */
PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
if (value) { /* should always be true */
diff --git a/source/blender/python/intern/bpy_traceback.h b/source/blender/python/intern/bpy_traceback.h
index 11295706240..26f6a574439 100644
--- a/source/blender/python/intern/bpy_traceback.h
+++ b/source/blender/python/intern/bpy_traceback.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_TRACEBACK_H__
-#define __BPY_TRACEBACK_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
void python_script_error_jump(const char *filepath, int *lineno, int *offset);
-#endif /* __BPY_TRACEBACK_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_utils_previews.h b/source/blender/python/intern/bpy_utils_previews.h
index e9de8876068..dbe74f619a9 100644
--- a/source/blender/python/intern/bpy_utils_previews.h
+++ b/source/blender/python/intern/bpy_utils_previews.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_UTILS_PREVIEWS_H__
-#define __BPY_UTILS_PREVIEWS_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_utils_previews_module(void);
-#endif /* __BPY_UTILS_PREVIEWS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/intern/bpy_utils_units.h b/source/blender/python/intern/bpy_utils_units.h
index 5a30c1c3dae..7a135bc6163 100644
--- a/source/blender/python/intern/bpy_utils_units.h
+++ b/source/blender/python/intern/bpy_utils_units.h
@@ -18,9 +18,14 @@
* \ingroup pythonintern
*/
-#ifndef __BPY_UTILS_UNITS_H__
-#define __BPY_UTILS_UNITS_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
PyObject *BPY_utils_units(void);
-#endif /* __BPY_UTILS_UNITS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h
index c59fa75b651..d8d390cfad0 100644
--- a/source/blender/python/mathutils/mathutils.h
+++ b/source/blender/python/mathutils/mathutils.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MATHUTILS_H__
-#define __MATHUTILS_H__
+#pragma once
/** \file
* \ingroup pymathutils
@@ -195,5 +194,3 @@ int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject
/* dynstr as python string utility functions */
PyObject *mathutils_dynstr_to_py(struct DynStr *ds);
#endif
-
-#endif /* __MATHUTILS_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Color.h b/source/blender/python/mathutils/mathutils_Color.h
index 51e1746ae74..c966bf1e3b2 100644
--- a/source/blender/python/mathutils/mathutils_Color.h
+++ b/source/blender/python/mathutils/mathutils_Color.h
@@ -18,8 +18,7 @@
* \ingroup pymathutils
*/
-#ifndef __MATHUTILS_COLOR_H__
-#define __MATHUTILS_COLOR_H__
+#pragma once
extern PyTypeObject color_Type;
#define ColorObject_Check(v) PyObject_TypeCheck((v), &color_Type)
@@ -42,5 +41,3 @@ PyObject *Color_CreatePyObject_wrap(float col[3], PyTypeObject *base_type) ATTR_
PyObject *Color_CreatePyObject_cb(PyObject *cb_user,
unsigned char cb_type,
unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT;
-
-#endif /* __MATHUTILS_COLOR_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Euler.h b/source/blender/python/mathutils/mathutils_Euler.h
index c56962395e5..0deef3cfdf3 100644
--- a/source/blender/python/mathutils/mathutils_Euler.h
+++ b/source/blender/python/mathutils/mathutils_Euler.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MATHUTILS_EULER_H__
-#define __MATHUTILS_EULER_H__
+#pragma once
/** \file
* \ingroup pymathutils
@@ -50,5 +49,3 @@ PyObject *Euler_CreatePyObject_cb(PyObject *cb_user,
unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT;
short euler_order_from_string(const char *str, const char *error_prefix);
-
-#endif /* __MATHUTILS_EULER_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 63137e094b7..3e30c81c8c6 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -2526,7 +2526,6 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
}
if (mat1 && mat2) {
-#ifdef USE_MATHUTILS_ELEM_MUL
/* MATRIX * MATRIX */
float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
@@ -2540,7 +2539,6 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
mul_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
-#endif
}
else if (mat2) {
/*FLOAT/INT * MATRIX */
@@ -2584,7 +2582,6 @@ static PyObject *Matrix_imul(PyObject *m1, PyObject *m2)
}
if (mat1 && mat2) {
-#ifdef USE_MATHUTILS_ELEM_MUL
/* MATRIX *= MATRIX */
if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) {
PyErr_SetString(PyExc_ValueError,
@@ -2594,14 +2591,6 @@ static PyObject *Matrix_imul(PyObject *m1, PyObject *m2)
}
mul_vn_vn(mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
-#else
- PyErr_Format(PyExc_TypeError,
- "In place element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(m1)->tp_name,
- Py_TYPE(m2)->tp_name);
- return NULL;
-#endif
}
else if (mat1 && (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0)) {
/* MATRIX *= FLOAT/INT */
diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h
index a0e2256b1ce..588c0b94891 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.h
+++ b/source/blender/python/mathutils/mathutils_Matrix.h
@@ -18,8 +18,7 @@
* \ingroup pymathutils
*/
-#ifndef __MATHUTILS_MATRIX_H__
-#define __MATHUTILS_MATRIX_H__
+#pragma once
extern PyTypeObject matrix_Type;
extern PyTypeObject matrix_access_Type;
@@ -96,5 +95,3 @@ extern struct Mathutils_Callback mathutils_matrix_col_cb;
extern struct Mathutils_Callback mathutils_matrix_translation_cb;
void matrix_as_3x3(float mat[3][3], MatrixObject *self);
-
-#endif /* __MATHUTILS_MATRIX_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index 7ce0ea5f249..2b7761b7678 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -962,11 +962,9 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
}
if (quat1 && quat2) { /* QUAT * QUAT (element-wise product) */
-#ifdef USE_MATHUTILS_ELEM_MUL
float quat[QUAT_SIZE];
mul_vn_vnvn(quat, quat1->quat, quat2->quat, QUAT_SIZE);
return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
-#endif
}
/* the only case this can happen (for a supported type is "FLOAT * QUAT") */
else if (quat2) { /* FLOAT * QUAT */
@@ -1007,17 +1005,8 @@ static PyObject *Quaternion_imul(PyObject *q1, PyObject *q2)
}
}
- if (quat1 && quat2) { /* QUAT *= QUAT (inplace element-wise product) */
-#ifdef USE_MATHUTILS_ELEM_MUL
+ if (quat1 && quat2) { /* QUAT *= QUAT (in-place element-wise product). */
mul_vn_vn(quat1->quat, quat2->quat, QUAT_SIZE);
-#else
- PyErr_Format(PyExc_TypeError,
- "In place element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(q1)->tp_name,
- Py_TYPE(q2)->tp_name);
- return NULL;
-#endif
}
else if (quat1 && (((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
/* QUAT *= FLOAT */
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.h b/source/blender/python/mathutils/mathutils_Quaternion.h
index bc6bd307ece..7d20558939e 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.h
+++ b/source/blender/python/mathutils/mathutils_Quaternion.h
@@ -14,8 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MATHUTILS_QUATERNION_H__
-#define __MATHUTILS_QUATERNION_H__
+#pragma once
/** \file
* \ingroup pymathutils
@@ -44,5 +43,3 @@ PyObject *Quaternion_CreatePyObject_wrap(float quat[4],
PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user,
unsigned char cb_type,
unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT;
-
-#endif /* __MATHUTILS_QUATERNION_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 15ae811fd91..4b47440a530 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -1738,7 +1738,7 @@ static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar);
return Vector_CreatePyObject_alloc(tvec, vec->size, Py_TYPE(vec));
}
-#ifdef USE_MATHUTILS_ELEM_MUL
+
static PyObject *vector_mul_vec(VectorObject *vec1, VectorObject *vec2)
{
float *tvec = PyMem_Malloc(vec1->size * sizeof(float));
@@ -1752,7 +1752,7 @@ static PyObject *vector_mul_vec(VectorObject *vec1, VectorObject *vec2)
mul_vn_vnvn(tvec, vec1->vec, vec2->vec, vec1->size);
return Vector_CreatePyObject_alloc(tvec, vec1->size, Py_TYPE(vec1));
}
-#endif
+
static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
{
VectorObject *vec1 = NULL, *vec2 = NULL;
@@ -1775,7 +1775,6 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
/* make sure v1 is always the vector */
if (vec1 && vec2) {
-#ifdef USE_MATHUTILS_ELEM_MUL
if (vec1->size != vec2->size) {
PyErr_SetString(PyExc_ValueError,
"Vector multiplication: "
@@ -1785,7 +1784,6 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
/* element-wise product */
return vector_mul_vec(vec1, vec2);
-#endif
}
else if (vec1) {
if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC * FLOAT */
@@ -1832,7 +1830,6 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
/* Intentionally don't support (Quaternion, Matrix) here, uses reverse order instead. */
if (vec1 && vec2) {
-#ifdef USE_MATHUTILS_ELEM_MUL
if (vec1->size != vec2->size) {
PyErr_SetString(PyExc_ValueError,
"Vector multiplication: "
@@ -1840,16 +1837,8 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
return NULL;
}
- /* element-wise product inplace */
+ /* Element-wise product in-place. */
mul_vn_vn(vec1->vec, vec2->vec, vec1->size);
-#else
- PyErr_Format(PyExc_TypeError,
- "In place element-wise multiplication: "
- "not supported between '%.200s' and '%.200s' types",
- Py_TYPE(v1)->tp_name,
- Py_TYPE(v2)->tp_name);
- return NULL;
-#endif
}
else if (vec1 && (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) ==
0)) { /* VEC *= FLOAT */
diff --git a/source/blender/python/mathutils/mathutils_Vector.h b/source/blender/python/mathutils/mathutils_Vector.h
index f75702bc54c..09fc429f9cc 100644
--- a/source/blender/python/mathutils/mathutils_Vector.h
+++ b/source/blender/python/mathutils/mathutils_Vector.h
@@ -18,8 +18,7 @@
* \ingroup pymathutils
*/
-#ifndef __MATHUTILS_VECTOR_H__
-#define __MATHUTILS_VECTOR_H__
+#pragma once
extern PyTypeObject vector_Type;
@@ -48,5 +47,3 @@ PyObject *Vector_CreatePyObject_alloc(float *vec,
const int size,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1);
-
-#endif /* __MATHUTILS_VECTOR_H__ */
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.h b/source/blender/python/mathutils/mathutils_bvhtree.h
index 2991982f3a2..82b09f11e5e 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.h
+++ b/source/blender/python/mathutils/mathutils_bvhtree.h
@@ -18,8 +18,7 @@
* \ingroup mathutils
*/
-#ifndef __MATHUTILS_BVHTREE_H__
-#define __MATHUTILS_BVHTREE_H__
+#pragma once
PyMODINIT_FUNC PyInit_mathutils_bvhtree(void);
@@ -27,5 +26,3 @@ extern PyTypeObject PyBVHTree_Type;
#define PyBVHTree_Check(v) PyObject_TypeCheck((v), &PyBVHTree_Type)
#define PyBVHTree_CheckExact(v) (Py_TYPE(v) == &PyBVHTree_Type)
-
-#endif /* __MATHUTILS_BVHTREE_H__ */
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 59c0021e0f3..93dbac32c19 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -1537,9 +1537,9 @@ static PyObject *M_Geometry_convex_hull_2d(PyObject *UNUSED(self), PyObject *poi
* to fill values, with start_table and len_table giving the start index
* and length of the toplevel_len sub-lists.
*/
-static PyObject *list_of_lists_from_arrays(int *array,
- int *start_table,
- int *len_table,
+static PyObject *list_of_lists_from_arrays(const int *array,
+ const int *start_table,
+ const int *len_table,
int toplevel_len)
{
PyObject *ret, *sublist;
diff --git a/source/blender/python/mathutils/mathutils_geometry.h b/source/blender/python/mathutils/mathutils_geometry.h
index 5a1198b4a26..4a200ec98ca 100644
--- a/source/blender/python/mathutils/mathutils_geometry.h
+++ b/source/blender/python/mathutils/mathutils_geometry.h
@@ -14,13 +14,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MATHUTILS_GEOMETRY_H__
-#define __MATHUTILS_GEOMETRY_H__
+#pragma once
/** \file
* \ingroup pymathutils
*/
PyMODINIT_FUNC PyInit_mathutils_geometry(void);
-
-#endif /* __MATHUTILS_GEOMETRY_H__ */
diff --git a/source/blender/python/mathutils/mathutils_interpolate.h b/source/blender/python/mathutils/mathutils_interpolate.h
index 50dee1ee8de..c51d2b6905b 100644
--- a/source/blender/python/mathutils/mathutils_interpolate.h
+++ b/source/blender/python/mathutils/mathutils_interpolate.h
@@ -14,13 +14,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MATHUTILS_INTERPOLATE_H__
-#define __MATHUTILS_INTERPOLATE_H__
+#pragma once
/** \file
* \ingroup pymathutils
*/
PyMODINIT_FUNC PyInit_mathutils_interpolate(void);
-
-#endif /* __MATHUTILS_INTERPOLATE_H__ */
diff --git a/source/blender/python/mathutils/mathutils_kdtree.h b/source/blender/python/mathutils/mathutils_kdtree.h
index 99411997282..3df3fc8d382 100644
--- a/source/blender/python/mathutils/mathutils_kdtree.h
+++ b/source/blender/python/mathutils/mathutils_kdtree.h
@@ -18,11 +18,8 @@
* \ingroup mathutils
*/
-#ifndef __MATHUTILS_KDTREE_H__
-#define __MATHUTILS_KDTREE_H__
+#pragma once
PyMODINIT_FUNC PyInit_mathutils_kdtree(void);
extern PyTypeObject PyKDTree_Type;
-
-#endif /* __MATHUTILS_KDTREE_H__ */
diff --git a/source/blender/python/mathutils/mathutils_noise.h b/source/blender/python/mathutils/mathutils_noise.h
index 8204c084947..da5e1a99a03 100644
--- a/source/blender/python/mathutils/mathutils_noise.h
+++ b/source/blender/python/mathutils/mathutils_noise.h
@@ -18,9 +18,6 @@
* \ingroup mathutils
*/
-#ifndef __MATHUTILS_NOISE_H__
-#define __MATHUTILS_NOISE_H__
+#pragma once
PyMODINIT_FUNC PyInit_mathutils_noise(void);
-
-#endif /* __MATHUTILS_NOISE_H__ */
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index f49c68a258d..e3c3cf712f9 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -32,7 +32,7 @@ set(INC
../makesdna
../makesrna
../nodes
- ../physics
+ ../simulation
../../../intern/atomic
../../../intern/guardedalloc
../../../intern/mikktspace
diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h
index 3bab9179f84..3ed41ede006 100644
--- a/source/blender/render/extern/include/RE_bake.h
+++ b/source/blender/render/extern/include/RE_bake.h
@@ -21,14 +21,17 @@
* \ingroup render
*/
-#ifndef __RE_BAKE_H__
-#define __RE_BAKE_H__
+#pragma once
struct Depsgraph;
struct ImBuf;
struct Mesh;
struct Render;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct BakeImage {
struct Image *image;
int width;
@@ -120,4 +123,6 @@ void RE_bake_normal_world_to_world(const BakePixel pixel_array[],
void RE_bake_ibuf_clear(struct Image *image, const bool is_tangent);
-#endif /* __RE_BAKE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 77a60854616..41f65fbda5c 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -21,8 +21,7 @@
* \ingroup render
*/
-#ifndef __RE_ENGINE_H__
-#define __RE_ENGINE_H__
+#pragma once
#include "DNA_listBase.h"
#include "DNA_node_types.h"
@@ -48,6 +47,10 @@ struct ViewLayer;
struct bNode;
struct bNodeTree;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* External Engine */
/* RenderEngineType.flag */
@@ -60,6 +63,7 @@ struct bNodeTree;
#define RE_USE_SHADING_NODES_CUSTOM 64
#define RE_USE_SPHERICAL_STEREO 128
#define RE_USE_STEREO_VIEWPORT 256
+#define RE_USE_GPU_CONTEXT 512
/* RenderEngine.flag */
#define RE_ENGINE_ANIMATION 1
@@ -236,4 +240,6 @@ void RE_bake_engine_set_engine_parameters(struct Render *re,
void RE_engine_free_blender_memory(struct RenderEngine *engine);
-#endif /* __RE_ENGINE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/render/extern/include/RE_multires_bake.h b/source/blender/render/extern/include/RE_multires_bake.h
index 6abd9be6608..c48ce7bfd6e 100644
--- a/source/blender/render/extern/include/RE_multires_bake.h
+++ b/source/blender/render/extern/include/RE_multires_bake.h
@@ -21,12 +21,15 @@
* \ingroup render
*/
-#ifndef __RE_MULTIRES_BAKE_H__
-#define __RE_MULTIRES_BAKE_H__
+#pragma once
struct MultiresBakeRender;
struct Scene;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct MultiresBakeRender {
Scene *scene;
DerivedMesh *lores_dm, *hires_dm;
@@ -63,4 +66,6 @@ typedef struct MultiresBakeRender {
void RE_multires_bake_images(struct MultiresBakeRender *bkr);
+#ifdef __cplusplus
+}
#endif
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index f9d2e915fad..c8cb537af39 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -21,8 +21,7 @@
* \ingroup render
*/
-#ifndef __RE_PIPELINE_H__
-#define __RE_PIPELINE_H__
+#pragma once
#include "DEG_depsgraph.h"
#include "DNA_listBase.h"
@@ -367,8 +366,8 @@ struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl,
#define RE_BAKE_AO 2
void RE_GetCameraWindow(struct Render *re, struct Object *camera, float mat[4][4]);
-void RE_GetCameraWindowWithOverscan(struct Render *re, float mat[4][4], float overscan);
-void RE_GetCameraModelMatrix(struct Render *re, struct Object *camera, float r_mat[4][4]);
+void RE_GetCameraWindowWithOverscan(struct Render *re, float overscan, float r_winmat[4][4]);
+void RE_GetCameraModelMatrix(struct Render *re, struct Object *camera, float r_modelmat[4][4]);
struct Scene *RE_GetScene(struct Render *re);
void RE_SetScene(struct Render *re, struct Scene *sce);
@@ -392,5 +391,3 @@ RenderResult *RE_DuplicateRenderResult(RenderResult *rr);
#ifdef __cplusplus
}
#endif
-
-#endif /* __RE_PIPELINE_H__ */
diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h
index bdf81354b8d..76812840c91 100644
--- a/source/blender/render/extern/include/RE_render_ext.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -20,8 +20,7 @@
* \ingroup render
*/
-#ifndef __RE_RENDER_EXT_H__
-#define __RE_RENDER_EXT_H__
+#pragma once
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* this include is for non-render pipeline exports (still old cruft here) */
@@ -32,6 +31,10 @@ struct Depsgraph;
struct ImagePool;
struct MTex;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* render_texture.c */
bool RE_texture_evaluate(const struct MTex *mtex,
const float vec[3],
@@ -72,4 +75,6 @@ void RE_point_density_free(struct PointDensity *pd);
void RE_point_density_fix_linking(void);
-#endif /* __RE_RENDER_EXT_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index f69ae4dfd5c..dc41afee938 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -20,8 +20,7 @@
* \ingroup render
*/
-#ifndef __RE_SHADER_EXT_H__
-#define __RE_SHADER_EXT_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -82,5 +81,3 @@ int multitex_nodes(struct Tex *tex,
#ifdef __cplusplus
}
#endif
-
-#endif /* __RE_SHADER_EXT_H__ */
diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h
index 99282a8e703..f5ac352752f 100644
--- a/source/blender/render/intern/include/initrender.h
+++ b/source/blender/render/intern/include/initrender.h
@@ -21,8 +21,11 @@
* \ingroup render
*/
-#ifndef __INITRENDER_H__
-#define __INITRENDER_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
/* Functions */
@@ -30,4 +33,6 @@ void RE_parts_init(Render *re);
void RE_parts_free(Render *re);
void RE_parts_clamp(Render *re);
-#endif /* __INITRENDER_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index 0ed8871b224..187685cd464 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -21,8 +21,7 @@
* \ingroup render
*/
-#ifndef __RENDER_RESULT_H__
-#define __RENDER_RESULT_H__
+#pragma once
#define PASS_VECTOR_MAX 10000.0f
@@ -44,6 +43,10 @@ struct RenderResult;
struct Scene;
struct rcti;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* New */
struct RenderResult *render_result_new(struct Render *re,
@@ -148,4 +151,6 @@ bool render_result_has_views(struct RenderResult *rr);
} \
((void)0)
-#endif /* __RENDER_RESULT_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 3ae4b9c0b90..6be5fb4792c 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -21,8 +21,7 @@
* \ingroup render
*/
-#ifndef __RENDER_TYPES_H__
-#define __RENDER_TYPES_H__
+#pragma once
/* ------------------------------------------------------------------------- */
/* exposed internal in render module only! */
@@ -43,6 +42,10 @@ struct Object;
struct RenderEngine;
struct ReportList;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* this is handed over to threaded hiding/passes/shading engine */
typedef struct RenderPart {
struct RenderPart *next, *prev;
@@ -160,4 +163,6 @@ struct Render {
/* R.flag */
#define R_ANIMATION 1
-#endif /* __RENDER_TYPES_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/render/intern/include/renderpipeline.h b/source/blender/render/intern/include/renderpipeline.h
index 12b231ef55f..062df59bfd3 100644
--- a/source/blender/render/intern/include/renderpipeline.h
+++ b/source/blender/render/intern/include/renderpipeline.h
@@ -21,8 +21,7 @@
* \ingroup render
*/
-#ifndef __RENDERPIPELINE_H__
-#define __RENDERPIPELINE_H__
+#pragma once
struct ListBase;
struct Render;
@@ -30,10 +29,16 @@ struct RenderData;
struct RenderLayer;
struct RenderResult;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct RenderLayer *render_get_active_layer(struct Render *re, struct RenderResult *rr);
void render_update_anim_renderdata(struct Render *re,
struct RenderData *rd,
struct ListBase *render_layers);
void render_copy_renderdata(struct RenderData *to, struct RenderData *from);
-#endif /* __RENDERPIPELINE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h
index f051d3ed318..22023baab95 100644
--- a/source/blender/render/intern/include/texture.h
+++ b/source/blender/render/intern/include/texture.h
@@ -21,8 +21,11 @@
* \ingroup render
*/
-#ifndef __TEXTURE_H__
-#define __TEXTURE_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
#define BRICONT \
texres->tin = (texres->tin - 0.5f) * tex->contrast + tex->bright - 0.5f; \
@@ -95,4 +98,6 @@ void image_sample(struct Image *ima,
float result[4],
struct ImagePool *pool);
-#endif /* __TEXTURE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h
index bc6addd6c5f..b898ff89ae4 100644
--- a/source/blender/render/intern/include/zbuf.h
+++ b/source/blender/render/intern/include/zbuf.h
@@ -18,8 +18,11 @@
* \ingroup render
*/
-#ifndef __ZBUF_H__
-#define __ZBUF_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
/* span fill in method, is also used to localize data for zbuffering */
typedef struct ZSpan {
@@ -40,4 +43,6 @@ void zspan_scanconvert(struct ZSpan *zpan,
float *v3,
void (*func)(void *, int, int, float, float));
+#ifdef __cplusplus
+}
#endif
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index 06f77854595..6e336604b59 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -694,14 +694,7 @@ void RE_bake_pixels_populate(Mesh *me,
const BakeImages *bake_images,
const char *uv_layer)
{
- BakeDataZSpan bd;
- size_t i;
- int a, p_id;
-
const MLoopUV *mloopuv;
- const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
- MLoopTri *looptri;
-
if ((uv_layer == NULL) || (uv_layer[0] == '\0')) {
mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
}
@@ -714,25 +707,26 @@ void RE_bake_pixels_populate(Mesh *me,
return;
}
+ BakeDataZSpan bd;
bd.pixel_array = pixel_array;
bd.zspan = MEM_callocN(sizeof(ZSpan) * bake_images->size, "bake zspan");
/* initialize all pixel arrays so we know which ones are 'blank' */
- for (i = 0; i < num_pixels; i++) {
+ for (int i = 0; i < num_pixels; i++) {
pixel_array[i].primitive_id = -1;
pixel_array[i].object_id = 0;
}
- for (i = 0; i < bake_images->size; i++) {
+ for (int i = 0; i < bake_images->size; i++) {
zbuf_alloc_span(&bd.zspan[i], bake_images->data[i].width, bake_images->data[i].height);
}
- looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
+ const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
+ MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
- p_id = -1;
- for (i = 0; i < tottri; i++) {
+ for (int i = 0; i < tottri; i++) {
const MLoopTri *lt = &looptri[i];
const MPoly *mp = &me->mpoly[lt->poly];
float vec[3][2];
@@ -744,9 +738,9 @@ void RE_bake_pixels_populate(Mesh *me,
}
bd.bk_image = &bake_images->data[image_id];
- bd.primitive_id = ++p_id;
+ bd.primitive_id = i;
- for (a = 0; a < 3; a++) {
+ for (int a = 0; a < 3; a++) {
const float *uv = mloopuv[lt->tri[a]].uv;
/* Note, workaround for pixel aligned UVs which are common and can screw up our
@@ -761,7 +755,7 @@ void RE_bake_pixels_populate(Mesh *me,
zspan_scanconvert(&bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel);
}
- for (i = 0; i < bake_images->size; i++) {
+ for (int i = 0; i < bake_images->size; i++) {
zbuf_free_span(&bd.zspan[i]);
}
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 5391775cab8..633b9324d9f 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -624,10 +624,6 @@ 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;
@@ -636,10 +632,6 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
BKE_scene_graph_update_for_newframe(engine->depsgraph, re->main);
BKE_scene_camera_switch_update(re->scene);
-
-#ifdef WITH_PYTHON
- BPy_END_ALLOW_THREADS;
-#endif
}
/* Bake */
@@ -871,8 +863,16 @@ int RE_engine_render(Render *re, int do_all)
re->draw_lock(re->dlh, 0);
}
+ if (engine->type->flag & RE_USE_GPU_CONTEXT) {
+ DRW_render_context_enable(engine->re);
+ }
+
type->render(engine, engine->depsgraph);
+ if (engine->type->flag & RE_USE_GPU_CONTEXT) {
+ DRW_render_context_disable(engine->re);
+ }
+
/* Grease pencil render over previous render result.
*
* NOTE: External engine might have been requested to free its
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 2e9f30397db..d631dd1a2ff 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -211,14 +211,14 @@ void RE_SetCamera(Render *re, Object *cam_ob)
re_camera_params_get(re, &params);
}
-void RE_GetCameraWindow(struct Render *re, struct Object *camera, float mat[4][4])
+void RE_GetCameraWindow(struct Render *re, struct Object *camera, float r_winmat[4][4])
{
RE_SetCamera(re, camera);
- copy_m4_m4(mat, re->winmat);
+ copy_m4_m4(r_winmat, re->winmat);
}
/* Must be called after RE_GetCameraWindow(), does not change re->winmat. */
-void RE_GetCameraWindowWithOverscan(struct Render *re, float mat[4][4], float overscan)
+void RE_GetCameraWindowWithOverscan(struct Render *re, float overscan, float r_winmat[4][4])
{
CameraParams params;
params.is_ortho = re->winmat[3][3] != 0.0f;
@@ -233,12 +233,12 @@ void RE_GetCameraWindowWithOverscan(struct Render *re, float mat[4][4], float ov
params.viewplane.ymin -= overscan;
params.viewplane.ymax += overscan;
BKE_camera_params_compute_matrix(&params);
- copy_m4_m4(mat, params.winmat);
+ copy_m4_m4(r_winmat, params.winmat);
}
-void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_mat[4][4])
+void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_modelmat[4][4])
{
- BKE_camera_multiview_model_matrix(&re->r, camera, re->viewname, r_mat);
+ BKE_camera_multiview_model_matrix(&re->r, camera, re->viewname, r_modelmat);
}
/* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index 7c301f7d591..b30821a1b73 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -1319,8 +1319,11 @@ static void bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter)
}
}
-static void bake_ibuf_normalize_displacement(
- ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max)
+static void bake_ibuf_normalize_displacement(ImBuf *ibuf,
+ const float *displacement,
+ const char *mask,
+ float displacement_min,
+ float displacement_max)
{
int i;
const float *current_displacement = displacement;
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index b335862abe0..fa53ad522a6 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1879,14 +1879,14 @@ const char *RE_GetActiveRenderView(Render *re)
}
/* evaluating scene options for general Blender render */
-static int render_initialize_from_main(Render *re,
- const RenderData *rd,
- Main *bmain,
- Scene *scene,
- ViewLayer *single_layer,
- Object *camera_override,
- int anim,
- int anim_init)
+static int render_init_from_main(Render *re,
+ const RenderData *rd,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *single_layer,
+ Object *camera_override,
+ int anim,
+ int anim_init)
{
int winx, winy;
rcti disprect;
@@ -2004,8 +2004,7 @@ void RE_RenderFrame(Render *re,
scene->r.cfra = frame;
- if (render_initialize_from_main(
- re, &scene->r, bmain, scene, single_layer, camera_override, 0, 0)) {
+ if (render_init_from_main(re, &scene->r, bmain, scene, single_layer, camera_override, 0, 0)) {
const RenderData rd = scene->r;
MEM_reset_peak_memory();
@@ -2058,7 +2057,7 @@ void RE_RenderFrame(Render *re,
void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render)
{
re->result_ok = 0;
- if (render_initialize_from_main(re, &scene->r, bmain, scene, NULL, NULL, 0, 0)) {
+ if (render_init_from_main(re, &scene->r, bmain, scene, NULL, NULL, 0, 0)) {
if (render) {
do_render_3d(re);
}
@@ -2422,7 +2421,7 @@ void RE_RenderAnim(Render *re,
(rd.im_format.views_format == R_IMF_VIEWS_INDIVIDUAL));
/* do not fully call for each frame, it initializes & pops output window */
- if (!render_initialize_from_main(re, &rd, bmain, scene, single_layer, camera_override, 0, 1)) {
+ if (!render_init_from_main(re, &rd, bmain, scene, single_layer, camera_override, 0, 1)) {
return;
}
@@ -2493,13 +2492,15 @@ void RE_RenderAnim(Render *re,
{
float ctime = BKE_scene_frame_get(scene);
AnimData *adt = BKE_animdata_from_id(&scene->id);
- BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, ADT_RECALC_ALL, false);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ re->pipeline_depsgraph, ctime);
+ BKE_animsys_evaluate_animdata(&scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false);
}
render_update_depsgraph(re);
/* only border now, todo: camera lens. (ton) */
- render_initialize_from_main(re, &rd, bmain, scene, single_layer, camera_override, 1, 0);
+ render_init_from_main(re, &rd, bmain, scene, single_layer, camera_override, 1, 0);
if (nfra != scene->r.cfra) {
/* Skip this frame, but could update for physics and particles system. */
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 8daad33b477..c49cf6203e0 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -557,7 +557,7 @@ static float density_falloff(PointDensityRangeData *pdr, int index, float square
}
if (pdr->density_curve && dist != 0.0f) {
- BKE_curvemapping_initialize(pdr->density_curve);
+ BKE_curvemapping_init(pdr->density_curve);
density = BKE_curvemapping_evaluateF(pdr->density_curve, 0, density / dist) * dist;
}
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 9926e08c968..b37eeed3681 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -902,7 +902,7 @@ static void do_2d_mapping(
float fx, fy, fac1, area[8];
int ok, proj, areaflag = 0, wrap;
- /* mtex variables localized, only cubemap doesn't cooperate yet... */
+ /* #MTex variables localized, only cube-map doesn't cooperate yet. */
wrap = mtex->mapping;
tex = mtex->tex;
diff --git a/source/blender/shader_fx/CMakeLists.txt b/source/blender/shader_fx/CMakeLists.txt
index 740f7c126d1..a12f36f9713 100644
--- a/source/blender/shader_fx/CMakeLists.txt
+++ b/source/blender/shader_fx/CMakeLists.txt
@@ -24,8 +24,8 @@ set(INC
intern
../blenfont
../blenkernel
- ../blentranslation
../blenlib
+ ../blentranslation
../bmesh
../depsgraph
../editors/include
diff --git a/source/blender/shader_fx/FX_shader_types.h b/source/blender/shader_fx/FX_shader_types.h
index f338f9bcc2a..54d3f98bdd4 100644
--- a/source/blender/shader_fx/FX_shader_types.h
+++ b/source/blender/shader_fx/FX_shader_types.h
@@ -18,8 +18,7 @@
* \ingroup shader_fx
*/
-#ifndef __FX_SHADER_TYPES_H__
-#define __FX_SHADER_TYPES_H__
+#pragma once
#include "BKE_shader_fx.h"
@@ -38,5 +37,3 @@ extern ShaderFxTypeInfo shaderfx_Type_Wave;
/* FX_shaderfx_util.c */
void shaderfx_type_init(ShaderFxTypeInfo *types[]);
-
-#endif /* __FX_SHADER_TYPES_H__ */
diff --git a/source/blender/shader_fx/intern/FX_shader_rim.c b/source/blender/shader_fx/intern/FX_shader_rim.c
index eaaa10af54c..82e1d151cb6 100644
--- a/source/blender/shader_fx/intern/FX_shader_rim.c
+++ b/source/blender/shader_fx/intern/FX_shader_rim.c
@@ -72,11 +72,11 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(layout, &ptr, "mask_color", 0, NULL, ICON_NONE);
uiItemR(layout, &ptr, "mode", 0, IFACE_("Blend Mode"), ICON_NONE);
- /* Add the X, Z labels manually because offset is a #PROP_PIXEL. */
+ /* Add the X, Y labels manually because offset is a #PROP_PIXEL. */
col = uiLayoutColumn(layout, true);
PropertyRNA *prop = RNA_struct_find_property(&ptr, "offset");
uiItemFullR(col, &ptr, prop, 0, 0, 0, IFACE_("Offset X"), ICON_NONE);
- uiItemFullR(col, &ptr, prop, 1, 0, 0, IFACE_("Z"), ICON_NONE);
+ uiItemFullR(col, &ptr, prop, 1, 0, 0, IFACE_("Y"), ICON_NONE);
shaderfx_panel_end(layout, &ptr);
}
@@ -91,11 +91,11 @@ static void blur_panel_draw(const bContext *C, Panel *panel)
uiLayoutSetPropSep(layout, true);
- /* Add the X, Z labels manually because blur is a #PROP_PIXEL. */
+ /* Add the X, Y labels manually because blur is a #PROP_PIXEL. */
col = uiLayoutColumn(layout, true);
PropertyRNA *prop = RNA_struct_find_property(&ptr, "blur");
uiItemFullR(col, &ptr, prop, 0, 0, 0, IFACE_("Blur X"), ICON_NONE);
- uiItemFullR(col, &ptr, prop, 1, 0, 0, IFACE_("Z"), ICON_NONE);
+ uiItemFullR(col, &ptr, prop, 1, 0, 0, IFACE_("Y"), ICON_NONE);
uiItemR(layout, &ptr, "samples", 0, NULL, ICON_NONE);
}
diff --git a/source/blender/shader_fx/intern/FX_shader_util.h b/source/blender/shader_fx/intern/FX_shader_util.h
index 8ff5a6c0d0e..9617cfd2ee0 100644
--- a/source/blender/shader_fx/intern/FX_shader_util.h
+++ b/source/blender/shader_fx/intern/FX_shader_util.h
@@ -21,7 +21,4 @@
* \ingroup shader_fx
*/
-#ifndef __FX_SHADER_UTIL_H__
-#define __FX_SHADER_UTIL_H__
-
-#endif /* __FX_SHADER_UTIL_H__ */
+#pragma once
diff --git a/source/blender/shader_fx/intern/FX_ui_common.c b/source/blender/shader_fx/intern/FX_ui_common.c
index 3a1df937c9f..952a6df560b 100644
--- a/source/blender/shader_fx/intern/FX_ui_common.c
+++ b/source/blender/shader_fx/intern/FX_ui_common.c
@@ -32,7 +32,6 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_shader_fx_types.h"
-#include "DNA_space_types.h"
#include "ED_object.h"
@@ -48,17 +47,6 @@
#include "FX_ui_common.h" /* Self include */
-static Object *get_context_object(const bContext *C)
-{
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
- if (sbuts != NULL && (sbuts->pinid != NULL) && GS(sbuts->pinid->name) == ID_OB) {
- return (Object *)sbuts->pinid;
- }
- else {
- return CTX_data_active_object(C);
- }
-}
-
/* -------------------------------------------------------------------- */
/** \name Panel Drag and Drop, Expansion Saving
* \{ */
@@ -68,7 +56,7 @@ static Object *get_context_object(const bContext *C)
*/
static void shaderfx_reorder(bContext *C, Panel *panel, int new_index)
{
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
ShaderFxData *fx = BLI_findlink(&ob->shader_fx, panel->runtime.list_index);
PointerRNA props_ptr;
@@ -77,6 +65,7 @@ static void shaderfx_reorder(bContext *C, Panel *panel, int new_index)
RNA_string_set(&props_ptr, "shaderfx", fx->name);
RNA_int_set(&props_ptr, "index", new_index);
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
+ WM_operator_properties_free(&props_ptr);
}
/**
@@ -84,7 +73,7 @@ static void shaderfx_reorder(bContext *C, Panel *panel, int new_index)
*/
static short get_shaderfx_expand_flag(const bContext *C, Panel *panel)
{
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
ShaderFxData *fx = BLI_findlink(&ob->shader_fx, panel->runtime.list_index);
return fx->ui_expand_flag;
}
@@ -94,7 +83,7 @@ static short get_shaderfx_expand_flag(const bContext *C, Panel *panel)
*/
static void set_shaderfx_expand_flag(const bContext *C, Panel *panel, short expand_flag)
{
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
ShaderFxData *fx = BLI_findlink(&ob->shader_fx, panel->runtime.list_index);
fx->ui_expand_flag = expand_flag;
}
@@ -125,7 +114,7 @@ void shaderfx_panel_get_property_pointers(const bContext *C,
PointerRNA *r_ob_ptr,
PointerRNA *r_md_ptr)
{
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
ShaderFxData *md = BLI_findlink(&ob->shader_fx, panel->runtime.list_index);
RNA_pointer_create(&ob->id, &RNA_ShaderFx, md, r_md_ptr);
@@ -146,7 +135,7 @@ static void shaderfx_panel_header(const bContext *C, Panel *panel)
PointerRNA ptr;
shaderfx_panel_get_property_pointers(C, panel, NULL, &ptr);
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
ShaderFxData *fx = (ShaderFxData *)ptr.data;
const ShaderFxTypeInfo *fxti = BKE_shaderfx_get_info(fx->type);
@@ -191,7 +180,7 @@ static void shaderfx_panel_header(const bContext *C, Panel *panel)
static bool shaderfx_ui_poll(const bContext *C, PanelType *UNUSED(pt))
{
- Object *ob = get_context_object(C);
+ Object *ob = ED_object_active_context(C);
return (ob != NULL) && (ob->type == OB_GPENCIL);
}
diff --git a/source/blender/shader_fx/intern/FX_ui_common.h b/source/blender/shader_fx/intern/FX_ui_common.h
index 877855b98e4..ce3038776ba 100644
--- a/source/blender/shader_fx/intern/FX_ui_common.h
+++ b/source/blender/shader_fx/intern/FX_ui_common.h
@@ -18,8 +18,7 @@
* \ingroup modifiers
*/
-#ifndef __FX_UI_COMMON_H__
-#define __FX_UI_COMMON_H__
+#pragma once
#include "FX_shader_types.h"
@@ -52,5 +51,3 @@ struct PanelType *shaderfx_subpanel_register(struct ARegionType *region_type,
#ifdef __cplusplus
}
#endif
-
-#endif /* __FX_UI_COMMON_H__ */
diff --git a/source/blender/physics/CMakeLists.txt b/source/blender/simulation/CMakeLists.txt
index 10520a18513..cbc6ee65303 100644
--- a/source/blender/physics/CMakeLists.txt
+++ b/source/blender/simulation/CMakeLists.txt
@@ -24,8 +24,11 @@ set(INC
../blenkernel
../blenlib
../depsgraph
+ ../functions
../imbuf
../makesdna
+ ../makesrna
+ ../nodes
../../../intern/guardedalloc
)
@@ -34,18 +37,36 @@ set(INC_SYS
)
set(SRC
- intern/BPH_mass_spring.cpp
- intern/ConstrainedConjugateGradient.h
- intern/eigen_utils.h
+ intern/SIM_mass_spring.cpp
intern/hair_volume.cpp
- intern/implicit.h
intern/implicit_blender.c
intern/implicit_eigen.cpp
+ intern/particle_allocator.cc
+ intern/particle_function.cc
+ intern/particle_mesh_emitter.cc
+ intern/simulation_collect_influences.cc
+ intern/simulation_solver_influences.cc
+ intern/simulation_solver.cc
+ intern/simulation_update.cc
+
+ intern/ConstrainedConjugateGradient.h
+ intern/eigen_utils.h
+ intern/implicit.h
+ intern/particle_allocator.hh
+ intern/particle_function.hh
+ intern/particle_mesh_emitter.hh
+ intern/simulation_collect_influences.hh
+ intern/simulation_solver_influences.hh
+ intern/simulation_solver.hh
+ intern/time_interval.hh
- BPH_mass_spring.h
+ SIM_mass_spring.h
+ SIM_simulation_update.hh
)
set(LIB
+ bf_blenkernel
+ bf_nodes
)
if(WITH_OPENMP_STATIC)
@@ -54,4 +75,4 @@ if(WITH_OPENMP_STATIC)
)
endif()
-blender_add_lib(bf_physics "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+blender_add_lib(bf_simulation "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/physics/BPH_mass_spring.h b/source/blender/simulation/SIM_mass_spring.h
index 5a8c78812a4..219ead477c2 100644
--- a/source/blender/physics/BPH_mass_spring.h
+++ b/source/blender/simulation/SIM_mass_spring.h
@@ -21,8 +21,7 @@
* \ingroup bph
*/
-#ifndef __BPH_MASS_SPRING_H__
-#define __BPH_MASS_SPRING_H__
+#pragma once
#ifdef __cplusplus
extern "C" {
@@ -35,28 +34,26 @@ struct ListBase;
struct Object;
typedef enum eMassSpringSolverStatus {
- BPH_SOLVER_SUCCESS = (1 << 0),
- BPH_SOLVER_NUMERICAL_ISSUE = (1 << 1),
- BPH_SOLVER_NO_CONVERGENCE = (1 << 2),
- BPH_SOLVER_INVALID_INPUT = (1 << 3),
+ SIM_SOLVER_SUCCESS = (1 << 0),
+ SIM_SOLVER_NUMERICAL_ISSUE = (1 << 1),
+ SIM_SOLVER_NO_CONVERGENCE = (1 << 2),
+ SIM_SOLVER_INVALID_INPUT = (1 << 3),
} eMassSpringSolverStatus;
-struct Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings);
-void BPH_mass_spring_solver_free(struct Implicit_Data *id);
-int BPH_mass_spring_solver_numvert(struct Implicit_Data *id);
+struct Implicit_Data *SIM_mass_spring_solver_create(int numverts, int numsprings);
+void SIM_mass_spring_solver_free(struct Implicit_Data *id);
+int SIM_mass_spring_solver_numvert(struct Implicit_Data *id);
-int BPH_cloth_solver_init(struct Object *ob, struct ClothModifierData *clmd);
-void BPH_cloth_solver_free(struct ClothModifierData *clmd);
-int BPH_cloth_solve(struct Depsgraph *depsgraph,
+int SIM_cloth_solver_init(struct Object *ob, struct ClothModifierData *clmd);
+void SIM_cloth_solver_free(struct ClothModifierData *clmd);
+int SIM_cloth_solve(struct Depsgraph *depsgraph,
struct Object *ob,
float frame,
struct ClothModifierData *clmd,
struct ListBase *effectors);
-void BKE_cloth_solver_set_positions(struct ClothModifierData *clmd);
-void BKE_cloth_solver_set_volume(ClothModifierData *clmd);
+void SIM_cloth_solver_set_positions(struct ClothModifierData *clmd);
+void SIM_cloth_solver_set_volume(ClothModifierData *clmd);
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/simulation/SIM_simulation_update.hh b/source/blender/simulation/SIM_simulation_update.hh
new file mode 100644
index 00000000000..7c2726f038e
--- /dev/null
+++ b/source/blender/simulation/SIM_simulation_update.hh
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+struct Depsgraph;
+struct Scene;
+struct Simulation;
+
+namespace blender::sim {
+
+void update_simulation_in_depsgraph(Depsgraph *depsgraph,
+ Scene *scene_cow,
+ Simulation *simulation_cow);
+
+bool update_simulation_dependencies(Simulation *simulation);
+
+} // namespace blender::sim
diff --git a/source/blender/physics/intern/ConstrainedConjugateGradient.h b/source/blender/simulation/intern/ConstrainedConjugateGradient.h
index c924490f97d..b0f2bb037d2 100644
--- a/source/blender/physics/intern/ConstrainedConjugateGradient.h
+++ b/source/blender/simulation/intern/ConstrainedConjugateGradient.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __CONSTRAINEDCONJUGATEGRADIENT_H__
-#define __CONSTRAINEDCONJUGATEGRADIENT_H__
+#pragma once
#include <Eigen/Core>
@@ -331,5 +330,3 @@ struct solve_retval<ConstrainedConjugateGradient<_MatrixType, _UpLo, _Filter, _P
} // end namespace internal
} // end namespace Eigen
-
-#endif // __CONSTRAINEDCONJUGATEGRADIENT_H__
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/simulation/intern/SIM_mass_spring.cpp
index 051f11aa1d9..4834d6d351c 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/simulation/intern/SIM_mass_spring.cpp
@@ -38,7 +38,7 @@
#include "BKE_collision.h"
#include "BKE_effect.h"
-#include "BPH_mass_spring.h"
+#include "SIM_mass_spring.h"
#include "implicit.h"
#include "DEG_depsgraph.h"
@@ -104,7 +104,7 @@ static void cloth_calc_pressure_gradient(ClothModifierData *clmd,
float pt[3];
for (unsigned int i = 0; i < mvert_num; i++) {
- BPH_mass_spring_get_position(data, i, pt);
+ SIM_mass_spring_get_position(data, i, pt);
r_vertex_pressure[i] = dot_v3v3(pt, gradient_vector);
}
}
@@ -127,7 +127,7 @@ static float cloth_calc_volume(ClothModifierData *clmd)
const MVertTri *vt = &tri[i];
if (cloth_get_pressure_weights(clmd, vt, weights)) {
- vol += BPH_tri_tetra_volume_signed_6x(data, vt->tri[0], vt->tri[1], vt->tri[2]);
+ vol += SIM_tri_tetra_volume_signed_6x(data, vt->tri[0], vt->tri[1], vt->tri[2]);
}
}
@@ -179,7 +179,7 @@ static float cloth_calc_average_pressure(ClothModifierData *clmd, const float *v
const MVertTri *vt = &tri[i];
if (cloth_get_pressure_weights(clmd, vt, weights)) {
- float area = BPH_tri_area(data, vt->tri[0], vt->tri[1], vt->tri[2]);
+ float area = SIM_tri_area(data, vt->tri[0], vt->tri[1], vt->tri[2]);
total_force += (vertex_pressure[vt->tri[0]] + vertex_pressure[vt->tri[1]] +
vertex_pressure[vt->tri[2]]) *
@@ -191,7 +191,7 @@ static float cloth_calc_average_pressure(ClothModifierData *clmd, const float *v
return total_force / total_area;
}
-int BPH_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
+int SIM_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts;
@@ -200,30 +200,30 @@ int BPH_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
unsigned int i, nondiag;
nondiag = cloth_count_nondiag_blocks(cloth);
- cloth->implicit = id = BPH_mass_spring_solver_create(cloth->mvert_num, nondiag);
+ cloth->implicit = id = SIM_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);
+ SIM_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);
+ SIM_mass_spring_set_motion_state(id, i, verts[i].x, ZERO);
}
return 1;
}
-void BPH_cloth_solver_free(ClothModifierData *clmd)
+void SIM_cloth_solver_free(ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
if (cloth->implicit) {
- BPH_mass_spring_solver_free(cloth->implicit);
+ SIM_mass_spring_solver_free(cloth->implicit);
cloth->implicit = NULL;
}
}
-void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
+void SIM_cloth_solver_set_positions(ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
ClothVertex *verts = cloth->verts;
@@ -234,17 +234,17 @@ void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
for (i = 0; i < mvert_num; i++) {
if (cloth_hairdata) {
ClothHairData *root = &cloth_hairdata[i];
- BPH_mass_spring_set_rest_transform(id, i, root->rot);
+ SIM_mass_spring_set_rest_transform(id, i, root->rot);
}
else {
- BPH_mass_spring_set_rest_transform(id, i, I3);
+ SIM_mass_spring_set_rest_transform(id, i, I3);
}
- BPH_mass_spring_set_motion_state(id, i, verts[i].x, verts[i].v);
+ SIM_mass_spring_set_motion_state(id, i, verts[i].x, verts[i].v);
}
}
-void BKE_cloth_solver_set_volume(ClothModifierData *clmd)
+void SIM_cloth_solver_set_volume(ClothModifierData *clmd)
{
Cloth *cloth = clmd->clothObject;
@@ -265,12 +265,12 @@ static void cloth_setup_constraints(ClothModifierData *clmd)
const float ZERO[3] = {0.0f, 0.0f, 0.0f};
- BPH_mass_spring_clear_constraints(data);
+ SIM_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 */
+ SIM_mass_spring_add_constraint_ndof0(data, v, ZERO); /* velocity is defined externally */
}
verts[v].impulse_count = 0;
@@ -388,7 +388,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
k = scaling * s->restlen *
0.1f; /* Multiplying by 0.1, just to scale the forces to more reasonable values. */
- BPH_mass_spring_force_spring_angular(
+ SIM_mass_spring_force_spring_angular(
data, s->ij, s->kl, s->pa, s->pb, s->la, s->lb, s->restang, k, parms->bending_damping);
#endif
}
@@ -409,7 +409,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
/* 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
* tunneling through collision objects. */
- BPH_mass_spring_force_spring_linear(data,
+ SIM_mass_spring_force_spring_linear(data,
s->ij,
s->kl,
s->restlen,
@@ -427,7 +427,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
s->lin_stiffness * fabsf(parms->max_compression - parms->compression);
k_compression = scaling_compression / (parms->avg_spring_len + FLT_EPSILON);
- BPH_mass_spring_force_spring_linear(data,
+ SIM_mass_spring_force_spring_linear(data,
s->ij,
s->kl,
s->restlen,
@@ -465,7 +465,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
k_compression_damp = 0.0f;
}
- BPH_mass_spring_force_spring_linear(data,
+ SIM_mass_spring_force_spring_linear(data,
s->ij,
s->kl,
s->restlen,
@@ -488,7 +488,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
scaling = parms->shear + s->lin_stiffness * fabsf(parms->max_shear - parms->shear);
k = scaling / (parms->avg_spring_len + FLT_EPSILON);
- BPH_mass_spring_force_spring_linear(data,
+ SIM_mass_spring_force_spring_linear(data,
s->ij,
s->kl,
s->restlen,
@@ -513,7 +513,7 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
// 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);
+ SIM_mass_spring_force_spring_bending(data, s->ij, s->kl, s->restlen, kb, cb);
#endif
}
else if (s->type & CLOTH_SPRING_TYPE_BENDING_HAIR) {
@@ -534,14 +534,14 @@ BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s)
/* XXX assuming same restlen for ij and jk segments here,
* this can be done correctly for hair later. */
- BPH_mass_spring_force_spring_bending_hair(data, s->ij, s->kl, s->mn, s->target, kb, cb);
+ SIM_mass_spring_force_spring_bending_hair(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);
+ SIM_mass_spring_get_motion_state(data, s->kl, x_kl, v);
+ SIM_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(
@@ -569,7 +569,7 @@ static void hair_get_boundbox(ClothModifierData *clmd, float gmin[3], float gmax
INIT_MINMAX(gmin, gmax);
for (i = 0; i < mvert_num; i++) {
float x[3];
- BPH_mass_spring_get_motion_state(data, i, x, NULL);
+ SIM_mass_spring_get_motion_state(data, i, x, NULL);
DO_MINMAX(x, gmin, gmax);
}
}
@@ -599,7 +599,7 @@ static void cloth_calc_force(
vert = cloth->verts;
for (i = 0; i < cloth->mvert_num; i++, vert++) {
- BPH_mass_spring_force_gravity(data, i, vert->mass, gravity);
+ SIM_mass_spring_force_gravity(data, i, vert->mass, gravity);
/* Vertex goal springs */
if ((!(vert->flags & CLOTH_VERT_FLAG_PINNED)) && (vert->goal > FLT_EPSILON)) {
@@ -613,7 +613,7 @@ static void cloth_calc_force(
k = vert->goal * clmd->sim_parms->goalspring /
(clmd->sim_parms->avg_spring_len + FLT_EPSILON);
- BPH_mass_spring_force_spring_goal(
+ SIM_mass_spring_force_spring_goal(
data, i, goal_x, goal_v, k, clmd->sim_parms->goalfrict * 0.01f);
}
}
@@ -622,7 +622,7 @@ static void cloth_calc_force(
/* cloth_calc_volume_force(clmd); */
#ifdef CLOTH_FORCE_DRAG
- BPH_mass_spring_force_drag(data, drag);
+ SIM_mass_spring_force_drag(data, drag);
#endif
/* handle pressure forces (making sure that this never gets computed for hair). */
if ((parms->flags & CLOTH_SIMSETTINGS_FLAG_PRESSURE) && (clmd->hairdata == NULL)) {
@@ -694,7 +694,7 @@ static void cloth_calc_force(
const MVertTri *vt = &tri[i];
if (cloth_get_pressure_weights(clmd, vt, weights)) {
- BPH_mass_spring_force_pressure(data,
+ SIM_mass_spring_force_pressure(data,
vt->tri[0],
vt->tri[1],
vt->tri[2],
@@ -724,7 +724,7 @@ static void cloth_calc_force(
float x[3], v[3];
EffectedPoint epoint;
- BPH_mass_spring_get_motion_state(data, i, x, v);
+ SIM_mass_spring_get_motion_state(data, i, x, v);
pd_point_from_loc(scene, x, v, i, &epoint);
BKE_effectors_apply(effectors,
NULL,
@@ -743,10 +743,10 @@ static void cloth_calc_force(
for (i = 0; i < cloth->primitive_num; i++) {
const MVertTri *vt = &tri[i];
if (has_wind) {
- BPH_mass_spring_force_face_wind(data, vt->tri[0], vt->tri[1], vt->tri[2], winvec);
+ SIM_mass_spring_force_face_wind(data, vt->tri[0], vt->tri[1], vt->tri[2], winvec);
}
if (has_force) {
- BPH_mass_spring_force_face_extern(data, vt->tri[0], vt->tri[1], vt->tri[2], forcevec);
+ SIM_mass_spring_force_face_extern(data, vt->tri[0], vt->tri[1], vt->tri[2], forcevec);
}
}
}
@@ -761,11 +761,11 @@ static void cloth_calc_force(
if (hairdata) {
hair_ij = &hairdata[spring->ij];
hair_kl = &hairdata[spring->kl];
- BPH_mass_spring_force_edge_wind(
+ SIM_mass_spring_force_edge_wind(
data, spring->ij, spring->kl, hair_ij->radius, hair_kl->radius, winvec);
}
else {
- BPH_mass_spring_force_edge_wind(data, spring->ij, spring->kl, 1.0f, 1.0f, winvec);
+ SIM_mass_spring_force_edge_wind(data, spring->ij, spring->kl, 1.0f, 1.0f, winvec);
}
}
}
@@ -776,10 +776,10 @@ static void cloth_calc_force(
for (i = 0; i < cloth->mvert_num; i++, vert++) {
if (hairdata) {
ClothHairData *hair = &hairdata[i];
- BPH_mass_spring_force_vertex_wind(data, i, hair->radius, winvec);
+ SIM_mass_spring_force_vertex_wind(data, i, hair->radius, winvec);
}
else {
- BPH_mass_spring_force_vertex_wind(data, i, 1.0f, winvec);
+ SIM_mass_spring_force_vertex_wind(data, i, 1.0f, winvec);
}
}
#endif
@@ -806,8 +806,8 @@ BLI_INLINE void cloth_get_grid_location(Implicit_Data *data,
float x[3],
float v[3])
{
- BPH_mass_spring_get_position(data, index, x);
- BPH_mass_spring_get_new_velocity(data, index, v);
+ SIM_mass_spring_get_position(data, index, x);
+ SIM_mass_spring_get_new_velocity(data, index, v);
mul_v3_fl(x, cell_scale);
add_v3_v3(x, cell_offset);
@@ -902,7 +902,7 @@ static LinkNode *cloth_continuum_add_hair_segments(HairGrid *grid,
zero_v3(dir3);
}
- BPH_hair_volume_add_segment(
+ SIM_hair_volume_add_segment(
grid, x1, v1, x2, v2, x3, v3, x4, v4, spring1 ? dir1 : NULL, dir2, spring3 ? dir3 : NULL);
}
@@ -921,7 +921,7 @@ static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
float x[3], v[3];
cloth_get_vertex_motion_state(data, vert, x, v);
- BPH_hair_volume_add_vertex(grid, x, v);
+ SIM_hair_volume_add_vertex(grid, x, v);
}
#else
LinkNode *link;
@@ -930,7 +930,7 @@ static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
/* scale and offset for transforming vertex locations into grid space
* (cell size is 0..1, gmin becomes origin)
*/
- BPH_hair_volume_grid_geometry(grid, &cellsize, NULL, gmin, NULL);
+ SIM_hair_volume_grid_geometry(grid, &cellsize, NULL, gmin, NULL);
cell_scale = cellsize > 0.0f ? 1.0f / cellsize : 0.0f;
mul_v3_v3fl(cell_offset, gmin, cell_scale);
negate_v3(cell_offset);
@@ -946,7 +946,7 @@ static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
}
}
#endif
- BPH_hair_volume_normalize_vertex_grid(grid);
+ SIM_hair_volume_normalize_vertex_grid(grid);
}
static void cloth_continuum_step(ClothModifierData *clmd, float dt)
@@ -977,31 +977,31 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
/* gather velocities & density */
if (smoothfac > 0.0f || density_strength > 0.0f) {
- HairGrid *grid = BPH_hair_volume_create_vertex_grid(
+ HairGrid *grid = SIM_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);
+ SIM_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);
+ SIM_mass_spring_get_position(data, i, x);
+ SIM_mass_spring_get_new_velocity(data, i, v);
- BPH_hair_volume_grid_velocity(grid, x, v, fluid_factor, nv);
+ SIM_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);
+ SIM_mass_spring_set_new_velocity(data, i, nv);
}
/* store basic grid info in the modifier data */
- BPH_hair_volume_grid_geometry(grid,
+ SIM_hair_volume_grid_geometry(grid,
&clmd->hair_grid_cellsize,
clmd->hair_grid_res,
clmd->hair_grid_min,
@@ -1034,7 +1034,7 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
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);
+ SIM_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,
@@ -1074,7 +1074,7 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
}
#endif
- BPH_hair_volume_free_vertex_grid(grid);
+ SIM_hair_volume_free_vertex_grid(grid);
}
}
@@ -1099,7 +1099,7 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
/* gather velocities & density */
if (smoothfac > 0.0f || pressfac > 0.0f) {
- HairVertexGrid *vertex_grid = BPH_hair_volume_create_vertex_grid(
+ HairVertexGrid *vertex_grid = SIM_hair_volume_create_vertex_grid(
clmd->sim_parms->voxel_res, gmin, gmax);
vert = cloth->verts;
@@ -1111,11 +1111,11 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
copy_v3_v3(v, vert->v);
}
else {
- BPH_mass_spring_get_motion_state(data, vert->solver_index, x, v);
+ SIM_mass_spring_get_motion_state(data, vert->solver_index, x, v);
}
- BPH_hair_volume_add_vertex(vertex_grid, x, v);
+ SIM_hair_volume_add_vertex(vertex_grid, x, v);
}
- BPH_hair_volume_normalize_vertex_grid(vertex_grid);
+ SIM_hair_volume_normalize_vertex_grid(vertex_grid);
vert = cloth->verts;
for (i = 0; i < mvert_num; i++, vert++) {
@@ -1126,14 +1126,14 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
}
/* calculate volumetric forces */
- BPH_mass_spring_get_motion_state(data, vert->solver_index, x, v);
- BPH_hair_volume_vertex_grid_forces(
+ SIM_mass_spring_get_motion_state(data, vert->solver_index, x, v);
+ SIM_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);
+ SIM_mass_spring_force_extern(data, vert->solver_index, f, dfdx, dfdv);
}
- BPH_hair_volume_free_vertex_grid(vertex_grid);
+ SIM_hair_volume_free_vertex_grid(vertex_grid);
}
}
#endif
@@ -1148,8 +1148,8 @@ static void cloth_calc_average_acceleration(ClothModifierData *clmd, float dt)
for (i = 0; i < mvert_num; i++) {
float v[3], nv[3];
- BPH_mass_spring_get_velocity(data, i, v);
- BPH_mass_spring_get_new_velocity(data, i, nv);
+ SIM_mass_spring_get_velocity(data, i, v);
+ SIM_mass_spring_get_new_velocity(data, i, nv);
sub_v3_v3(nv, v);
add_v3_v3(total, nv);
@@ -1181,11 +1181,11 @@ static void cloth_solve_collisions(
return;
}
- BPH_mass_spring_solve_positions(id, dt);
+ SIM_mass_spring_solve_positions(id, dt);
/* Update verts to current positions. */
for (i = 0; i < mvert_num; i++) {
- BPH_mass_spring_get_new_position(id, i, verts[i].tx);
+ SIM_mass_spring_get_new_position(id, i, verts[i].tx);
sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
zero_v3(verts[i].dcvel);
@@ -1201,9 +1201,9 @@ static void cloth_solve_collisions(
continue;
}
- BPH_mass_spring_get_new_velocity(id, i, verts[i].tv);
+ SIM_mass_spring_get_new_velocity(id, i, verts[i].tv);
madd_v3_v3fl(verts[i].tv, verts[i].dcvel, time_multiplier);
- BPH_mass_spring_set_new_velocity(id, i, verts[i].tv);
+ SIM_mass_spring_set_new_velocity(id, i, verts[i].tv);
}
}
}
@@ -1224,7 +1224,7 @@ static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *r
if (sres->status) { /* already initialized ? */
/* error only makes sense for successful iterations */
- if (result->status == BPH_SOLVER_SUCCESS) {
+ if (result->status == SIM_SOLVER_SUCCESS) {
sres->min_error = min_ff(sres->min_error, result->error);
sres->max_error = max_ff(sres->max_error, result->error);
sres->avg_error += result->error * dt;
@@ -1236,7 +1236,7 @@ static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *r
}
else {
/* error only makes sense for successful iterations */
- if (result->status == BPH_SOLVER_SUCCESS) {
+ if (result->status == SIM_SOLVER_SUCCESS) {
sres->min_error = sres->max_error = result->error;
sres->avg_error += result->error * dt;
}
@@ -1248,7 +1248,7 @@ static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *r
sres->status |= result->status;
}
-int BPH_cloth_solve(
+int SIM_cloth_solve(
Depsgraph *depsgraph, Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
{
/* Hair currently is a cloth sim in disguise ...
@@ -1287,7 +1287,7 @@ int BPH_cloth_solve(
// mul_v3_fl(v, clmd->sim_parms->stepsPerFrame);
/* divide by time_scale to prevent constrained velocities from being multiplied */
mul_v3_fl(v, 1.0f / clmd->sim_parms->time_scale);
- BPH_mass_spring_set_velocity(id, i, v);
+ SIM_mass_spring_set_velocity(id, i, v);
}
}
}
@@ -1303,13 +1303,13 @@ int BPH_cloth_solve(
cloth_setup_constraints(clmd);
/* initialize forces to zero */
- BPH_mass_spring_clear_forces(id);
+ SIM_mass_spring_clear_forces(id);
// calculate forces
cloth_calc_force(scene, clmd, frame, effectors, step);
// calculate new velocity and position
- BPH_mass_spring_solve_velocities(id, dt, &result);
+ SIM_mass_spring_solve_velocities(id, dt, &result);
cloth_record_result(clmd, &result, dt);
/* Calculate collision impulses. */
@@ -1323,8 +1323,8 @@ int BPH_cloth_solve(
cloth_calc_average_acceleration(clmd, dt);
}
- BPH_mass_spring_solve_positions(id, dt);
- BPH_mass_spring_apply_result(id);
+ SIM_mass_spring_solve_positions(id, dt);
+ SIM_mass_spring_apply_result(id);
/* move pinned verts to correct position */
for (i = 0; i < mvert_num; i++) {
@@ -1335,11 +1335,11 @@ int BPH_cloth_solve(
* delta locations from being multiplied */
interp_v3_v3v3(
x, verts[i].xold, verts[i].xconst, (step + dt) / clmd->sim_parms->time_scale);
- BPH_mass_spring_set_position(id, i, x);
+ SIM_mass_spring_set_position(id, i, x);
}
}
- BPH_mass_spring_get_motion_state(id, i, verts[i].txold, NULL);
+ SIM_mass_spring_get_motion_state(id, i, verts[i].txold, NULL);
}
step += dt;
@@ -1347,7 +1347,7 @@ int BPH_cloth_solve(
/* 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);
+ SIM_mass_spring_get_motion_state(id, i, verts[i].x, verts[i].v);
copy_v3_v3(verts[i].txold, verts[i].x);
}
diff --git a/source/blender/physics/intern/eigen_utils.h b/source/blender/simulation/intern/eigen_utils.h
index c186cf567df..897ba8b2a67 100644
--- a/source/blender/physics/intern/eigen_utils.h
+++ b/source/blender/simulation/intern/eigen_utils.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __EIGEN_UTILS_H__
-#define __EIGEN_UTILS_H__
+#pragma once
/** \file
* \ingroup bph
@@ -232,5 +231,3 @@ BLI_INLINE void print_lmatrix(const lMatrix &m)
printf("\n");
}
}
-
-#endif
diff --git a/source/blender/physics/intern/hair_volume.cpp b/source/blender/simulation/intern/hair_volume.cpp
index 6246bf54f75..c80ae69ce73 100644
--- a/source/blender/physics/intern/hair_volume.cpp
+++ b/source/blender/simulation/intern/hair_volume.cpp
@@ -205,7 +205,7 @@ BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid,
}
}
-void BPH_hair_volume_vertex_grid_forces(HairGrid *grid,
+void SIM_hair_volume_vertex_grid_forces(HairGrid *grid,
const float x[3],
const float v[3],
float smoothfac,
@@ -244,7 +244,7 @@ void BPH_hair_volume_vertex_grid_forces(HairGrid *grid,
mul_m3_fl(dfdv, smoothfac);
}
-void BPH_hair_volume_grid_interpolate(HairGrid *grid,
+void SIM_hair_volume_grid_interpolate(HairGrid *grid,
const float x[3],
float *density,
float velocity[3],
@@ -264,7 +264,7 @@ void BPH_hair_volume_grid_interpolate(HairGrid *grid,
velocity_gradient);
}
-void BPH_hair_volume_grid_velocity(
+void SIM_hair_volume_grid_velocity(
HairGrid *grid, const float x[3], const float v[3], float fluid_factor, float r_v[3])
{
float gdensity, gvelocity[3], gvel_smooth[3], ggrad[3], gvelgrad[3][3];
@@ -291,7 +291,7 @@ void BPH_hair_volume_grid_velocity(
interp_v3_v3v3(r_v, v_pic, v_flip, fluid_factor);
}
-void BPH_hair_volume_grid_clear(HairGrid *grid)
+void SIM_hair_volume_grid_clear(HairGrid *grid)
{
const int size = hair_grid_size(grid->res);
int i;
@@ -303,7 +303,7 @@ void BPH_hair_volume_grid_clear(HairGrid *grid)
}
}
-BLI_INLINE bool hair_grid_point_valid(const float vec[3], float gmin[3], float gmax[3])
+BLI_INLINE bool hair_grid_point_valid(const float vec[3], const float gmin[3], const float gmax[3])
{
return !(vec[0] < gmin[0] || vec[1] < gmin[1] || vec[2] < gmin[2] || vec[0] > gmax[0] ||
vec[1] > gmax[1] || vec[2] > gmax[2]);
@@ -362,7 +362,7 @@ BLI_INLINE void grid_to_world(HairGrid *grid, float vecw[3], const float vec[3])
add_v3_v3(vecw, grid->gmin);
}
-void BPH_hair_volume_add_vertex(HairGrid *grid, const float x[3], const float v[3])
+void SIM_hair_volume_add_vertex(HairGrid *grid, const float x[3], const float v[3])
{
const int res[3] = {grid->res[0], grid->res[1], grid->res[2]};
float weights[8];
@@ -503,7 +503,7 @@ BLI_INLINE void hair_volume_add_segment_2D(HairGrid *grid,
* The radius of influence around a segment is assumed to be at most 2*cellsize,
* i.e. only cells containing the segment and their direct neighbors are examined.
*/
-void BPH_hair_volume_add_segment(HairGrid *grid,
+void SIM_hair_volume_add_segment(HairGrid *grid,
const float x1[3],
const float v1[3],
const float x2[3],
@@ -633,7 +633,7 @@ BLI_INLINE void hair_volume_eval_grid_vertex_sample(HairGridVert *vert,
/* XXX simplified test implementation using a series of discrete sample along the segment,
* instead of finding the closest point for all affected grid vertices.
*/
-void BPH_hair_volume_add_segment(HairGrid *grid,
+void SIM_hair_volume_add_segment(HairGrid *grid,
const float UNUSED(x1[3]),
const float UNUSED(v1[3]),
const float x2[3],
@@ -684,7 +684,7 @@ void BPH_hair_volume_add_segment(HairGrid *grid,
}
#endif
-void BPH_hair_volume_normalize_vertex_grid(HairGrid *grid)
+void SIM_hair_volume_normalize_vertex_grid(HairGrid *grid)
{
int i, size = hair_grid_size(grid->res);
/* divide velocity with density */
@@ -715,7 +715,7 @@ BLI_INLINE float hair_volume_density_divergence(float density,
}
}
-bool BPH_hair_volume_solve_divergence(HairGrid *grid,
+bool SIM_hair_volume_solve_divergence(HairGrid *grid,
float /*dt*/,
float target_density,
float target_strength)
@@ -1078,7 +1078,7 @@ BLI_INLINE void hair_volume_filter_box_convolute(
}
}
-void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_size)
+void SIM_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_size)
{
int size = hair_grid_size(grid->res);
int kernel_sizev[3] = {kernel_size, kernel_size, kernel_size};
@@ -1113,7 +1113,7 @@ void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_siz
}
#endif
-HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize,
+HairGrid *SIM_hair_volume_create_vertex_grid(float cellsize,
const float gmin[3],
const float gmax[3])
{
@@ -1170,7 +1170,7 @@ HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize,
return grid;
}
-void BPH_hair_volume_free_vertex_grid(HairGrid *grid)
+void SIM_hair_volume_free_vertex_grid(HairGrid *grid)
{
if (grid) {
if (grid->verts) {
@@ -1180,7 +1180,7 @@ void BPH_hair_volume_free_vertex_grid(HairGrid *grid)
}
}
-void BPH_hair_volume_grid_geometry(
+void SIM_hair_volume_grid_geometry(
HairGrid *grid, float *cellsize, int res[3], float gmin[3], float gmax[3])
{
if (cellsize) {
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/simulation/intern/implicit.h
index 8bc09755180..a3c8e5f34c4 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/simulation/intern/implicit.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __IMPLICIT_H__
-#define __IMPLICIT_H__
+#pragma once
/** \file
* \ingroup bph
@@ -65,87 +64,87 @@ BLI_INLINE void implicit_print_matrix_elem(float v)
printf("%-8.3f", v);
}
-void BPH_mass_spring_set_vertex_mass(struct Implicit_Data *data, int index, float mass);
-void BPH_mass_spring_set_rest_transform(struct Implicit_Data *data, int index, float rot[3][3]);
+void SIM_mass_spring_set_vertex_mass(struct Implicit_Data *data, int index, float mass);
+void SIM_mass_spring_set_rest_transform(struct Implicit_Data *data, int index, float rot[3][3]);
-void BPH_mass_spring_set_motion_state(struct Implicit_Data *data,
+void SIM_mass_spring_set_motion_state(struct Implicit_Data *data,
int index,
const float x[3],
const float v[3]);
-void BPH_mass_spring_set_position(struct Implicit_Data *data, int index, const float x[3]);
-void BPH_mass_spring_set_velocity(struct Implicit_Data *data, int index, const float v[3]);
-void BPH_mass_spring_get_motion_state(struct Implicit_Data *data,
+void SIM_mass_spring_set_position(struct Implicit_Data *data, int index, const float x[3]);
+void SIM_mass_spring_set_velocity(struct Implicit_Data *data, int index, const float v[3]);
+void SIM_mass_spring_get_motion_state(struct Implicit_Data *data,
int index,
float x[3],
float v[3]);
-void BPH_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3]);
-void BPH_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3]);
+void SIM_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3]);
+void SIM_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3]);
/* access to modified motion state during solver step */
-void BPH_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3]);
-void BPH_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3]);
-void BPH_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3]);
-void BPH_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3]);
+void SIM_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3]);
+void SIM_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3]);
+void SIM_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3]);
+void SIM_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3]);
-void BPH_mass_spring_clear_constraints(struct Implicit_Data *data);
-void BPH_mass_spring_add_constraint_ndof0(struct Implicit_Data *data,
+void SIM_mass_spring_clear_constraints(struct Implicit_Data *data);
+void SIM_mass_spring_add_constraint_ndof0(struct Implicit_Data *data,
int index,
const float dV[3]);
-void BPH_mass_spring_add_constraint_ndof1(struct Implicit_Data *data,
+void SIM_mass_spring_add_constraint_ndof1(struct Implicit_Data *data,
int index,
const float c1[3],
const float c2[3],
const float dV[3]);
-void BPH_mass_spring_add_constraint_ndof2(struct Implicit_Data *data,
+void SIM_mass_spring_add_constraint_ndof2(struct Implicit_Data *data,
int index,
const float c1[3],
const float dV[3]);
-bool BPH_mass_spring_solve_velocities(struct Implicit_Data *data,
+bool SIM_mass_spring_solve_velocities(struct Implicit_Data *data,
float dt,
struct ImplicitSolverResult *result);
-bool BPH_mass_spring_solve_positions(struct Implicit_Data *data, float dt);
-void BPH_mass_spring_apply_result(struct Implicit_Data *data);
+bool SIM_mass_spring_solve_positions(struct Implicit_Data *data, float dt);
+void SIM_mass_spring_apply_result(struct Implicit_Data *data);
/* Clear the force vector at the beginning of the time step */
-void BPH_mass_spring_clear_forces(struct Implicit_Data *data);
+void SIM_mass_spring_clear_forces(struct Implicit_Data *data);
/* Fictitious forces introduced by moving coordinate systems */
-void BPH_mass_spring_force_reference_frame(struct Implicit_Data *data,
+void SIM_mass_spring_force_reference_frame(struct Implicit_Data *data,
int index,
const float acceleration[3],
const float omega[3],
const float domega_dt[3],
float mass);
/* Simple uniform gravity force */
-void BPH_mass_spring_force_gravity(struct Implicit_Data *data,
+void SIM_mass_spring_force_gravity(struct Implicit_Data *data,
int index,
float mass,
const float g[3]);
/* Global drag force (velocity damping) */
-void BPH_mass_spring_force_drag(struct Implicit_Data *data, float drag);
+void SIM_mass_spring_force_drag(struct Implicit_Data *data, float drag);
/* Custom external force */
-void BPH_mass_spring_force_extern(
+void SIM_mass_spring_force_extern(
struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3]);
/* Wind force, acting on a face (only generates pressure from the normal component) */
-void BPH_mass_spring_force_face_wind(
+void SIM_mass_spring_force_face_wind(
struct Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3]);
/* Arbitrary per-unit-area vector force field acting on a face. */
-void BPH_mass_spring_force_face_extern(
+void SIM_mass_spring_force_face_extern(
struct Implicit_Data *data, int v1, int v2, int v3, const float (*forcevec)[3]);
/* Wind force, acting on an edge */
-void BPH_mass_spring_force_edge_wind(struct Implicit_Data *data,
+void SIM_mass_spring_force_edge_wind(struct Implicit_Data *data,
int v1,
int v2,
float radius1,
float radius2,
const float (*winvec)[3]);
/* Wind force, acting on a vertex */
-void BPH_mass_spring_force_vertex_wind(struct Implicit_Data *data,
+void SIM_mass_spring_force_vertex_wind(struct Implicit_Data *data,
int v,
float radius,
const float (*winvec)[3]);
/* Linear spring force between two points */
-bool BPH_mass_spring_force_spring_linear(struct Implicit_Data *data,
+bool SIM_mass_spring_force_spring_linear(struct Implicit_Data *data,
int i,
int j,
float restlen,
@@ -157,7 +156,7 @@ bool BPH_mass_spring_force_spring_linear(struct Implicit_Data *data,
bool new_compress,
float clamp_force);
/* Angular spring force between two polygons */
-bool BPH_mass_spring_force_spring_angular(struct Implicit_Data *data,
+bool SIM_mass_spring_force_spring_angular(struct Implicit_Data *data,
int i,
int j,
int *i_a,
@@ -168,10 +167,10 @@ bool BPH_mass_spring_force_spring_angular(struct Implicit_Data *data,
float stiffness,
float damping);
/* Bending force, forming a triangle at the base of two structural springs */
-bool BPH_mass_spring_force_spring_bending(
+bool SIM_mass_spring_force_spring_bending(
struct Implicit_Data *data, int i, int j, float restlen, float kb, float cb);
/* Angular bending force based on local target vectors */
-bool BPH_mass_spring_force_spring_bending_hair(struct Implicit_Data *data,
+bool SIM_mass_spring_force_spring_bending_hair(struct Implicit_Data *data,
int i,
int j,
int k,
@@ -179,17 +178,17 @@ bool BPH_mass_spring_force_spring_bending_hair(struct Implicit_Data *data,
float stiffness,
float damping);
/* Global goal spring */
-bool BPH_mass_spring_force_spring_goal(struct Implicit_Data *data,
+bool SIM_mass_spring_force_spring_goal(struct Implicit_Data *data,
int i,
const float goal_x[3],
const float goal_v[3],
float stiffness,
float damping);
-float BPH_tri_tetra_volume_signed_6x(struct Implicit_Data *data, int v1, int v2, int v3);
-float BPH_tri_area(struct Implicit_Data *data, int v1, int v2, int v3);
+float SIM_tri_tetra_volume_signed_6x(struct Implicit_Data *data, int v1, int v2, int v3);
+float SIM_tri_area(struct Implicit_Data *data, int v1, int v2, int v3);
-void BPH_mass_spring_force_pressure(struct Implicit_Data *data,
+void SIM_mass_spring_force_pressure(struct Implicit_Data *data,
int v1,
int v2,
int v3,
@@ -203,16 +202,16 @@ struct HairGrid;
#define MAX_HAIR_GRID_RES 256
-struct HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize,
+struct HairGrid *SIM_hair_volume_create_vertex_grid(float cellsize,
const float gmin[3],
const float gmax[3]);
-void BPH_hair_volume_free_vertex_grid(struct HairGrid *grid);
-void BPH_hair_volume_grid_geometry(
+void SIM_hair_volume_free_vertex_grid(struct HairGrid *grid);
+void SIM_hair_volume_grid_geometry(
struct HairGrid *grid, float *cellsize, int res[3], float gmin[3], float gmax[3]);
-void BPH_hair_volume_grid_clear(struct HairGrid *grid);
-void BPH_hair_volume_add_vertex(struct HairGrid *grid, const float x[3], const float v[3]);
-void BPH_hair_volume_add_segment(struct HairGrid *grid,
+void SIM_hair_volume_grid_clear(struct HairGrid *grid);
+void SIM_hair_volume_add_vertex(struct HairGrid *grid, const float x[3], const float v[3]);
+void SIM_hair_volume_add_segment(struct HairGrid *grid,
const float x1[3],
const float v1[3],
const float x2[3],
@@ -225,17 +224,17 @@ void BPH_hair_volume_add_segment(struct HairGrid *grid,
const float dir2[3],
const float dir3[3]);
-void BPH_hair_volume_normalize_vertex_grid(struct HairGrid *grid);
+void SIM_hair_volume_normalize_vertex_grid(struct HairGrid *grid);
-bool BPH_hair_volume_solve_divergence(struct HairGrid *grid,
+bool SIM_hair_volume_solve_divergence(struct HairGrid *grid,
float dt,
float target_density,
float target_strength);
#if 0 /* XXX weighting is incorrect, disabled for now */
-void BPH_hair_volume_vertex_grid_filter_box(struct HairVertexGrid *grid, int kernel_size);
+void SIM_hair_volume_vertex_grid_filter_box(struct HairVertexGrid *grid, int kernel_size);
#endif
-void BPH_hair_volume_grid_interpolate(struct HairGrid *grid,
+void SIM_hair_volume_grid_interpolate(struct HairGrid *grid,
const float x[3],
float *density,
float velocity[3],
@@ -247,7 +246,7 @@ void BPH_hair_volume_grid_interpolate(struct HairGrid *grid,
* fluid_factor controls blending between PIC (Particle-in-Cell)
* and FLIP (Fluid-Implicit-Particle) methods (0 = only PIC, 1 = only FLIP)
*/
-void BPH_hair_volume_grid_velocity(
+void SIM_hair_volume_grid_velocity(
struct HairGrid *grid, const float x[3], const float v[3], float fluid_factor, float r_v[3]);
/* XXX Warning: expressing grid effects on velocity as a force is not very stable,
* due to discontinuities in interpolated values!
@@ -255,7 +254,7 @@ void BPH_hair_volume_grid_velocity(
* "Detail Preserving Continuum Simulation of Straight Hair"
* (McAdams, Selle 2009)
*/
-void BPH_hair_volume_vertex_grid_forces(struct HairGrid *grid,
+void SIM_hair_volume_vertex_grid_forces(struct HairGrid *grid,
const float x[3],
const float v[3],
float smoothfac,
@@ -268,5 +267,3 @@ void BPH_hair_volume_vertex_grid_forces(struct HairGrid *grid,
#ifdef __cplusplus
}
#endif
-
-#endif
diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/simulation/intern/implicit_blender.c
index 5ec4c750d5d..856572aa3f5 100644
--- a/source/blender/physics/intern/implicit_blender.c
+++ b/source/blender/simulation/intern/implicit_blender.c
@@ -40,7 +40,7 @@
# include "BKE_collision.h"
# include "BKE_effect.h"
-# include "BPH_mass_spring.h"
+# include "SIM_mass_spring.h"
# ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wtype-limits"
@@ -90,7 +90,7 @@ typedef struct fmatrix3x3 {
///////////////////////////
/* simple vector code */
/* STATUS: verified */
-DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar)
+DO_INLINE void mul_fvector_S(float to[3], const float from[3], float scalar)
{
to[0] = from[0] * scalar;
to[1] = from[1] * scalar;
@@ -429,7 +429,7 @@ DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar)
/* a vector multiplied by a 3x3 matrix */
/* STATUS: verified */
-DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][3])
+DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, float matrix[3][3])
{
to[0] = matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2];
to[1] = matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2];
@@ -478,7 +478,7 @@ DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float fro
to[2] += dot_v3v3(matrix[2], from);
}
-DO_INLINE void muladd_fmatrixT_fvector(float to[3], float matrix[3][3], float from[3])
+DO_INLINE void muladd_fmatrixT_fvector(float to[3], float matrix[3][3], const float from[3])
{
to[0] += matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2];
to[1] += matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2];
@@ -679,7 +679,7 @@ typedef struct Implicit_Data {
fmatrix3x3 *P, *Pinv; /* pre-conditioning matrix */
} Implicit_Data;
-Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings)
+Implicit_Data *SIM_mass_spring_solver_create(int numverts, int numsprings)
{
Implicit_Data *id = (Implicit_Data *)MEM_callocN(sizeof(Implicit_Data), "implicit vecmat");
@@ -707,7 +707,7 @@ Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings)
return id;
}
-void BPH_mass_spring_solver_free(Implicit_Data *id)
+void SIM_mass_spring_solver_free(Implicit_Data *id)
{
del_bfmatrix(id->tfm);
del_bfmatrix(id->A);
@@ -924,8 +924,8 @@ static int cg_filtered(lfVector *ldV,
del_lfvector(s);
// printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount);
- result->status = conjgrad_loopcount < conjgrad_looplimit ? BPH_SOLVER_SUCCESS :
- BPH_SOLVER_NO_CONVERGENCE;
+ result->status = conjgrad_loopcount < conjgrad_looplimit ? SIM_SOLVER_SUCCESS :
+ SIM_SOLVER_NO_CONVERGENCE;
result->iterations = conjgrad_loopcount;
result->error = bnorm2 > 0.0f ? sqrtf(delta_new / bnorm2) : 0.0f;
@@ -1139,7 +1139,7 @@ static int cg_filtered_pre(lfVector *dv,
}
# endif
-bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSolverResult *result)
+bool SIM_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSolverResult *result)
{
unsigned int numverts = data->dFdV[0].vcount;
@@ -1173,10 +1173,10 @@ bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSol
del_lfvector(dFdXmV);
- return result->status == BPH_SOLVER_SUCCESS;
+ return result->status == SIM_SOLVER_SUCCESS;
}
-bool BPH_mass_spring_solve_positions(Implicit_Data *data, float dt)
+bool SIM_mass_spring_solve_positions(Implicit_Data *data, float dt)
{
int numverts = data->M[0].vcount;
@@ -1186,20 +1186,20 @@ bool BPH_mass_spring_solve_positions(Implicit_Data *data, float dt)
return true;
}
-void BPH_mass_spring_apply_result(Implicit_Data *data)
+void SIM_mass_spring_apply_result(Implicit_Data *data)
{
int numverts = data->M[0].vcount;
cp_lfvector(data->X, data->Xnew, numverts);
cp_lfvector(data->V, data->Vnew, numverts);
}
-void BPH_mass_spring_set_vertex_mass(Implicit_Data *data, int index, float mass)
+void SIM_mass_spring_set_vertex_mass(Implicit_Data *data, int index, float mass)
{
unit_m3(data->M[index].m);
mul_m3_fl(data->M[index].m, mass);
}
-void BPH_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tfm[3][3])
+void SIM_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tfm[3][3])
{
# ifdef CLOTH_ROOT_FRAME
copy_m3_m3(data->tfm[index].m, tfm);
@@ -1209,7 +1209,7 @@ void BPH_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tf
# endif
}
-void BPH_mass_spring_set_motion_state(Implicit_Data *data,
+void SIM_mass_spring_set_motion_state(Implicit_Data *data,
int index,
const float x[3],
const float v[3])
@@ -1218,17 +1218,17 @@ void BPH_mass_spring_set_motion_state(Implicit_Data *data,
world_to_root_v3(data, index, data->V[index], v);
}
-void BPH_mass_spring_set_position(Implicit_Data *data, int index, const float x[3])
+void SIM_mass_spring_set_position(Implicit_Data *data, int index, const float x[3])
{
world_to_root_v3(data, index, data->X[index], x);
}
-void BPH_mass_spring_set_velocity(Implicit_Data *data, int index, const float v[3])
+void SIM_mass_spring_set_velocity(Implicit_Data *data, int index, const float v[3])
{
world_to_root_v3(data, index, data->V[index], v);
}
-void BPH_mass_spring_get_motion_state(struct Implicit_Data *data,
+void SIM_mass_spring_get_motion_state(struct Implicit_Data *data,
int index,
float x[3],
float v[3])
@@ -1241,39 +1241,39 @@ void BPH_mass_spring_get_motion_state(struct Implicit_Data *data,
}
}
-void BPH_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
+void SIM_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
{
root_to_world_v3(data, index, x, data->X[index]);
}
-void BPH_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3])
+void SIM_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3])
{
root_to_world_v3(data, index, v, data->V[index]);
}
-void BPH_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3])
+void SIM_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3])
{
root_to_world_v3(data, index, x, data->Xnew[index]);
}
-void BPH_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3])
+void SIM_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3])
{
world_to_root_v3(data, index, data->Xnew[index], x);
}
-void BPH_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3])
+void SIM_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3])
{
root_to_world_v3(data, index, v, data->Vnew[index]);
}
-void BPH_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3])
+void SIM_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3])
{
world_to_root_v3(data, index, data->Vnew[index], v);
}
/* -------------------------------- */
-static int BPH_mass_spring_add_block(Implicit_Data *data, int v1, int v2)
+static int SIM_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);
@@ -1291,7 +1291,7 @@ static int BPH_mass_spring_add_block(Implicit_Data *data, int v1, int v2)
return s;
}
-void BPH_mass_spring_clear_constraints(Implicit_Data *data)
+void SIM_mass_spring_clear_constraints(Implicit_Data *data)
{
int i, numverts = data->S[0].vcount;
for (i = 0; i < numverts; i++) {
@@ -1300,14 +1300,14 @@ 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])
+void SIM_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(
+void SIM_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];
@@ -1328,7 +1328,7 @@ void BPH_mass_spring_add_constraint_ndof1(
add_v3_v3(data->z[index], u);
}
-void BPH_mass_spring_add_constraint_ndof2(Implicit_Data *data,
+void SIM_mass_spring_add_constraint_ndof2(Implicit_Data *data,
int index,
const float c1[3],
const float dV[3])
@@ -1346,7 +1346,7 @@ void BPH_mass_spring_add_constraint_ndof2(Implicit_Data *data,
add_v3_v3(data->z[index], u);
}
-void BPH_mass_spring_clear_forces(Implicit_Data *data)
+void SIM_mass_spring_clear_forces(Implicit_Data *data)
{
int numverts = data->M[0].vcount;
zero_lfvector(data->F, numverts);
@@ -1356,7 +1356,7 @@ void BPH_mass_spring_clear_forces(Implicit_Data *data)
data->num_blocks = 0;
}
-void BPH_mass_spring_force_reference_frame(Implicit_Data *data,
+void SIM_mass_spring_force_reference_frame(Implicit_Data *data,
int index,
const float acceleration[3],
const float omega[3],
@@ -1411,7 +1411,7 @@ void BPH_mass_spring_force_reference_frame(Implicit_Data *data,
# endif
}
-void BPH_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, const float g[3])
+void SIM_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, const float g[3])
{
/* force = mass * acceleration (in this case: gravity) */
float f[3];
@@ -1421,7 +1421,7 @@ void BPH_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, c
add_v3_v3(data->F[index], f);
}
-void BPH_mass_spring_force_drag(Implicit_Data *data, float drag)
+void SIM_mass_spring_force_drag(Implicit_Data *data, float drag)
{
int i, numverts = data->M[0].vcount;
for (i = 0; i < numverts; i++) {
@@ -1436,7 +1436,7 @@ void BPH_mass_spring_force_drag(Implicit_Data *data, float drag)
}
}
-void BPH_mass_spring_force_extern(
+void SIM_mass_spring_force_extern(
struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3])
{
float tf[3], tdfdx[3][3], tdfdv[3][3];
@@ -1465,7 +1465,7 @@ static float calc_nor_area_tri(float nor[3],
/* XXX does not support force jacobians yet, since the effector system does not provide them either
*/
-void BPH_mass_spring_force_face_wind(
+void SIM_mass_spring_force_face_wind(
Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3])
{
const float effector_scale = 0.02f;
@@ -1505,7 +1505,7 @@ void BPH_mass_spring_force_face_wind(
madd_v3_v3fl(data->F[v3], nor, base_force + force[2]);
}
-void BPH_mass_spring_force_face_extern(
+void SIM_mass_spring_force_face_extern(
Implicit_Data *data, int v1, int v2, int v3, const float (*forcevec)[3])
{
const float effector_scale = 0.02f;
@@ -1536,20 +1536,20 @@ void BPH_mass_spring_force_face_extern(
}
}
-float BPH_tri_tetra_volume_signed_6x(Implicit_Data *data, int v1, int v2, int v3)
+float SIM_tri_tetra_volume_signed_6x(Implicit_Data *data, int v1, int v2, int v3)
{
/* The result will be 6x the volume */
return volume_tri_tetrahedron_signed_v3_6x(data->X[v1], data->X[v2], data->X[v3]);
}
-float BPH_tri_area(struct Implicit_Data *data, int v1, int v2, int v3)
+float SIM_tri_area(struct Implicit_Data *data, int v1, int v2, int v3)
{
float nor[3];
return calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
}
-void BPH_mass_spring_force_pressure(Implicit_Data *data,
+void SIM_mass_spring_force_pressure(Implicit_Data *data,
int v1,
int v2,
int v3,
@@ -1617,7 +1617,7 @@ static void edge_wind_vertex(const float dir[3],
mul_v3_v3fl(f, wind, density * cross_section);
}
-void BPH_mass_spring_force_edge_wind(
+void SIM_mass_spring_force_edge_wind(
Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float (*winvec)[3])
{
float win[3], dir[3], length;
@@ -1635,7 +1635,7 @@ void BPH_mass_spring_force_edge_wind(
add_v3_v3(data->F[v2], f);
}
-void BPH_mass_spring_force_vertex_wind(Implicit_Data *data,
+void SIM_mass_spring_force_vertex_wind(Implicit_Data *data,
int v,
float UNUSED(radius),
const float (*winvec)[3])
@@ -1766,7 +1766,7 @@ BLI_INLINE bool spring_length(Implicit_Data *data,
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);
+ int block_ij = SIM_mass_spring_add_block(data, i, j);
add_v3_v3(data->F[i], f);
sub_v3_v3(data->F[j], f);
@@ -1780,7 +1780,7 @@ BLI_INLINE void apply_spring(
sub_m3_m3m3(data->dFdV[block_ij].m, data->dFdV[block_ij].m, dfdv);
}
-bool BPH_mass_spring_force_spring_linear(Implicit_Data *data,
+bool SIM_mass_spring_force_spring_linear(Implicit_Data *data,
int i,
int j,
float restlen,
@@ -1841,7 +1841,7 @@ bool BPH_mass_spring_force_spring_linear(Implicit_Data *data,
}
/* See "Stable but Responsive Cloth" (Choi, Ko 2005) */
-bool BPH_mass_spring_force_spring_bending(
+bool SIM_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];
@@ -1869,7 +1869,7 @@ bool BPH_mass_spring_force_spring_bending(
}
}
-BLI_INLINE void poly_avg(lfVector *data, int *inds, int len, float r_avg[3])
+BLI_INLINE void poly_avg(lfVector *data, const int *inds, int len, float r_avg[3])
{
float fact = 1.0f / (float)len;
@@ -1948,7 +1948,7 @@ BLI_INLINE void spring_angle(Implicit_Data *data,
/* Angular springs roughly based on the bending model proposed by Baraff and Witkin in "Large Steps
* in Cloth Simulation". */
-bool BPH_mass_spring_force_spring_angular(Implicit_Data *data,
+bool SIM_mass_spring_force_spring_angular(Implicit_Data *data,
int i,
int j,
int *i_a,
@@ -2169,7 +2169,7 @@ BLI_INLINE void spring_hairbend_estimate_dfdv(Implicit_Data *data,
/* Angular spring that pulls the vertex toward the local target
* See "Artistic Simulation of Curly Hair" (Pixar technical memo #12-03a)
*/
-bool BPH_mass_spring_force_spring_bending_hair(Implicit_Data *data,
+bool SIM_mass_spring_force_spring_bending_hair(Implicit_Data *data,
int i,
int j,
int k,
@@ -2184,9 +2184,9 @@ bool BPH_mass_spring_force_spring_bending_hair(Implicit_Data *data,
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);
+ int block_ij = SIM_mass_spring_add_block(data, i, j);
+ int block_jk = SIM_mass_spring_add_block(data, j, k);
+ int block_ik = SIM_mass_spring_add_block(data, i, k);
world_to_root_v3(data, j, goal, target);
@@ -2318,7 +2318,7 @@ bool BPH_mass_spring_force_spring_bending_hair(Implicit_Data *data,
return true;
}
-bool BPH_mass_spring_force_spring_goal(Implicit_Data *data,
+bool SIM_mass_spring_force_spring_goal(Implicit_Data *data,
int i,
const float goal_x[3],
const float goal_v[3],
diff --git a/source/blender/physics/intern/implicit_eigen.cpp b/source/blender/simulation/intern/implicit_eigen.cpp
index 58538c13116..15b9e30e32a 100644
--- a/source/blender/physics/intern/implicit_eigen.cpp
+++ b/source/blender/simulation/intern/implicit_eigen.cpp
@@ -78,7 +78,7 @@ extern "C" {
# include "BKE_effect.h"
# include "BKE_global.h"
-# include "BPH_mass_spring.h"
+# include "SIM_mass_spring.h"
}
typedef float Scalar;
@@ -460,20 +460,20 @@ struct Implicit_Data {
lMatrixCtor iS; /* filtering matrix for constraints */
};
-Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings)
+Implicit_Data *SIM_mass_spring_solver_create(int numverts, int numsprings)
{
Implicit_Data *id = new Implicit_Data(numverts);
return id;
}
-void BPH_mass_spring_solver_free(Implicit_Data *id)
+void SIM_mass_spring_solver_free(Implicit_Data *id)
{
if (id) {
delete id;
}
}
-int BPH_mass_spring_solver_numvert(Implicit_Data *id)
+int SIM_mass_spring_solver_numvert(Implicit_Data *id)
{
if (id) {
return id->numverts;
@@ -511,7 +511,7 @@ BLI_INLINE void root_to_world_m3(Implicit_Data *data, int index, float r[3][3],
/* ================================ */
-bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSolverResult *result)
+bool SIM_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSolverResult *result)
{
# ifdef USE_EIGEN_CORE
typedef ConjugateGradient solver_t;
@@ -566,16 +566,16 @@ bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSol
switch (cg.info()) {
case Eigen::Success:
- result->status = BPH_SOLVER_SUCCESS;
+ result->status = SIM_SOLVER_SUCCESS;
break;
case Eigen::NoConvergence:
- result->status = BPH_SOLVER_NO_CONVERGENCE;
+ result->status = SIM_SOLVER_NO_CONVERGENCE;
break;
case Eigen::InvalidInput:
- result->status = BPH_SOLVER_INVALID_INPUT;
+ result->status = SIM_SOLVER_INVALID_INPUT;
break;
case Eigen::NumericalIssue:
- result->status = BPH_SOLVER_NUMERICAL_ISSUE;
+ result->status = SIM_SOLVER_NUMERICAL_ISSUE;
break;
}
@@ -585,7 +585,7 @@ bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSol
return cg.info() == Eigen::Success;
}
-bool BPH_mass_spring_solve_positions(Implicit_Data *data, float dt)
+bool SIM_mass_spring_solve_positions(Implicit_Data *data, float dt)
{
data->Xnew = data->X + data->Vnew * dt;
return true;
@@ -593,13 +593,13 @@ bool BPH_mass_spring_solve_positions(Implicit_Data *data, float dt)
/* ================================ */
-void BPH_mass_spring_apply_result(Implicit_Data *data)
+void SIM_mass_spring_apply_result(Implicit_Data *data)
{
data->X = data->Xnew;
data->V = data->Vnew;
}
-void BPH_mass_spring_set_vertex_mass(Implicit_Data *data, int index, float mass)
+void SIM_mass_spring_set_vertex_mass(Implicit_Data *data, int index, float mass)
{
float m[3][3];
copy_m3_m3(m, I);
@@ -607,7 +607,7 @@ void BPH_mass_spring_set_vertex_mass(Implicit_Data *data, int index, float mass)
data->iM.add(index, index, m);
}
-void BPH_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tfm[3][3])
+void SIM_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tfm[3][3])
{
# ifdef CLOTH_ROOT_FRAME
copy_m3_m3(data->tfm[index], tfm);
@@ -617,7 +617,7 @@ void BPH_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tf
# endif
}
-void BPH_mass_spring_set_motion_state(Implicit_Data *data,
+void SIM_mass_spring_set_motion_state(Implicit_Data *data,
int index,
const float x[3],
const float v[3])
@@ -626,17 +626,17 @@ void BPH_mass_spring_set_motion_state(Implicit_Data *data,
world_to_root_v3(data, index, data->V.v3(index), v);
}
-void BPH_mass_spring_set_position(Implicit_Data *data, int index, const float x[3])
+void SIM_mass_spring_set_position(Implicit_Data *data, int index, const float x[3])
{
world_to_root_v3(data, index, data->X.v3(index), x);
}
-void BPH_mass_spring_set_velocity(Implicit_Data *data, int index, const float v[3])
+void SIM_mass_spring_set_velocity(Implicit_Data *data, int index, const float v[3])
{
world_to_root_v3(data, index, data->V.v3(index), v);
}
-void BPH_mass_spring_get_motion_state(struct Implicit_Data *data,
+void SIM_mass_spring_get_motion_state(struct Implicit_Data *data,
int index,
float x[3],
float v[3])
@@ -649,22 +649,22 @@ void BPH_mass_spring_get_motion_state(struct Implicit_Data *data,
}
}
-void BPH_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
+void SIM_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
{
root_to_world_v3(data, index, x, data->X.v3(index));
}
-void BPH_mass_spring_get_new_velocity(Implicit_Data *data, int index, float v[3])
+void SIM_mass_spring_get_new_velocity(Implicit_Data *data, int index, float v[3])
{
root_to_world_v3(data, index, v, data->V.v3(index));
}
-void BPH_mass_spring_set_new_velocity(Implicit_Data *data, int index, const float v[3])
+void SIM_mass_spring_set_new_velocity(Implicit_Data *data, int index, const float v[3])
{
world_to_root_v3(data, index, data->V.v3(index), v);
}
-void BPH_mass_spring_clear_constraints(Implicit_Data *data)
+void SIM_mass_spring_clear_constraints(Implicit_Data *data)
{
int numverts = data->numverts;
for (int i = 0; i < numverts; i++) {
@@ -673,14 +673,14 @@ 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])
+void SIM_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(
+void SIM_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];
@@ -701,7 +701,7 @@ void BPH_mass_spring_add_constraint_ndof1(
add_v3_v3(data->z.v3(index), u);
}
-void BPH_mass_spring_add_constraint_ndof2(Implicit_Data *data,
+void SIM_mass_spring_add_constraint_ndof2(Implicit_Data *data,
int index,
const float c1[3],
const float dV[3])
@@ -719,14 +719,14 @@ void BPH_mass_spring_add_constraint_ndof2(Implicit_Data *data,
add_v3_v3(data->z.v3(index), u);
}
-void BPH_mass_spring_clear_forces(Implicit_Data *data)
+void SIM_mass_spring_clear_forces(Implicit_Data *data)
{
data->F.setZero();
data->dFdX.setZero();
data->dFdV.setZero();
}
-void BPH_mass_spring_force_reference_frame(Implicit_Data *data,
+void SIM_mass_spring_force_reference_frame(Implicit_Data *data,
int index,
const float acceleration[3],
const float omega[3],
@@ -781,7 +781,7 @@ void BPH_mass_spring_force_reference_frame(Implicit_Data *data,
# endif
}
-void BPH_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, const float g[3])
+void SIM_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, const float g[3])
{
/* force = mass * acceleration (in this case: gravity) */
float f[3];
@@ -791,7 +791,7 @@ void BPH_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, c
add_v3_v3(data->F.v3(index), f);
}
-void BPH_mass_spring_force_drag(Implicit_Data *data, float drag)
+void SIM_mass_spring_force_drag(Implicit_Data *data, float drag)
{
int numverts = data->numverts;
for (int i = 0; i < numverts; i++) {
@@ -806,7 +806,7 @@ void BPH_mass_spring_force_drag(Implicit_Data *data, float drag)
}
}
-void BPH_mass_spring_force_extern(
+void SIM_mass_spring_force_extern(
struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3])
{
float tf[3], tdfdx[3][3], tdfdv[3][3];
@@ -835,7 +835,7 @@ static float calc_nor_area_tri(float nor[3],
/* XXX does not support force jacobians yet,
* since the effector system does not provide them either. */
-void BPH_mass_spring_force_face_wind(
+void SIM_mass_spring_force_face_wind(
Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3])
{
const float effector_scale = 0.02f;
@@ -856,7 +856,7 @@ void BPH_mass_spring_force_face_wind(
madd_v3_v3fl(data->F.v3(v3), nor, factor * dot_v3v3(win, nor));
}
-void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, const float (*winvec)[3])
+void SIM_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, const float (*winvec)[3])
{
const float effector_scale = 0.01;
float win[3], dir[3], nor[3], length;
@@ -1000,7 +1000,7 @@ BLI_INLINE void apply_spring(
data->idFdV.sub(j, i, dfdv);
}
-bool BPH_mass_spring_force_spring_linear(Implicit_Data *data,
+bool SIM_mass_spring_force_spring_linear(Implicit_Data *data,
int i,
int j,
float restlen,
@@ -1063,7 +1063,7 @@ bool BPH_mass_spring_force_spring_linear(Implicit_Data *data,
}
/* See "Stable but Responsive Cloth" (Choi, Ko 2005) */
-bool BPH_mass_spring_force_spring_bending(Implicit_Data *data,
+bool SIM_mass_spring_force_spring_bending(Implicit_Data *data,
int i,
int j,
float restlen,
@@ -1293,7 +1293,7 @@ BLI_INLINE void spring_angbend_estimate_dfdv(Implicit_Data *data,
/* Angular spring that pulls the vertex toward the local target
* See "Artistic Simulation of Curly Hair" (Pixar technical memo #12-03a)
*/
-bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data,
+bool SIM_mass_spring_force_spring_bending_angular(Implicit_Data *data,
int i,
int j,
int k,
@@ -1444,7 +1444,7 @@ bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data,
return true;
}
-bool BPH_mass_spring_force_spring_goal(Implicit_Data *data,
+bool SIM_mass_spring_force_spring_goal(Implicit_Data *data,
int i,
const float goal_x[3],
const float goal_v[3],
diff --git a/source/blender/simulation/intern/particle_allocator.cc b/source/blender/simulation/intern/particle_allocator.cc
new file mode 100644
index 00000000000..e47a6354d81
--- /dev/null
+++ b/source/blender/simulation/intern/particle_allocator.cc
@@ -0,0 +1,86 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "particle_allocator.hh"
+
+#include "BLI_rand.hh"
+
+namespace blender::sim {
+
+AttributesAllocator::~AttributesAllocator()
+{
+ for (std::unique_ptr<AttributesBlock> &block : allocated_blocks_) {
+ for (int i : attributes_info_.index_range()) {
+ const fn::CPPType &type = attributes_info_.type_of(i);
+ type.destruct_n(block->buffers[i], block->size);
+ MEM_freeN(block->buffers[i]);
+ }
+ }
+}
+
+fn::MutableAttributesRef AttributesAllocator::allocate_uninitialized(int size)
+{
+ std::unique_ptr<AttributesBlock> block = std::make_unique<AttributesBlock>();
+ block->buffers = Array<void *>(attributes_info_.size(), nullptr);
+ block->size = size;
+
+ for (int i : attributes_info_.index_range()) {
+ const fn::CPPType &type = attributes_info_.type_of(i);
+ void *buffer = MEM_mallocN_aligned(size * type.size(), type.alignment(), AT);
+ block->buffers[i] = buffer;
+ }
+
+ fn::MutableAttributesRef attributes{attributes_info_, block->buffers, size};
+
+ {
+ std::lock_guard lock{mutex_};
+ allocated_blocks_.append(std::move(block));
+ allocated_attributes_.append(attributes);
+ total_allocated_ += size;
+ }
+
+ return attributes;
+}
+
+fn::MutableAttributesRef ParticleAllocator::allocate(int size)
+{
+ const fn::AttributesInfo &info = attributes_allocator_.attributes_info();
+ fn::MutableAttributesRef attributes = attributes_allocator_.allocate_uninitialized(size);
+ for (int i : info.index_range()) {
+ const fn::CPPType &type = info.type_of(i);
+ StringRef name = info.name_of(i);
+ if (name == "ID") {
+ int start_id = next_id_.fetch_add(size);
+ MutableSpan<int> ids = attributes.get<int>("ID");
+ for (int pindex : IndexRange(size)) {
+ ids[pindex] = start_id + pindex;
+ }
+ }
+ else if (name == "Hash") {
+ MutableSpan<int> hashes = attributes.get<int>("Hash");
+ RandomNumberGenerator rng(hash_seed_ ^ (uint32_t)next_id_);
+ for (int pindex : IndexRange(size)) {
+ hashes[pindex] = (int)rng.get_uint32();
+ }
+ }
+ else {
+ type.fill_uninitialized(info.default_of(i), attributes.get(i).data(), size);
+ }
+ }
+ return attributes;
+}
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/particle_allocator.hh b/source/blender/simulation/intern/particle_allocator.hh
new file mode 100644
index 00000000000..c0bbdb845d9
--- /dev/null
+++ b/source/blender/simulation/intern/particle_allocator.hh
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "BLI_array.hh"
+#include "BLI_vector.hh"
+
+#include "FN_attributes_ref.hh"
+
+#include <atomic>
+#include <mutex>
+
+namespace blender::sim {
+
+class AttributesAllocator : NonCopyable, NonMovable {
+ private:
+ struct AttributesBlock {
+ Array<void *> buffers;
+ int size;
+ };
+
+ const fn::AttributesInfo &attributes_info_;
+ Vector<std::unique_ptr<AttributesBlock>> allocated_blocks_;
+ Vector<fn::MutableAttributesRef> allocated_attributes_;
+ int total_allocated_ = 0;
+ std::mutex mutex_;
+
+ public:
+ AttributesAllocator(const fn::AttributesInfo &attributes_info)
+ : attributes_info_(attributes_info)
+ {
+ }
+
+ ~AttributesAllocator();
+
+ Span<fn::MutableAttributesRef> get_allocations() const
+ {
+ return allocated_attributes_;
+ }
+
+ int total_allocated() const
+ {
+ return total_allocated_;
+ }
+
+ const fn::AttributesInfo &attributes_info() const
+ {
+ return attributes_info_;
+ }
+
+ fn::MutableAttributesRef allocate_uninitialized(int size);
+};
+
+class ParticleAllocator : NonCopyable, NonMovable {
+ private:
+ AttributesAllocator attributes_allocator_;
+ std::atomic<int> next_id_;
+ uint32_t hash_seed_;
+
+ public:
+ ParticleAllocator(const fn::AttributesInfo &attributes_info, int next_id, uint32_t hash_seed)
+ : attributes_allocator_(attributes_info), next_id_(next_id), hash_seed_(hash_seed)
+ {
+ }
+
+ const fn::AttributesInfo &attributes_info() const
+ {
+ return attributes_allocator_.attributes_info();
+ }
+
+ Span<fn::MutableAttributesRef> get_allocations() const
+ {
+ return attributes_allocator_.get_allocations();
+ }
+
+ int total_allocated() const
+ {
+ return attributes_allocator_.total_allocated();
+ }
+
+ fn::MutableAttributesRef allocate(int size);
+};
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/particle_function.cc b/source/blender/simulation/intern/particle_function.cc
new file mode 100644
index 00000000000..035e6d50e21
--- /dev/null
+++ b/source/blender/simulation/intern/particle_function.cc
@@ -0,0 +1,167 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "particle_function.hh"
+
+namespace blender::sim {
+
+ParticleFunction::ParticleFunction(const fn::MultiFunction *global_fn,
+ const fn::MultiFunction *per_particle_fn,
+ Span<const ParticleFunctionInput *> global_inputs,
+ Span<const ParticleFunctionInput *> per_particle_inputs,
+ Span<bool> output_is_global)
+ : global_fn_(global_fn),
+ per_particle_fn_(per_particle_fn),
+ global_inputs_(global_inputs),
+ per_particle_inputs_(per_particle_inputs),
+ output_is_global_(output_is_global)
+{
+ for (int i : output_is_global_.index_range()) {
+ if (output_is_global_[i]) {
+ int param_index = global_inputs_.size() + global_output_indices_.size();
+ fn::MFParamType param_type = global_fn_->param_type(param_index);
+ BLI_assert(param_type.is_output());
+ output_types_.append(param_type.data_type());
+ output_names_.append(global_fn_->param_name(param_index));
+ global_output_indices_.append(i);
+ }
+ else {
+ int param_index = per_particle_inputs_.size() + per_particle_output_indices_.size();
+ fn::MFParamType param_type = per_particle_fn_->param_type(param_index);
+ BLI_assert(param_type.is_output());
+ output_types_.append(param_type.data_type());
+ output_names_.append(per_particle_fn_->param_name(param_index));
+ per_particle_output_indices_.append(i);
+ }
+ }
+}
+
+ParticleFunctionEvaluator::ParticleFunctionEvaluator(const ParticleFunction &particle_fn,
+ const SimulationSolveContext &solve_context,
+ const ParticleChunkContext &particles)
+ : particle_fn_(particle_fn),
+ solve_context_(solve_context),
+ particles_(particles),
+ mask_(particles_.index_mask),
+ outputs_(particle_fn_.output_types_.size(), nullptr)
+{
+ global_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map);
+ per_particle_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map);
+}
+
+ParticleFunctionEvaluator::~ParticleFunctionEvaluator()
+{
+ for (int output_index : outputs_.index_range()) {
+ void *buffer = outputs_[output_index];
+ fn::MFDataType data_type = particle_fn_.output_types_[output_index];
+ BLI_assert(data_type.is_single()); /* For now. */
+ const fn::CPPType &type = data_type.single_type();
+
+ if (particle_fn_.output_is_global_[output_index]) {
+ type.destruct(buffer);
+ }
+ else {
+ type.destruct_indices(outputs_[0], mask_);
+ }
+ }
+}
+
+void ParticleFunctionEvaluator::compute()
+{
+ BLI_assert(!is_computed_);
+ this->compute_globals();
+ this->compute_per_particle();
+ is_computed_ = true;
+}
+
+fn::GVSpan ParticleFunctionEvaluator::get(int output_index, StringRef expected_name) const
+{
+#ifdef DEBUG
+ if (expected_name != "") {
+ StringRef real_name = particle_fn_.output_names_[output_index];
+ BLI_assert(expected_name == real_name);
+ }
+ BLI_assert(is_computed_);
+#endif
+ UNUSED_VARS_NDEBUG(expected_name);
+ const void *buffer = outputs_[output_index];
+ const fn::CPPType &type = particle_fn_.output_types_[output_index].single_type();
+ if (particle_fn_.output_is_global_[output_index]) {
+ return fn::GVSpan::FromSingleWithMaxSize(type, buffer);
+ }
+ else {
+ return fn::GVSpan(fn::GSpan(type, buffer, mask_.min_array_size()));
+ }
+}
+
+void ParticleFunctionEvaluator::compute_globals()
+{
+ if (particle_fn_.global_fn_ == nullptr) {
+ return;
+ }
+
+ fn::MFParamsBuilder params(*particle_fn_.global_fn_, mask_.min_array_size());
+
+ /* Add input parameters. */
+ ParticleFunctionInputContext input_context{solve_context_, particles_};
+ for (const ParticleFunctionInput *input : particle_fn_.global_inputs_) {
+ input->add_input(input_context, params, resources_);
+ }
+
+ /* Add output parameters. */
+ for (int output_index : particle_fn_.global_output_indices_) {
+ fn::MFDataType data_type = particle_fn_.output_types_[output_index];
+ BLI_assert(data_type.is_single()); /* For now. */
+
+ const fn::CPPType &type = data_type.single_type();
+ void *buffer = resources_.linear_allocator().allocate(type.size(), type.alignment());
+ params.add_uninitialized_single_output(fn::GMutableSpan(type, buffer, 1));
+ outputs_[output_index] = buffer;
+ }
+
+ particle_fn_.global_fn_->call({0}, params, global_context_);
+}
+
+void ParticleFunctionEvaluator::compute_per_particle()
+{
+ if (particle_fn_.per_particle_fn_ == nullptr) {
+ return;
+ }
+
+ fn::MFParamsBuilder params(*particle_fn_.per_particle_fn_, mask_.min_array_size());
+
+ /* Add input parameters. */
+ ParticleFunctionInputContext input_context{solve_context_, particles_};
+ for (const ParticleFunctionInput *input : particle_fn_.per_particle_inputs_) {
+ input->add_input(input_context, params, resources_);
+ }
+
+ /* Add output parameters. */
+ for (int output_index : particle_fn_.per_particle_output_indices_) {
+ fn::MFDataType data_type = particle_fn_.output_types_[output_index];
+ BLI_assert(data_type.is_single()); /* For now. */
+
+ const fn::CPPType &type = data_type.single_type();
+ void *buffer = resources_.linear_allocator().allocate(type.size() * mask_.min_array_size(),
+ type.alignment());
+ params.add_uninitialized_single_output(fn::GMutableSpan(type, buffer, mask_.min_array_size()));
+ outputs_[output_index] = buffer;
+ }
+
+ particle_fn_.per_particle_fn_->call(mask_, params, global_context_);
+}
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/particle_function.hh b/source/blender/simulation/intern/particle_function.hh
new file mode 100644
index 00000000000..ead4e6f3c31
--- /dev/null
+++ b/source/blender/simulation/intern/particle_function.hh
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "FN_attributes_ref.hh"
+#include "FN_multi_function.hh"
+
+#include "BLI_resource_collector.hh"
+
+#include "simulation_solver.hh"
+
+namespace blender::sim {
+
+struct ParticleFunctionInputContext {
+ const SimulationSolveContext &solve_context;
+ const ParticleChunkContext &particles;
+};
+
+class ParticleFunctionInput {
+ public:
+ virtual ~ParticleFunctionInput() = default;
+ virtual void add_input(ParticleFunctionInputContext &context,
+ fn::MFParamsBuilder &params,
+ ResourceCollector &resources) const = 0;
+};
+
+class ParticleFunction {
+ private:
+ const fn::MultiFunction *global_fn_;
+ const fn::MultiFunction *per_particle_fn_;
+ Array<const ParticleFunctionInput *> global_inputs_;
+ Array<const ParticleFunctionInput *> per_particle_inputs_;
+ Array<bool> output_is_global_;
+ Vector<int> global_output_indices_;
+ Vector<int> per_particle_output_indices_;
+ Vector<fn::MFDataType> output_types_;
+ Vector<StringRefNull> output_names_;
+
+ friend class ParticleFunctionEvaluator;
+
+ public:
+ ParticleFunction(const fn::MultiFunction *global_fn,
+ const fn::MultiFunction *per_particle_fn,
+ Span<const ParticleFunctionInput *> global_inputs,
+ Span<const ParticleFunctionInput *> per_particle_inputs,
+ Span<bool> output_is_global);
+};
+
+class ParticleFunctionEvaluator {
+ private:
+ ResourceCollector resources_;
+ const ParticleFunction &particle_fn_;
+ const SimulationSolveContext &solve_context_;
+ const ParticleChunkContext &particles_;
+ IndexMask mask_;
+ fn::MFContextBuilder global_context_;
+ fn::MFContextBuilder per_particle_context_;
+ Vector<void *> outputs_;
+ bool is_computed_ = false;
+
+ public:
+ ParticleFunctionEvaluator(const ParticleFunction &particle_fn,
+ const SimulationSolveContext &solve_context,
+ const ParticleChunkContext &particles);
+ ~ParticleFunctionEvaluator();
+
+ void compute();
+ fn::GVSpan get(int output_index, StringRef expected_name = "") const;
+
+ template<typename T> fn::VSpan<T> get(int output_index, StringRef expected_name = "") const
+ {
+ return this->get(output_index, expected_name).typed<T>();
+ }
+
+ private:
+ void compute_globals();
+ void compute_per_particle();
+};
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/particle_mesh_emitter.cc b/source/blender/simulation/intern/particle_mesh_emitter.cc
new file mode 100644
index 00000000000..26541d550eb
--- /dev/null
+++ b/source/blender/simulation/intern/particle_mesh_emitter.cc
@@ -0,0 +1,362 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "particle_mesh_emitter.hh"
+
+#include "BLI_float4x4.hh"
+#include "BLI_rand.hh"
+#include "BLI_vector_adaptor.hh"
+
+#include "BKE_mesh_runtime.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+
+namespace blender::sim {
+
+ParticleMeshEmitter::~ParticleMeshEmitter() = default;
+
+struct EmitterSettings {
+ Object *object;
+ float rate;
+};
+
+static BLI_NOINLINE void compute_birth_times(float rate,
+ TimeInterval emit_interval,
+ ParticleMeshEmitterSimulationState &state,
+ Vector<float> &r_birth_times)
+{
+ const float time_between_particles = 1.0f / rate;
+ int counter = 0;
+ while (true) {
+ counter++;
+ const float time_offset = counter * time_between_particles;
+ const float birth_time = state.last_birth_time + time_offset;
+ if (birth_time > emit_interval.stop()) {
+ break;
+ }
+ if (birth_time <= emit_interval.start()) {
+ continue;
+ }
+ r_birth_times.append(birth_time);
+ }
+}
+
+static BLI_NOINLINE Span<MLoopTri> get_mesh_triangles(Mesh &mesh)
+{
+ const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(&mesh);
+ int amount = BKE_mesh_runtime_looptri_len(&mesh);
+ return Span(triangles, amount);
+}
+
+static BLI_NOINLINE void compute_triangle_areas(Mesh &mesh,
+ Span<MLoopTri> triangles,
+ MutableSpan<float> r_areas)
+{
+ assert_same_size(triangles, r_areas);
+
+ for (int i : triangles.index_range()) {
+ const MLoopTri &tri = triangles[i];
+
+ const float3 v1 = mesh.mvert[mesh.mloop[tri.tri[0]].v].co;
+ const float3 v2 = mesh.mvert[mesh.mloop[tri.tri[1]].v].co;
+ const float3 v3 = mesh.mvert[mesh.mloop[tri.tri[2]].v].co;
+
+ const float area = area_tri_v3(v1, v2, v3);
+ r_areas[i] = area;
+ }
+}
+
+static BLI_NOINLINE void compute_triangle_weights(Mesh &mesh,
+ Span<MLoopTri> triangles,
+ MutableSpan<float> r_weights)
+{
+ assert_same_size(triangles, r_weights);
+ compute_triangle_areas(mesh, triangles, r_weights);
+}
+
+static BLI_NOINLINE void compute_cumulative_distribution(Span<float> weights,
+ MutableSpan<float> r_cumulative_weights)
+{
+ BLI_assert(weights.size() + 1 == r_cumulative_weights.size());
+
+ r_cumulative_weights[0] = 0;
+ for (int i : weights.index_range()) {
+ r_cumulative_weights[i + 1] = r_cumulative_weights[i] + weights[i];
+ }
+}
+
+static void sample_cumulative_distribution_recursive(RandomNumberGenerator &rng,
+ int amount,
+ int start,
+ int one_after_end,
+ Span<float> cumulative_weights,
+ VectorAdaptor<int> &r_sampled_indices)
+{
+ BLI_assert(start <= one_after_end);
+ const int size = one_after_end - start;
+ if (size == 0) {
+ BLI_assert(amount == 0);
+ }
+ else if (amount == 0) {
+ return;
+ }
+ else if (size == 1) {
+ r_sampled_indices.append_n_times(start, amount);
+ }
+ else {
+ const int middle = start + size / 2;
+ const float left_weight = cumulative_weights[middle] - cumulative_weights[start];
+ const float right_weight = cumulative_weights[one_after_end] - cumulative_weights[middle];
+ BLI_assert(left_weight >= 0.0f && right_weight >= 0.0f);
+ const float weight_sum = left_weight + right_weight;
+ BLI_assert(weight_sum > 0.0f);
+
+ const float left_factor = left_weight / weight_sum;
+ const float right_factor = right_weight / weight_sum;
+
+ int left_amount = amount * left_factor;
+ int right_amount = amount * right_factor;
+
+ if (left_amount + right_amount < amount) {
+ BLI_assert(left_amount + right_amount + 1 == amount);
+ const float weight_per_item = weight_sum / amount;
+ const float total_remaining_weight = weight_sum -
+ (left_amount + right_amount) * weight_per_item;
+ const float left_remaining_weight = left_weight - left_amount * weight_per_item;
+ const float left_remaining_factor = left_remaining_weight / total_remaining_weight;
+ if (rng.get_float() < left_remaining_factor) {
+ left_amount++;
+ }
+ else {
+ right_amount++;
+ }
+ }
+
+ sample_cumulative_distribution_recursive(
+ rng, left_amount, start, middle, cumulative_weights, r_sampled_indices);
+ sample_cumulative_distribution_recursive(
+ rng, right_amount, middle, one_after_end, cumulative_weights, r_sampled_indices);
+ }
+}
+
+static BLI_NOINLINE void sample_cumulative_distribution(RandomNumberGenerator &rng,
+ Span<float> cumulative_weights,
+ MutableSpan<int> r_samples)
+{
+ VectorAdaptor<int> sampled_indices(r_samples);
+ sample_cumulative_distribution_recursive(rng,
+ r_samples.size(),
+ 0,
+ cumulative_weights.size() - 1,
+ cumulative_weights,
+ sampled_indices);
+ BLI_assert(sampled_indices.is_full());
+}
+
+static BLI_NOINLINE bool sample_weighted_buckets(RandomNumberGenerator &rng,
+ Span<float> weights,
+ MutableSpan<int> r_samples)
+{
+ Array<float> cumulative_weights(weights.size() + 1);
+ compute_cumulative_distribution(weights, cumulative_weights);
+
+ if (r_samples.size() > 0 && cumulative_weights.as_span().last() == 0.0f) {
+ /* All weights are zero. */
+ return false;
+ }
+
+ sample_cumulative_distribution(rng, cumulative_weights, r_samples);
+ return true;
+}
+
+static BLI_NOINLINE void sample_looptris(RandomNumberGenerator &rng,
+ Mesh &mesh,
+ Span<MLoopTri> triangles,
+ Span<int> triangles_to_sample,
+ MutableSpan<float3> r_sampled_positions,
+ MutableSpan<float3> r_sampled_normals)
+{
+ assert_same_size(triangles_to_sample, r_sampled_positions, r_sampled_normals);
+
+ MLoop *loops = mesh.mloop;
+ MVert *verts = mesh.mvert;
+
+ for (uint i : triangles_to_sample.index_range()) {
+ const uint triangle_index = triangles_to_sample[i];
+ const MLoopTri &triangle = triangles[triangle_index];
+
+ const float3 v1 = verts[loops[triangle.tri[0]].v].co;
+ const float3 v2 = verts[loops[triangle.tri[1]].v].co;
+ const float3 v3 = verts[loops[triangle.tri[2]].v].co;
+
+ const float3 bary_coords = rng.get_barycentric_coordinates();
+
+ float3 position;
+ interp_v3_v3v3v3(position, v1, v2, v3, bary_coords);
+
+ float3 normal;
+ normal_tri_v3(normal, v1, v2, v3);
+
+ r_sampled_positions[i] = position;
+ r_sampled_normals[i] = normal;
+ }
+}
+
+static BLI_NOINLINE bool compute_new_particle_attributes(ParticleEmitterContext &context,
+ EmitterSettings &settings,
+ ParticleMeshEmitterSimulationState &state,
+ Vector<float3> &r_positions,
+ Vector<float3> &r_velocities,
+ Vector<float> &r_birth_times)
+{
+ if (settings.object == nullptr) {
+ return false;
+ }
+ if (settings.rate <= 0.000001f) {
+ return false;
+ }
+ if (settings.object->type != OB_MESH) {
+ return false;
+ }
+ Mesh &mesh = *(Mesh *)settings.object->data;
+ if (mesh.totvert == 0) {
+ return false;
+ }
+
+ const float start_time = context.emit_interval.start();
+ const uint32_t seed = DefaultHash<StringRef>{}(state.head.name);
+ RandomNumberGenerator rng{(*(uint32_t *)&start_time) ^ seed};
+
+ compute_birth_times(settings.rate, context.emit_interval, state, r_birth_times);
+ const int particle_amount = r_birth_times.size();
+ if (particle_amount == 0) {
+ return false;
+ }
+
+ const float last_birth_time = r_birth_times.last();
+ rng.shuffle(r_birth_times.as_mutable_span());
+
+ Span<MLoopTri> triangles = get_mesh_triangles(mesh);
+ if (triangles.is_empty()) {
+ return false;
+ }
+
+ Array<float> triangle_weights(triangles.size());
+ compute_triangle_weights(mesh, triangles, triangle_weights);
+
+ Array<int> triangles_to_sample(particle_amount);
+ if (!sample_weighted_buckets(rng, triangle_weights, triangles_to_sample)) {
+ return false;
+ }
+
+ r_positions.resize(particle_amount);
+ r_velocities.resize(particle_amount);
+ sample_looptris(rng, mesh, triangles, triangles_to_sample, r_positions, r_velocities);
+
+ if (context.solve_context.dependency_animations.is_object_transform_changing(*settings.object)) {
+ Array<float4x4> local_to_world_matrices(particle_amount);
+ context.solve_context.dependency_animations.get_object_transforms(
+ *settings.object, r_birth_times, local_to_world_matrices);
+
+ for (int i : IndexRange(particle_amount)) {
+ const float4x4 &position_to_world = local_to_world_matrices[i];
+ const float4x4 normal_to_world = position_to_world.inverted_transposed_affine();
+ r_positions[i] = position_to_world * r_positions[i];
+ r_velocities[i] = normal_to_world * r_velocities[i];
+ }
+ }
+ else {
+ const float4x4 position_to_world = settings.object->obmat;
+ const float4x4 normal_to_world = position_to_world.inverted_transposed_affine();
+ for (int i : IndexRange(particle_amount)) {
+ r_positions[i] = position_to_world * r_positions[i];
+ r_velocities[i] = normal_to_world * r_velocities[i];
+ }
+ }
+
+ for (int i : IndexRange(particle_amount)) {
+ r_velocities[i].normalize();
+ }
+
+ state.last_birth_time = last_birth_time;
+ return true;
+}
+
+static BLI_NOINLINE EmitterSettings compute_settings(const fn::MultiFunction &inputs_fn,
+ ParticleEmitterContext &context)
+{
+ EmitterSettings parameters;
+
+ fn::MFContextBuilder mf_context;
+ mf_context.add_global_context("PersistentDataHandleMap", &context.solve_context.handle_map);
+
+ fn::MFParamsBuilder mf_params{inputs_fn, 1};
+ bke::PersistentObjectHandle object_handle;
+ mf_params.add_uninitialized_single_output(&object_handle, "Object");
+ mf_params.add_uninitialized_single_output(&parameters.rate, "Rate");
+
+ inputs_fn.call(IndexRange(1), mf_params, mf_context);
+
+ parameters.object = context.solve_context.handle_map.lookup(object_handle);
+ return parameters;
+}
+
+void ParticleMeshEmitter::emit(ParticleEmitterContext &context) const
+{
+ auto *state = context.lookup_state<ParticleMeshEmitterSimulationState>(own_state_name_);
+ if (state == nullptr) {
+ return;
+ }
+
+ EmitterSettings settings = compute_settings(inputs_fn_, context);
+
+ Vector<float3> new_positions;
+ Vector<float3> new_velocities;
+ Vector<float> new_birth_times;
+
+ if (!compute_new_particle_attributes(
+ context, settings, *state, new_positions, new_velocities, new_birth_times)) {
+ return;
+ }
+
+ for (StringRef name : particle_names_) {
+ ParticleAllocator *allocator = context.try_get_particle_allocator(name);
+ if (allocator == nullptr) {
+ continue;
+ }
+
+ int amount = new_positions.size();
+ fn::MutableAttributesRef attributes = allocator->allocate(amount);
+
+ attributes.get<float3>("Position").copy_from(new_positions);
+ attributes.get<float3>("Velocity").copy_from(new_velocities);
+ attributes.get<float>("Birth Time").copy_from(new_birth_times);
+
+ if (action_ != nullptr) {
+ ParticleChunkContext particles{
+ *context.solve_context.state_map.lookup<ParticleSimulationState>(name),
+ IndexRange(amount),
+ attributes,
+ nullptr};
+ ParticleActionContext action_context{context.solve_context, particles};
+ action_->execute(action_context);
+ }
+ }
+}
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/particle_mesh_emitter.hh b/source/blender/simulation/intern/particle_mesh_emitter.hh
new file mode 100644
index 00000000000..cdcf2a34e16
--- /dev/null
+++ b/source/blender/simulation/intern/particle_mesh_emitter.hh
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "simulation_solver_influences.hh"
+
+#include "FN_multi_function.hh"
+
+namespace blender::sim {
+
+class ParticleMeshEmitter final : public ParticleEmitter {
+ private:
+ std::string own_state_name_;
+ Array<std::string> particle_names_;
+ const fn::MultiFunction &inputs_fn_;
+ const ParticleAction *action_;
+
+ public:
+ ParticleMeshEmitter(std::string own_state_name,
+ Array<std::string> particle_names,
+ const fn::MultiFunction &inputs_fn,
+ const ParticleAction *action)
+ : own_state_name_(std::move(own_state_name)),
+ particle_names_(particle_names),
+ inputs_fn_(inputs_fn),
+ action_(action)
+ {
+ }
+
+ ~ParticleMeshEmitter();
+
+ void emit(ParticleEmitterContext &context) const override;
+};
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc
new file mode 100644
index 00000000000..818415e5d88
--- /dev/null
+++ b/source/blender/simulation/intern/simulation_collect_influences.cc
@@ -0,0 +1,907 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "simulation_collect_influences.hh"
+#include "particle_function.hh"
+#include "particle_mesh_emitter.hh"
+
+#include "FN_attributes_ref.hh"
+#include "FN_multi_function_network_evaluation.hh"
+#include "FN_multi_function_network_optimization.hh"
+
+#include "NOD_node_tree_multi_function.hh"
+
+#include "DEG_depsgraph_query.h"
+
+#include "BLI_hash.h"
+#include "BLI_rand.hh"
+#include "BLI_set.hh"
+
+namespace blender::sim {
+
+using fn::GVSpan;
+using fn::MFContextBuilder;
+using fn::MFDataType;
+using fn::MFDummyNode;
+using fn::MFFunctionNode;
+using fn::MFInputSocket;
+using fn::MFNetwork;
+using fn::MFNetworkEvaluator;
+using fn::MFNode;
+using fn::MFOutputSocket;
+using fn::MFParamsBuilder;
+using fn::MFParamType;
+using fn::MultiFunction;
+using fn::VSpan;
+using nodes::DerivedNodeTree;
+using nodes::DInputSocket;
+using nodes::DNode;
+using nodes::DOutputSocket;
+using nodes::DParentNode;
+using nodes::MFNetworkTreeMap;
+using nodes::NodeTreeRefMap;
+
+struct DummyDataSources {
+ Map<const MFOutputSocket *, std::string> particle_attributes;
+ Set<const MFOutputSocket *> simulation_time;
+ Set<const MFOutputSocket *> scene_time;
+};
+
+extern "C" {
+void WM_clipboard_text_set(const char *buf, bool selection);
+}
+
+static std::string dnode_to_path(const DNode &dnode)
+{
+ std::string path;
+ for (const DParentNode *parent = dnode.parent(); parent; parent = parent->parent()) {
+ path = parent->node_ref().name() + "/" + path;
+ }
+ path = path + dnode.name();
+ return path;
+}
+
+struct CollectContext : NonCopyable, NonMovable {
+ SimulationInfluences &influences;
+ RequiredStates &required_states;
+ ResourceCollector &resources;
+ MFNetworkTreeMap &network_map;
+ MFNetwork &network;
+ const DerivedNodeTree &tree;
+
+ DummyDataSources data_sources;
+ Span<const DNode *> particle_simulation_nodes;
+ Map<const DNode *, std::string> node_paths;
+
+ CollectContext(SimulationInfluences &influences,
+ RequiredStates &required_states,
+ ResourceCollector &resources,
+ MFNetworkTreeMap &network_map)
+ : influences(influences),
+ required_states(required_states),
+ resources(resources),
+ network_map(network_map),
+ network(network_map.network()),
+ tree(network_map.tree())
+ {
+ particle_simulation_nodes = tree.nodes_by_type("SimulationNodeParticleSimulation");
+ }
+};
+
+static const ParticleAction *create_particle_action(CollectContext &context,
+ const DOutputSocket &dsocket,
+ Span<StringRefNull> particle_names);
+
+static const ParticleAction *create_particle_action(CollectContext &context,
+ const DInputSocket &dsocket,
+ Span<StringRefNull> particle_names)
+{
+ BLI_assert(dsocket.bsocket()->type == SOCK_CONTROL_FLOW);
+ if (dsocket.linked_sockets().size() != 1) {
+ return nullptr;
+ }
+ return create_particle_action(context, *dsocket.linked_sockets()[0], particle_names);
+}
+
+static StringRefNull get_identifier(CollectContext &context, const DNode &dnode)
+{
+ return context.node_paths.lookup_or_add_cb(&dnode, [&]() { return dnode_to_path(dnode); });
+}
+
+static Span<const DNode *> nodes_by_type(CollectContext &context, StringRefNull idname)
+{
+ return context.tree.nodes_by_type(idname);
+}
+
+static Array<StringRefNull> find_linked_particle_simulations(CollectContext &context,
+ const DOutputSocket &output_socket)
+{
+ VectorSet<StringRefNull> names;
+ for (const DInputSocket *target_socket : output_socket.linked_sockets()) {
+ if (target_socket->node().idname() == "SimulationNodeParticleSimulation") {
+ names.add(get_identifier(context, target_socket->node()));
+ }
+ }
+ return names.as_span();
+}
+
+/* Returns true on success. */
+static bool compute_global_inputs(MFNetworkTreeMap &network_map,
+ ResourceCollector &resources,
+ Span<const MFInputSocket *> sockets,
+ MutableSpan<GMutableSpan> r_results)
+{
+ int amount = sockets.size();
+ if (amount == 0) {
+ return true;
+ }
+
+ if (network_map.network().have_dummy_or_unlinked_dependencies(sockets)) {
+ return false;
+ }
+
+ MFNetworkEvaluator network_fn{{}, sockets};
+ MFParamsBuilder params{network_fn, 1};
+ for (int param_index : network_fn.param_indices()) {
+ MFParamType param_type = network_fn.param_type(param_index);
+ BLI_assert(param_type.category() == MFParamType::Category::SingleOutput); /* For now. */
+ const CPPType &type = param_type.data_type().single_type();
+ void *buffer = resources.linear_allocator().allocate(type.size(), type.alignment());
+ resources.add(buffer, type.destruct_cb(), AT);
+ GMutableSpan span{type, buffer, 1};
+ r_results[param_index] = span;
+ params.add_uninitialized_single_output(span);
+ }
+ MFContextBuilder context;
+ network_fn.call(IndexRange(1), params, context);
+ return true;
+}
+
+static std::optional<Array<std::string>> compute_global_string_inputs(
+ MFNetworkTreeMap &network_map, Span<const MFInputSocket *> sockets)
+{
+ ResourceCollector local_resources;
+ Array<GMutableSpan> computed_values(sockets.size(), NoInitialization());
+ if (!compute_global_inputs(network_map, local_resources, sockets, computed_values)) {
+ return {};
+ }
+
+ Array<std::string> strings(sockets.size());
+ for (int i : sockets.index_range()) {
+ strings[i] = std::move(computed_values[i].typed<std::string>()[0]);
+ }
+ return strings;
+}
+
+/**
+ * This will find all the particle attribute input nodes. Then it will compute the attribute names
+ * by evaluating the network (those names should not depend on per particle data). In the end,
+ * input nodes that access the same attribute are combined.
+ */
+static void prepare_particle_attribute_nodes(CollectContext &context)
+{
+ Span<const DNode *> attribute_dnodes = nodes_by_type(context, "SimulationNodeParticleAttribute");
+
+ Vector<MFInputSocket *> name_sockets;
+ for (const DNode *dnode : attribute_dnodes) {
+ MFInputSocket &name_socket = context.network_map.lookup_dummy(dnode->input(0));
+ name_sockets.append(&name_socket);
+ }
+
+ std::optional<Array<std::string>> attribute_names = compute_global_string_inputs(
+ context.network_map, name_sockets);
+ if (!attribute_names.has_value()) {
+ return;
+ }
+
+ MultiValueMap<std::pair<std::string, MFDataType>, MFNode *> attribute_nodes_by_name_and_type;
+ for (int i : attribute_names->index_range()) {
+ attribute_nodes_by_name_and_type.add(
+ {(*attribute_names)[i], name_sockets[i]->node().output(0).data_type()},
+ &name_sockets[i]->node());
+ }
+
+ Map<const MFOutputSocket *, std::string> attribute_inputs;
+ for (auto item : attribute_nodes_by_name_and_type.items()) {
+ StringRef attribute_name = item.key.first;
+ MFDataType data_type = item.key.second;
+ Span<MFNode *> nodes = item.value;
+
+ MFOutputSocket &new_attribute_socket = context.network.add_input(
+ "Attribute '" + attribute_name + "'", data_type);
+ for (MFNode *node : nodes) {
+ context.network.relink(node->output(0), new_attribute_socket);
+ }
+ context.network.remove(nodes);
+
+ context.data_sources.particle_attributes.add_new(&new_attribute_socket, attribute_name);
+ }
+}
+
+static void prepare_time_input_nodes(CollectContext &context)
+{
+ Span<const DNode *> time_input_dnodes = nodes_by_type(context, "SimulationNodeTime");
+ Vector<const DNode *> simulation_time_inputs;
+ Vector<const DNode *> scene_time_inputs;
+ for (const DNode *dnode : time_input_dnodes) {
+ NodeSimInputTimeType type = (NodeSimInputTimeType)dnode->node_ref().bnode()->custom1;
+ switch (type) {
+ case NODE_SIM_INPUT_SIMULATION_TIME: {
+ simulation_time_inputs.append(dnode);
+ break;
+ }
+ case NODE_SIM_INPUT_SCENE_TIME: {
+ scene_time_inputs.append(dnode);
+ break;
+ }
+ }
+ }
+
+ if (simulation_time_inputs.size() > 0) {
+ MFOutputSocket &new_socket = context.network.add_input("Simulation Time",
+ MFDataType::ForSingle<float>());
+ for (const DNode *dnode : simulation_time_inputs) {
+ MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0));
+ context.network.relink(old_socket, new_socket);
+ context.network.remove(old_socket.node());
+ }
+ context.data_sources.simulation_time.add(&new_socket);
+ }
+ if (scene_time_inputs.size() > 0) {
+ MFOutputSocket &new_socket = context.network.add_input("Scene Time",
+ MFDataType::ForSingle<float>());
+ for (const DNode *dnode : scene_time_inputs) {
+ MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0));
+ context.network.relink(old_socket, new_socket);
+ context.network.remove(old_socket.node());
+ }
+ context.data_sources.scene_time.add(&new_socket);
+ }
+}
+
+class ParticleAttributeInput : public ParticleFunctionInput {
+ private:
+ std::string attribute_name_;
+ const CPPType &attribute_type_;
+
+ public:
+ ParticleAttributeInput(std::string attribute_name, const CPPType &attribute_type)
+ : attribute_name_(std::move(attribute_name)), attribute_type_(attribute_type)
+ {
+ }
+
+ void add_input(ParticleFunctionInputContext &context,
+ MFParamsBuilder &params,
+ ResourceCollector &UNUSED(resources)) const override
+ {
+ std::optional<GSpan> span = context.particles.attributes.try_get(attribute_name_,
+ attribute_type_);
+ if (span.has_value()) {
+ params.add_readonly_single_input(*span);
+ }
+ else {
+ params.add_readonly_single_input(GVSpan::FromDefault(attribute_type_));
+ }
+ }
+};
+
+class SceneTimeInput : public ParticleFunctionInput {
+ void add_input(ParticleFunctionInputContext &context,
+ MFParamsBuilder &params,
+ ResourceCollector &resources) const override
+ {
+ const float time = DEG_get_ctime(&context.solve_context.depsgraph);
+ float *time_ptr = &resources.construct<float>(AT, time);
+ params.add_readonly_single_input(time_ptr);
+ }
+};
+
+class SimulationTimeInput : public ParticleFunctionInput {
+ void add_input(ParticleFunctionInputContext &context,
+ MFParamsBuilder &params,
+ ResourceCollector &resources) const override
+ {
+ /* TODO: Vary this per particle. */
+ const float time = context.solve_context.solve_interval.stop();
+ float *time_ptr = &resources.construct<float>(AT, time);
+ params.add_readonly_single_input(time_ptr);
+ }
+};
+
+static const ParticleFunction *create_particle_function_for_inputs(
+ CollectContext &context, Span<const MFInputSocket *> sockets_to_compute)
+{
+ BLI_assert(sockets_to_compute.size() >= 1);
+ const MFNetwork &network = sockets_to_compute[0]->node().network();
+
+ VectorSet<const MFOutputSocket *> dummy_deps;
+ VectorSet<const MFInputSocket *> unlinked_input_deps;
+ network.find_dependencies(sockets_to_compute, dummy_deps, unlinked_input_deps);
+ BLI_assert(unlinked_input_deps.size() == 0);
+
+ Vector<const ParticleFunctionInput *> per_particle_inputs;
+ for (const MFOutputSocket *socket : dummy_deps) {
+ if (context.data_sources.particle_attributes.contains(socket)) {
+ const std::string *attribute_name = context.data_sources.particle_attributes.lookup_ptr(
+ socket);
+ if (attribute_name == nullptr) {
+ return nullptr;
+ }
+ per_particle_inputs.append(&context.resources.construct<ParticleAttributeInput>(
+ AT, *attribute_name, socket->data_type().single_type()));
+ }
+ else if (context.data_sources.scene_time.contains(socket)) {
+ per_particle_inputs.append(&context.resources.construct<SceneTimeInput>(AT));
+ }
+ else if (context.data_sources.simulation_time.contains(socket)) {
+ per_particle_inputs.append(&context.resources.construct<SimulationTimeInput>(AT));
+ }
+ }
+
+ const MultiFunction &per_particle_fn = context.resources.construct<MFNetworkEvaluator>(
+ AT, dummy_deps.as_span(), sockets_to_compute);
+
+ Array<bool> output_is_global(sockets_to_compute.size(), false);
+
+ const ParticleFunction &particle_fn = context.resources.construct<ParticleFunction>(
+ AT,
+ nullptr,
+ &per_particle_fn,
+ Span<const ParticleFunctionInput *>(),
+ per_particle_inputs.as_span(),
+ output_is_global.as_span());
+
+ return &particle_fn;
+}
+
+static const ParticleFunction *create_particle_function_for_inputs(
+ CollectContext &context, Span<const DInputSocket *> dsockets_to_compute)
+{
+ Vector<const MFInputSocket *> sockets_to_compute;
+ for (const DInputSocket *dsocket : dsockets_to_compute) {
+ const MFInputSocket &socket = context.network_map.lookup_dummy(*dsocket);
+ sockets_to_compute.append(&socket);
+ }
+ return create_particle_function_for_inputs(context, sockets_to_compute);
+}
+
+class ParticleFunctionForce : public ParticleForce {
+ private:
+ const ParticleFunction &particle_fn_;
+
+ public:
+ ParticleFunctionForce(const ParticleFunction &particle_fn) : particle_fn_(particle_fn)
+ {
+ }
+
+ void add_force(ParticleForceContext &context) const override
+ {
+ IndexMask mask = context.particles.index_mask;
+ MutableSpan<float3> r_combined_force = context.force_dst;
+
+ ParticleFunctionEvaluator evaluator{particle_fn_, context.solve_context, context.particles};
+ evaluator.compute();
+ VSpan<float3> forces = evaluator.get<float3>(0, "Force");
+
+ for (int64_t i : mask) {
+ r_combined_force[i] += forces[i];
+ }
+ }
+};
+
+static void create_forces_for_particle_simulation(CollectContext &context,
+ const DNode &simulation_node)
+{
+ Vector<const ParticleForce *> forces;
+ for (const DOutputSocket *origin_socket : simulation_node.input(2, "Forces").linked_sockets()) {
+ const DNode &origin_node = origin_socket->node();
+ if (origin_node.idname() != "SimulationNodeForce") {
+ continue;
+ }
+
+ const ParticleFunction *particle_fn = create_particle_function_for_inputs(
+ context, {&origin_node.input(0, "Force")});
+
+ if (particle_fn == nullptr) {
+ continue;
+ }
+
+ const ParticleForce &force = context.resources.construct<ParticleFunctionForce>(AT,
+ *particle_fn);
+ forces.append(&force);
+ }
+
+ StringRef particle_name = get_identifier(context, simulation_node);
+ context.influences.particle_forces.add_multiple_as(particle_name, forces);
+}
+
+static void collect_forces(CollectContext &context)
+{
+ for (const DNode *dnode : context.particle_simulation_nodes) {
+ create_forces_for_particle_simulation(context, *dnode);
+ }
+}
+
+static ParticleEmitter *create_particle_emitter(CollectContext &context, const DNode &dnode)
+{
+ Array<StringRefNull> names = find_linked_particle_simulations(context, dnode.output(0));
+ if (names.size() == 0) {
+ return nullptr;
+ }
+
+ Array<const MFInputSocket *> input_sockets{2};
+ for (int i : input_sockets.index_range()) {
+ input_sockets[i] = &context.network_map.lookup_dummy(dnode.input(i));
+ }
+
+ if (context.network.have_dummy_or_unlinked_dependencies(input_sockets)) {
+ return nullptr;
+ }
+
+ MultiFunction &inputs_fn = context.resources.construct<MFNetworkEvaluator>(
+ AT, Span<const MFOutputSocket *>(), input_sockets.as_span());
+
+ const ParticleAction *birth_action = create_particle_action(
+ context, dnode.input(2, "Execute"), names);
+
+ StringRefNull own_state_name = get_identifier(context, dnode);
+ context.required_states.add(own_state_name, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER);
+ ParticleEmitter &emitter = context.resources.construct<ParticleMeshEmitter>(
+ AT, own_state_name, names.as_span(), inputs_fn, birth_action);
+ return &emitter;
+}
+
+static void collect_emitters(CollectContext &context)
+{
+ for (const DNode *dnode : nodes_by_type(context, "SimulationNodeParticleMeshEmitter")) {
+ ParticleEmitter *emitter = create_particle_emitter(context, *dnode);
+ if (emitter != nullptr) {
+ context.influences.particle_emitters.append(emitter);
+ }
+ }
+}
+
+static void collect_birth_events(CollectContext &context)
+{
+ for (const DNode *event_dnode : nodes_by_type(context, "SimulationNodeParticleBirthEvent")) {
+ const DInputSocket &execute_input = event_dnode->input(0);
+ if (execute_input.linked_sockets().size() != 1) {
+ continue;
+ }
+
+ Array<StringRefNull> particle_names = find_linked_particle_simulations(context,
+ event_dnode->output(0));
+
+ const DOutputSocket &execute_source = *execute_input.linked_sockets()[0];
+ const ParticleAction *action = create_particle_action(context, execute_source, particle_names);
+ if (action == nullptr) {
+ continue;
+ }
+
+ for (StringRefNull particle_name : particle_names) {
+ context.influences.particle_birth_actions.add_as(particle_name, action);
+ }
+ }
+}
+
+static void collect_time_step_events(CollectContext &context)
+{
+ for (const DNode *event_dnode : nodes_by_type(context, "SimulationNodeParticleTimeStepEvent")) {
+ const DInputSocket &execute_input = event_dnode->input(0);
+ Array<StringRefNull> particle_names = find_linked_particle_simulations(context,
+ event_dnode->output(0));
+
+ const ParticleAction *action = create_particle_action(context, execute_input, particle_names);
+ if (action == nullptr) {
+ continue;
+ }
+
+ NodeSimParticleTimeStepEventType type =
+ (NodeSimParticleTimeStepEventType)event_dnode->node_ref().bnode()->custom1;
+ if (type == NODE_PARTICLE_TIME_STEP_EVENT_BEGIN) {
+ for (StringRefNull particle_name : particle_names) {
+ context.influences.particle_time_step_begin_actions.add_as(particle_name, action);
+ }
+ }
+ else {
+ for (StringRefNull particle_name : particle_names) {
+ context.influences.particle_time_step_end_actions.add_as(particle_name, action);
+ }
+ }
+ }
+}
+
+class SequenceParticleAction : public ParticleAction {
+ private:
+ Vector<const ParticleAction *> actions_;
+
+ public:
+ SequenceParticleAction(Span<const ParticleAction *> actions) : actions_(std::move(actions))
+ {
+ }
+
+ void execute(ParticleActionContext &context) const override
+ {
+ for (const ParticleAction *action : actions_) {
+ action->execute(context);
+ }
+ }
+};
+
+class SetParticleAttributeAction : public ParticleAction {
+ private:
+ std::string attribute_name_;
+ const CPPType &cpp_type_;
+ const ParticleFunction &inputs_fn_;
+
+ public:
+ SetParticleAttributeAction(std::string attribute_name,
+ const CPPType &cpp_type,
+ const ParticleFunction &inputs_fn)
+ : attribute_name_(std::move(attribute_name)), cpp_type_(cpp_type), inputs_fn_(inputs_fn)
+ {
+ }
+
+ void execute(ParticleActionContext &context) const override
+ {
+ std::optional<GMutableSpan> attribute_array = context.particles.attributes.try_get(
+ attribute_name_, cpp_type_);
+ if (!attribute_array.has_value()) {
+ return;
+ }
+
+ ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles};
+ evaluator.compute();
+ GVSpan values = evaluator.get(0);
+
+ if (values.is_single_element()) {
+ cpp_type_.fill_initialized_indices(
+ values.as_single_element(), attribute_array->data(), context.particles.index_mask);
+ }
+ else {
+ GSpan value_array = values.as_full_array();
+ cpp_type_.copy_to_initialized_indices(
+ value_array.data(), attribute_array->data(), context.particles.index_mask);
+ }
+
+ if (attribute_name_ == "Velocity") {
+ context.particles.update_diffs_after_velocity_change();
+ }
+ }
+};
+
+static const ParticleAction *concatenate_actions(CollectContext &context,
+ Span<const ParticleAction *> actions)
+{
+ Vector<const ParticleAction *> non_null_actions;
+ for (const ParticleAction *action : actions) {
+ if (action != nullptr) {
+ non_null_actions.append(action);
+ }
+ }
+ if (non_null_actions.size() == 0) {
+ return nullptr;
+ }
+ if (non_null_actions.size() == 1) {
+ return non_null_actions[0];
+ }
+ return &context.resources.construct<SequenceParticleAction>(AT, std::move(non_null_actions));
+}
+
+static const ParticleAction *create_set_particle_attribute_action(
+ CollectContext &context, const DOutputSocket &dsocket, Span<StringRefNull> particle_names)
+{
+ const DNode &dnode = dsocket.node();
+
+ const ParticleAction *previous_action = create_particle_action(
+ context, dnode.input(0), particle_names);
+
+ MFInputSocket &name_socket = context.network_map.lookup_dummy(dnode.input(1));
+ MFInputSocket &value_socket = name_socket.node().input(1);
+ std::optional<Array<std::string>> names = compute_global_string_inputs(context.network_map,
+ {&name_socket});
+ if (!names.has_value()) {
+ return previous_action;
+ }
+
+ std::string attribute_name = (*names)[0];
+ if (attribute_name.empty()) {
+ return previous_action;
+ }
+ const CPPType &attribute_type = value_socket.data_type().single_type();
+
+ const ParticleFunction *inputs_fn = create_particle_function_for_inputs(context,
+ {&value_socket});
+ if (inputs_fn == nullptr) {
+ return previous_action;
+ }
+
+ for (StringRef particle_name : particle_names) {
+ context.influences.particle_attributes_builder.lookup_as(particle_name)
+ ->add(attribute_name, attribute_type);
+ }
+
+ ParticleAction &this_action = context.resources.construct<SetParticleAttributeAction>(
+ AT, attribute_name, attribute_type, *inputs_fn);
+
+ return concatenate_actions(context, {previous_action, &this_action});
+}
+
+class ParticleConditionAction : public ParticleAction {
+ private:
+ const ParticleFunction &inputs_fn_;
+ const ParticleAction *action_true_;
+ const ParticleAction *action_false_;
+
+ public:
+ ParticleConditionAction(const ParticleFunction &inputs_fn,
+ const ParticleAction *action_true,
+ const ParticleAction *action_false)
+ : inputs_fn_(inputs_fn), action_true_(action_true), action_false_(action_false)
+ {
+ }
+
+ void execute(ParticleActionContext &context) const override
+ {
+ ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles};
+ evaluator.compute();
+ VSpan<bool> conditions = evaluator.get<bool>(0, "Condition");
+
+ if (conditions.is_single_element()) {
+ const bool condition = conditions.as_single_element();
+ if (condition) {
+ if (action_true_ != nullptr) {
+ action_true_->execute(context);
+ }
+ }
+ else {
+ if (action_false_ != nullptr) {
+ action_false_->execute(context);
+ }
+ }
+ }
+ else {
+ Span<bool> conditions_array = conditions.as_full_array();
+
+ Vector<int64_t> true_indices;
+ Vector<int64_t> false_indices;
+ for (int i : context.particles.index_mask) {
+ if (conditions_array[i]) {
+ true_indices.append(i);
+ }
+ else {
+ false_indices.append(i);
+ }
+ }
+
+ if (action_true_ != nullptr) {
+ ParticleChunkContext chunk_context{context.particles.state,
+ true_indices.as_span(),
+ context.particles.attributes,
+ context.particles.integration};
+ ParticleActionContext action_context{context.solve_context, chunk_context};
+ action_true_->execute(action_context);
+ }
+ if (action_false_ != nullptr) {
+ ParticleChunkContext chunk_context{context.particles.state,
+ false_indices.as_span(),
+ context.particles.attributes,
+ context.particles.integration};
+ ParticleActionContext action_context{context.solve_context, chunk_context};
+ action_false_->execute(action_context);
+ }
+ }
+ }
+};
+
+static const ParticleAction *create_particle_condition_action(CollectContext &context,
+ const DOutputSocket &dsocket,
+ Span<StringRefNull> particle_names)
+{
+ const DNode &dnode = dsocket.node();
+
+ const ParticleFunction *inputs_fn = create_particle_function_for_inputs(
+ context, {&dnode.input(0, "Condition")});
+ if (inputs_fn == nullptr) {
+ return nullptr;
+ }
+
+ const ParticleAction *true_action = create_particle_action(
+ context, dnode.input(1), particle_names);
+ const ParticleAction *false_action = create_particle_action(
+ context, dnode.input(2), particle_names);
+
+ if (true_action == nullptr && false_action == nullptr) {
+ return nullptr;
+ }
+ return &context.resources.construct<ParticleConditionAction>(
+ AT, *inputs_fn, true_action, false_action);
+}
+
+class KillParticleAction : public ParticleAction {
+ public:
+ void execute(ParticleActionContext &context) const override
+ {
+ MutableSpan<int> dead_states = context.particles.attributes.get<int>("Dead");
+ for (int i : context.particles.index_mask) {
+ dead_states[i] = true;
+ }
+ }
+};
+
+static const ParticleAction *create_particle_action(CollectContext &context,
+ const DOutputSocket &dsocket,
+ Span<StringRefNull> particle_names)
+{
+ const DNode &dnode = dsocket.node();
+ StringRef idname = dnode.idname();
+ if (idname == "SimulationNodeSetParticleAttribute") {
+ return create_set_particle_attribute_action(context, dsocket, particle_names);
+ }
+ if (idname == "SimulationNodeExecuteCondition") {
+ return create_particle_condition_action(context, dsocket, particle_names);
+ }
+ if (idname == "SimulationNodeKillParticle") {
+ return &context.resources.construct<KillParticleAction>(AT);
+ }
+ return nullptr;
+}
+
+static void initialize_particle_attribute_builders(CollectContext &context)
+{
+ for (const DNode *dnode : context.particle_simulation_nodes) {
+ StringRef name = get_identifier(context, *dnode);
+ AttributesInfoBuilder &attributes_builder = context.resources.construct<AttributesInfoBuilder>(
+ AT);
+ attributes_builder.add<float3>("Position", {0, 0, 0});
+ attributes_builder.add<float3>("Velocity", {0, 0, 0});
+ attributes_builder.add<int>("ID", 0);
+ /* TODO: Use bool property, but need to add CD_PROP_BOOL first. */
+ attributes_builder.add<int>("Dead", 0);
+ /* TODO: Use uint32_t, but we don't have a corresponding custom property type. */
+ attributes_builder.add<int>("Hash", 0);
+ attributes_builder.add<float>("Birth Time", 0.0f);
+ attributes_builder.add<float>("Radius", 0.02f);
+ context.influences.particle_attributes_builder.add_new(name, &attributes_builder);
+ }
+}
+
+static void optimize_function_network(CollectContext &context)
+{
+ fn::mf_network_optimization::constant_folding(context.network, context.resources);
+ fn::mf_network_optimization::common_subnetwork_elimination(context.network);
+ fn::mf_network_optimization::dead_node_removal(context.network);
+ // WM_clipboard_text_set(network.to_dot().c_str(), false);
+}
+
+class AgeReachedEvent : public ParticleEvent {
+ private:
+ std::string attribute_name_;
+ const ParticleFunction &inputs_fn_;
+ const ParticleAction &action_;
+
+ public:
+ AgeReachedEvent(std::string attribute_name,
+ const ParticleFunction &inputs_fn,
+ const ParticleAction &action)
+ : attribute_name_(std::move(attribute_name)), inputs_fn_(inputs_fn), action_(action)
+ {
+ }
+
+ void filter(ParticleEventFilterContext &context) const override
+ {
+ Span<float> birth_times = context.particles.attributes.get<float>("Birth Time");
+ std::optional<Span<int>> has_been_triggered = context.particles.attributes.try_get<int>(
+ attribute_name_);
+ if (!has_been_triggered.has_value()) {
+ return;
+ }
+
+ ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles};
+ evaluator.compute();
+ VSpan<float> trigger_ages = evaluator.get<float>(0, "Age");
+
+ const float end_time = context.particles.integration->end_time;
+ for (int i : context.particles.index_mask) {
+ if ((*has_been_triggered)[i]) {
+ continue;
+ }
+ const float trigger_age = trigger_ages[i];
+ const float birth_time = birth_times[i];
+ const float trigger_time = birth_time + trigger_age;
+ if (trigger_time > end_time) {
+ continue;
+ }
+
+ const float duration = context.particles.integration->durations[i];
+ TimeInterval interval(end_time - duration, duration);
+ const float time_factor = interval.safe_factor_at_time(trigger_time);
+
+ context.factor_dst[i] = std::max<float>(0.0f, time_factor);
+ }
+ }
+
+ void execute(ParticleActionContext &context) const override
+ {
+ MutableSpan<int> has_been_triggered = context.particles.attributes.get<int>(attribute_name_);
+ for (int i : context.particles.index_mask) {
+ has_been_triggered[i] = 1;
+ }
+ action_.execute(context);
+ }
+};
+
+static void collect_age_reached_events(CollectContext &context)
+{
+ for (const DNode *dnode : nodes_by_type(context, "SimulationNodeAgeReachedEvent")) {
+ const DInputSocket &age_input = dnode->input(0, "Age");
+ const DInputSocket &execute_input = dnode->input(1, "Execute");
+ Array<StringRefNull> particle_names = find_linked_particle_simulations(context,
+ dnode->output(0));
+ const ParticleAction *action = create_particle_action(context, execute_input, particle_names);
+ if (action == nullptr) {
+ continue;
+ }
+ const ParticleFunction *inputs_fn = create_particle_function_for_inputs(context, {&age_input});
+ if (inputs_fn == nullptr) {
+ continue;
+ }
+
+ std::string attribute_name = get_identifier(context, *dnode);
+ const ParticleEvent &event = context.resources.construct<AgeReachedEvent>(
+ AT, attribute_name, *inputs_fn, *action);
+ for (StringRefNull particle_name : particle_names) {
+ const bool added_attribute = context.influences.particle_attributes_builder
+ .lookup_as(particle_name)
+ ->add<int>(attribute_name, 0);
+ if (added_attribute) {
+ context.influences.particle_events.add_as(particle_name, &event);
+ }
+ }
+ }
+}
+
+void collect_simulation_influences(Simulation &simulation,
+ ResourceCollector &resources,
+ SimulationInfluences &r_influences,
+ RequiredStates &r_required_states)
+{
+ NodeTreeRefMap tree_refs;
+ const DerivedNodeTree tree{simulation.nodetree, tree_refs};
+
+ MFNetwork &network = resources.construct<MFNetwork>(AT);
+ MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources);
+
+ CollectContext context{r_influences, r_required_states, resources, network_map};
+ initialize_particle_attribute_builders(context);
+
+ prepare_particle_attribute_nodes(context);
+ prepare_time_input_nodes(context);
+
+ collect_forces(context);
+ collect_emitters(context);
+ collect_birth_events(context);
+ collect_time_step_events(context);
+ collect_age_reached_events(context);
+
+ optimize_function_network(context);
+
+ for (const DNode *dnode : context.particle_simulation_nodes) {
+ r_required_states.add(get_identifier(context, *dnode), SIM_TYPE_NAME_PARTICLE_SIMULATION);
+ }
+}
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_collect_influences.hh b/source/blender/simulation/intern/simulation_collect_influences.hh
new file mode 100644
index 00000000000..8673a308b04
--- /dev/null
+++ b/source/blender/simulation/intern/simulation_collect_influences.hh
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "NOD_derived_node_tree.hh"
+
+#include "BLI_resource_collector.hh"
+
+#include "simulation_solver_influences.hh"
+
+namespace blender::sim {
+
+class RequiredStates {
+ private:
+ Map<std::string, const char *> state_type_by_state_name_;
+
+ public:
+ void add(std::string state_name, const char *state_type)
+ {
+ BLI_assert(state_type != nullptr);
+ const char *type_name = state_type_by_state_name_.lookup_default(state_name, nullptr);
+ if (type_name != nullptr) {
+ if (!STREQ(state_type, type_name)) {
+ std::cout << "Warning: Tried to have two different states with the same name.\n";
+ std::cout << " Name: " << state_name << "\n";
+ std::cout << " Type 1: " << state_type << "\n";
+ std::cout << " Type 2: " << type_name << "\n";
+ }
+ return;
+ }
+
+ state_type_by_state_name_.add(std::move(state_name), state_type);
+ }
+
+ const Map<std::string, const char *> &states() const
+ {
+ return state_type_by_state_name_;
+ }
+
+ bool is_required(StringRef state_name, StringRef state_type) const
+ {
+ return state_type_by_state_name_.lookup_default_as(state_name, "") == state_type;
+ }
+};
+
+void collect_simulation_influences(Simulation &simulation,
+ ResourceCollector &resources,
+ SimulationInfluences &r_influences,
+ RequiredStates &r_required_states);
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc
new file mode 100644
index 00000000000..d53ccd2bd49
--- /dev/null
+++ b/source/blender/simulation/intern/simulation_solver.cc
@@ -0,0 +1,522 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "simulation_solver.hh"
+
+#include "BKE_customdata.h"
+#include "BKE_persistent_data_handle.hh"
+
+#include "BLI_rand.hh"
+#include "BLI_set.hh"
+
+#include "DEG_depsgraph_query.h"
+
+namespace blender::sim {
+
+static CustomDataType cpp_to_custom_data_type(const CPPType &type)
+{
+ if (type.is<float3>()) {
+ return CD_PROP_FLOAT3;
+ }
+ if (type.is<float>()) {
+ return CD_PROP_FLOAT;
+ }
+ if (type.is<int32_t>()) {
+ return CD_PROP_INT32;
+ }
+ BLI_assert(false);
+ return CD_PROP_FLOAT;
+}
+
+static const CPPType &custom_to_cpp_data_type(CustomDataType type)
+{
+ switch (type) {
+ case CD_PROP_FLOAT3:
+ return CPPType::get<float3>();
+ case CD_PROP_FLOAT:
+ return CPPType::get<float>();
+ case CD_PROP_INT32:
+ return CPPType::get<int32_t>();
+ default:
+ BLI_assert(false);
+ return CPPType::get<float>();
+ }
+}
+
+class CustomDataAttributesRef {
+ private:
+ Array<void *> buffers_;
+ int64_t size_;
+ const AttributesInfo &info_;
+
+ public:
+ CustomDataAttributesRef(CustomData &custom_data, int64_t size, const AttributesInfo &info)
+ : buffers_(info.size(), nullptr), size_(size), info_(info)
+ {
+ for (int attribute_index : info.index_range()) {
+ StringRefNull name = info.name_of(attribute_index);
+ const CPPType &cpp_type = info.type_of(attribute_index);
+ CustomDataType custom_type = cpp_to_custom_data_type(cpp_type);
+ void *data = CustomData_get_layer_named(&custom_data, custom_type, name.c_str());
+ buffers_[attribute_index] = data;
+ }
+ }
+
+ operator MutableAttributesRef()
+ {
+ return MutableAttributesRef(info_, buffers_, size_);
+ }
+
+ operator AttributesRef() const
+ {
+ return AttributesRef(info_, buffers_, size_);
+ }
+};
+
+static void ensure_attributes_exist(ParticleSimulationState *state, const AttributesInfo &info)
+{
+ bool found_layer_to_remove;
+ do {
+ found_layer_to_remove = false;
+ for (int layer_index = 0; layer_index < state->attributes.totlayer; layer_index++) {
+ CustomDataLayer *layer = &state->attributes.layers[layer_index];
+ BLI_assert(layer->name != nullptr);
+ const CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer->type);
+ StringRefNull name = layer->name;
+ if (!info.has_attribute(name, cpp_type)) {
+ found_layer_to_remove = true;
+ CustomData_free_layer(&state->attributes, layer->type, state->tot_particles, layer_index);
+ break;
+ }
+ }
+ } while (found_layer_to_remove);
+
+ for (int attribute_index : info.index_range()) {
+ StringRefNull attribute_name = info.name_of(attribute_index);
+ const CPPType &cpp_type = info.type_of(attribute_index);
+ CustomDataType custom_type = cpp_to_custom_data_type(cpp_type);
+ if (CustomData_get_layer_named(&state->attributes, custom_type, attribute_name.c_str()) ==
+ nullptr) {
+ void *data = CustomData_add_layer_named(&state->attributes,
+ custom_type,
+ CD_CALLOC,
+ nullptr,
+ state->tot_particles,
+ attribute_name.c_str());
+ cpp_type.fill_uninitialized(info.default_of(attribute_index), data, state->tot_particles);
+ }
+ }
+}
+
+BLI_NOINLINE static void apply_remaining_diffs(ParticleChunkContext &context)
+{
+ BLI_assert(context.integration != nullptr);
+ MutableSpan<float3> positions = context.attributes.get<float3>("Position");
+ MutableSpan<float3> velocities = context.attributes.get<float3>("Velocity");
+
+ for (int i : context.index_mask) {
+ positions[i] += context.integration->position_diffs[i];
+ velocities[i] += context.integration->velocity_diffs[i];
+ }
+}
+
+BLI_NOINLINE static void find_next_event_per_particle(
+ SimulationSolveContext &solve_context,
+ ParticleChunkContext &particles,
+ Span<const ParticleEvent *> events,
+ MutableSpan<int> r_next_event_indices,
+ MutableSpan<float> r_time_factors_to_next_event)
+{
+ r_next_event_indices.fill_indices(particles.index_mask, -1);
+ r_time_factors_to_next_event.fill_indices(particles.index_mask, 1.0f);
+
+ Array<float> time_factors(particles.index_mask.min_array_size());
+ for (int event_index : events.index_range()) {
+ time_factors.fill(-1.0f);
+ ParticleEventFilterContext event_context{solve_context, particles, time_factors};
+ const ParticleEvent &event = *events[event_index];
+ event.filter(event_context);
+
+ for (int i : particles.index_mask) {
+ const float time_factor = time_factors[i];
+ const float previously_smallest_time_factor = r_time_factors_to_next_event[i];
+ if (time_factor >= 0.0f && time_factor <= previously_smallest_time_factor) {
+ r_time_factors_to_next_event[i] = time_factor;
+ r_next_event_indices[i] = event_index;
+ }
+ }
+ }
+}
+
+BLI_NOINLINE static void forward_particles_to_next_event_or_end(
+ ParticleChunkContext &particles, Span<float> time_factors_to_next_event)
+{
+ MutableSpan<float3> positions = particles.attributes.get<float3>("Position");
+ MutableSpan<float3> velocities = particles.attributes.get<float3>("Velocity");
+
+ MutableSpan<float3> position_diffs = particles.integration->position_diffs;
+ MutableSpan<float3> velocity_diffs = particles.integration->velocity_diffs;
+ MutableSpan<float> durations = particles.integration->durations;
+
+ for (int i : particles.index_mask) {
+ const float time_factor = time_factors_to_next_event[i];
+ positions[i] += position_diffs[i] * time_factor;
+ velocities[i] += velocity_diffs[i] * time_factor;
+
+ const float remaining_time_factor = 1.0f - time_factor;
+ position_diffs[i] *= remaining_time_factor;
+ velocity_diffs[i] *= remaining_time_factor;
+ durations[i] *= remaining_time_factor;
+ }
+}
+
+BLI_NOINLINE static void group_particles_by_event(
+ IndexMask mask,
+ Span<int> next_event_indices,
+ MutableSpan<Vector<int64_t>> r_particles_per_event)
+{
+ for (int i : mask) {
+ int event_index = next_event_indices[i];
+ if (event_index >= 0) {
+ r_particles_per_event[event_index].append(i);
+ }
+ }
+}
+
+BLI_NOINLINE static void execute_events(SimulationSolveContext &solve_context,
+ ParticleChunkContext &all_particles,
+ Span<const ParticleEvent *> events,
+ Span<Vector<int64_t>> particles_per_event)
+{
+ for (int event_index : events.index_range()) {
+ Span<int64_t> pindices = particles_per_event[event_index];
+ if (pindices.is_empty()) {
+ continue;
+ }
+
+ const ParticleEvent &event = *events[event_index];
+ ParticleChunkContext particles{
+ all_particles.state, pindices, all_particles.attributes, all_particles.integration};
+ ParticleActionContext action_context{solve_context, particles};
+ event.execute(action_context);
+ }
+}
+
+BLI_NOINLINE static void find_unfinished_particles(IndexMask index_mask,
+ Span<float> time_factors_to_next_event,
+ Vector<int64_t> &r_unfinished_pindices)
+{
+ for (int i : index_mask) {
+ float time_factor = time_factors_to_next_event[i];
+ if (time_factor < 1.0f) {
+ r_unfinished_pindices.append(i);
+ }
+ }
+}
+
+BLI_NOINLINE static void simulate_to_next_event(SimulationSolveContext &solve_context,
+ ParticleChunkContext &particles,
+ Span<const ParticleEvent *> events,
+ Vector<int64_t> &r_unfinished_pindices)
+{
+ int array_size = particles.index_mask.min_array_size();
+ Array<int> next_event_indices(array_size);
+ Array<float> time_factors_to_next_event(array_size);
+
+ find_next_event_per_particle(
+ solve_context, particles, events, next_event_indices, time_factors_to_next_event);
+
+ forward_particles_to_next_event_or_end(particles, time_factors_to_next_event);
+
+ Array<Vector<int64_t>> particles_per_event(events.size());
+ group_particles_by_event(particles.index_mask, next_event_indices, particles_per_event);
+
+ execute_events(solve_context, particles, events, particles_per_event);
+ find_unfinished_particles(
+ particles.index_mask, time_factors_to_next_event, r_unfinished_pindices);
+}
+
+BLI_NOINLINE static void simulate_with_max_n_events(SimulationSolveContext &solve_context,
+ ParticleSimulationState &state,
+ ParticleChunkContext &particles,
+ int max_events)
+{
+ Span<const ParticleEvent *> events = solve_context.influences.particle_events.lookup_as(
+ state.head.name);
+ if (events.size() == 0) {
+ apply_remaining_diffs(particles);
+ return;
+ }
+
+ Vector<int64_t> unfininished_pindices = particles.index_mask.indices();
+ for (int iteration : IndexRange(max_events)) {
+ UNUSED_VARS(iteration);
+ if (unfininished_pindices.is_empty()) {
+ break;
+ }
+
+ Vector<int64_t> new_unfinished_pindices;
+ ParticleChunkContext remaining_particles{particles.state,
+ unfininished_pindices.as_span(),
+ particles.attributes,
+ particles.integration};
+ simulate_to_next_event(solve_context, remaining_particles, events, new_unfinished_pindices);
+ unfininished_pindices = std::move(new_unfinished_pindices);
+ }
+
+ if (!unfininished_pindices.is_empty()) {
+ ParticleChunkContext remaining_particles{particles.state,
+ unfininished_pindices.as_span(),
+ particles.attributes,
+ particles.integration};
+ apply_remaining_diffs(remaining_particles);
+ }
+}
+
+BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_context,
+ ParticleSimulationState &state,
+ MutableAttributesRef attributes,
+ MutableSpan<float> remaining_durations,
+ float end_time)
+{
+ int particle_amount = attributes.size();
+
+ Span<const ParticleAction *> begin_actions =
+ solve_context.influences.particle_time_step_begin_actions.lookup_as(state.head.name);
+ for (const ParticleAction *action : begin_actions) {
+ ParticleChunkContext particles{state, IndexMask(particle_amount), attributes};
+ ParticleActionContext action_context{solve_context, particles};
+ action->execute(action_context);
+ }
+
+ Array<float3> force_vectors{particle_amount, {0, 0, 0}};
+ Span<const ParticleForce *> forces = solve_context.influences.particle_forces.lookup_as(
+ state.head.name);
+ for (const ParticleForce *force : forces) {
+ ParticleChunkContext particles{state, IndexMask(particle_amount), attributes};
+ ParticleForceContext particle_force_context{solve_context, particles, force_vectors};
+ force->add_force(particle_force_context);
+ }
+
+ MutableSpan<float3> velocities = attributes.get<float3>("Velocity");
+
+ Array<float3> position_diffs(particle_amount);
+ Array<float3> velocity_diffs(particle_amount);
+ for (int i : IndexRange(particle_amount)) {
+ const float time_step = remaining_durations[i];
+ velocity_diffs[i] = force_vectors[i] * time_step;
+ position_diffs[i] = (velocities[i] + velocity_diffs[i] / 2.0f) * time_step;
+ }
+
+ ParticleChunkIntegrationContext integration_context = {
+ position_diffs, velocity_diffs, remaining_durations, end_time};
+ ParticleChunkContext particle_chunk_context{
+ state, IndexMask(particle_amount), attributes, &integration_context};
+
+ simulate_with_max_n_events(solve_context, state, particle_chunk_context, 10);
+
+ Span<const ParticleAction *> end_actions =
+ solve_context.influences.particle_time_step_end_actions.lookup_as(state.head.name);
+ for (const ParticleAction *action : end_actions) {
+ ParticleChunkContext particles{state, IndexMask(particle_amount), attributes};
+ ParticleActionContext action_context{solve_context, particles};
+ action->execute(action_context);
+ }
+}
+
+BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &solve_context,
+ ParticleSimulationState &state,
+ const AttributesInfo &attributes_info)
+{
+ CustomDataAttributesRef custom_data_attributes{
+ state.attributes, state.tot_particles, attributes_info};
+ MutableAttributesRef attributes = custom_data_attributes;
+
+ Array<float> remaining_durations(state.tot_particles, solve_context.solve_interval.duration());
+ simulate_particle_chunk(
+ solve_context, state, attributes, remaining_durations, solve_context.solve_interval.stop());
+}
+
+BLI_NOINLINE static void run_emitters(SimulationSolveContext &solve_context,
+ ParticleAllocators &particle_allocators)
+{
+ for (const ParticleEmitter *emitter : solve_context.influences.particle_emitters) {
+ ParticleEmitterContext emitter_context{
+ solve_context, particle_allocators, solve_context.solve_interval};
+ emitter->emit(emitter_context);
+ }
+}
+
+BLI_NOINLINE static int count_particles_after_time_step(ParticleSimulationState &state,
+ ParticleAllocator &allocator)
+{
+ CustomDataAttributesRef custom_data_attributes{
+ state.attributes, state.tot_particles, allocator.attributes_info()};
+ MutableAttributesRef attributes = custom_data_attributes;
+ int new_particle_amount = attributes.get<int>("Dead").count(0);
+
+ for (MutableAttributesRef emitted_attributes : allocator.get_allocations()) {
+ new_particle_amount += emitted_attributes.get<int>("Dead").count(0);
+ }
+
+ return new_particle_amount;
+}
+
+BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationState &state,
+ ParticleAllocator &allocator)
+{
+ const int new_particle_amount = count_particles_after_time_step(state, allocator);
+
+ CustomDataAttributesRef custom_data_attributes{
+ state.attributes, state.tot_particles, allocator.attributes_info()};
+
+ Vector<MutableAttributesRef> particle_sources;
+ particle_sources.append(custom_data_attributes);
+ particle_sources.extend(allocator.get_allocations());
+
+ CustomDataLayer *dead_layer = nullptr;
+
+ for (CustomDataLayer &layer : MutableSpan(state.attributes.layers, state.attributes.totlayer)) {
+ StringRefNull name = layer.name;
+ if (name == "Dead") {
+ dead_layer = &layer;
+ continue;
+ }
+ const CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer.type);
+ GMutableSpan new_buffer{
+ cpp_type,
+ MEM_mallocN_aligned(new_particle_amount * cpp_type.size(), cpp_type.alignment(), AT),
+ new_particle_amount};
+
+ int current = 0;
+ for (MutableAttributesRef attributes : particle_sources) {
+ Span<int> dead_states = attributes.get<int>("Dead");
+ GSpan source_buffer = attributes.get(name);
+ BLI_assert(source_buffer.type() == cpp_type);
+ for (int i : attributes.index_range()) {
+ if (dead_states[i] == 0) {
+ cpp_type.copy_to_uninitialized(source_buffer[i], new_buffer[current]);
+ current++;
+ }
+ }
+ }
+
+ if (layer.data != nullptr) {
+ MEM_freeN(layer.data);
+ }
+ layer.data = new_buffer.data();
+ }
+
+ BLI_assert(dead_layer != nullptr);
+ if (dead_layer->data != nullptr) {
+ MEM_freeN(dead_layer->data);
+ }
+ dead_layer->data = MEM_callocN(sizeof(int) * new_particle_amount, AT);
+
+ state.tot_particles = new_particle_amount;
+ state.next_particle_id += allocator.total_allocated();
+}
+
+void initialize_simulation_states(Simulation &simulation,
+ Depsgraph &UNUSED(depsgraph),
+ const SimulationInfluences &UNUSED(influences),
+ const bke::PersistentDataHandleMap &UNUSED(handle_map))
+{
+ simulation.current_simulation_time = 0.0f;
+}
+
+void solve_simulation_time_step(Simulation &simulation,
+ Depsgraph &depsgraph,
+ const SimulationInfluences &influences,
+ const bke::PersistentDataHandleMap &handle_map,
+ const DependencyAnimations &dependency_animations,
+ float time_step)
+{
+ SimulationStateMap state_map;
+ LISTBASE_FOREACH (SimulationState *, state, &simulation.states) {
+ state_map.add(state);
+ }
+
+ SimulationSolveContext solve_context{simulation,
+ depsgraph,
+ influences,
+ TimeInterval(simulation.current_simulation_time, time_step),
+ state_map,
+ handle_map,
+ dependency_animations};
+
+ Span<ParticleSimulationState *> particle_simulation_states =
+ state_map.lookup<ParticleSimulationState>();
+
+ Map<std::string, std::unique_ptr<AttributesInfo>> attribute_infos;
+ Map<std::string, std::unique_ptr<ParticleAllocator>> particle_allocators_map;
+ for (ParticleSimulationState *state : particle_simulation_states) {
+ const AttributesInfoBuilder &builder = *influences.particle_attributes_builder.lookup_as(
+ state->head.name);
+ auto info = std::make_unique<AttributesInfo>(builder);
+
+ ensure_attributes_exist(state, *info);
+
+ uint32_t hash_seed = DefaultHash<StringRef>{}(state->head.name);
+ particle_allocators_map.add_new(
+ state->head.name,
+ std::make_unique<ParticleAllocator>(*info, state->next_particle_id, hash_seed));
+ attribute_infos.add_new(state->head.name, std::move(info));
+ }
+
+ ParticleAllocators particle_allocators{particle_allocators_map};
+
+ for (ParticleSimulationState *state : particle_simulation_states) {
+ const AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name);
+ simulate_existing_particles(solve_context, *state, attributes_info);
+ }
+
+ run_emitters(solve_context, particle_allocators);
+
+ for (ParticleSimulationState *state : particle_simulation_states) {
+ ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name);
+
+ for (MutableAttributesRef attributes : allocator.get_allocations()) {
+ Span<const ParticleAction *> actions = influences.particle_birth_actions.lookup_as(
+ state->head.name);
+ for (const ParticleAction *action : actions) {
+ ParticleChunkContext chunk_context{*state, IndexRange(attributes.size()), attributes};
+ ParticleActionContext action_context{solve_context, chunk_context};
+ action->execute(action_context);
+ }
+ }
+ }
+
+ for (ParticleSimulationState *state : particle_simulation_states) {
+ ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name);
+
+ for (MutableAttributesRef attributes : allocator.get_allocations()) {
+ Array<float> remaining_durations(attributes.size());
+ Span<float> birth_times = attributes.get<float>("Birth Time");
+ const float end_time = solve_context.solve_interval.stop();
+ for (int i : attributes.index_range()) {
+ remaining_durations[i] = end_time - birth_times[i];
+ }
+ simulate_particle_chunk(solve_context, *state, attributes, remaining_durations, end_time);
+ }
+
+ remove_dead_and_add_new_particles(*state, allocator);
+ }
+
+ simulation.current_simulation_time = solve_context.solve_interval.stop();
+}
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_solver.hh b/source/blender/simulation/intern/simulation_solver.hh
new file mode 100644
index 00000000000..2cf8eb2aa27
--- /dev/null
+++ b/source/blender/simulation/intern/simulation_solver.hh
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "simulation_collect_influences.hh"
+
+struct Depsgraph;
+
+namespace blender::sim {
+
+void initialize_simulation_states(Simulation &simulation,
+ Depsgraph &depsgraph,
+ const SimulationInfluences &influences,
+ const bke::PersistentDataHandleMap &handle_map);
+
+void solve_simulation_time_step(Simulation &simulation,
+ Depsgraph &depsgraph,
+ const SimulationInfluences &influences,
+ const bke::PersistentDataHandleMap &handle_map,
+ const DependencyAnimations &dependency_animations,
+ float time_step);
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_solver_influences.cc b/source/blender/simulation/intern/simulation_solver_influences.cc
new file mode 100644
index 00000000000..3485d7c7bfb
--- /dev/null
+++ b/source/blender/simulation/intern/simulation_solver_influences.cc
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "simulation_solver_influences.hh"
+
+#include "DNA_object_types.h"
+
+namespace blender::sim {
+
+ParticleForce::~ParticleForce()
+{
+}
+
+ParticleEmitter::~ParticleEmitter()
+{
+}
+
+ParticleAction::~ParticleAction()
+{
+}
+
+ParticleEvent::~ParticleEvent()
+{
+}
+
+DependencyAnimations::~DependencyAnimations()
+{
+}
+
+bool DependencyAnimations::is_object_transform_changing(Object &UNUSED(object)) const
+{
+ return false;
+}
+
+void DependencyAnimations::get_object_transforms(Object &object,
+ Span<float> simulation_times,
+ MutableSpan<float4x4> r_transforms) const
+{
+ assert_same_size(simulation_times, r_transforms);
+ float4x4 world_matrix = object.obmat;
+ r_transforms.fill(world_matrix);
+}
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_solver_influences.hh b/source/blender/simulation/intern/simulation_solver_influences.hh
new file mode 100644
index 00000000000..d7914819d36
--- /dev/null
+++ b/source/blender/simulation/intern/simulation_solver_influences.hh
@@ -0,0 +1,234 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "BLI_float3.hh"
+#include "BLI_float4x4.hh"
+#include "BLI_multi_value_map.hh"
+#include "BLI_span.hh"
+
+#include "DNA_simulation_types.h"
+
+#include "FN_attributes_ref.hh"
+
+#include "BKE_persistent_data_handle.hh"
+#include "BKE_simulation.h"
+
+#include "particle_allocator.hh"
+#include "time_interval.hh"
+
+namespace blender::sim {
+
+using fn::AttributesInfo;
+using fn::AttributesInfoBuilder;
+using fn::AttributesRef;
+using fn::CPPType;
+using fn::GMutableSpan;
+using fn::GSpan;
+using fn::MutableAttributesRef;
+
+struct ParticleEmitterContext;
+struct ParticleForceContext;
+struct ParticleActionContext;
+struct ParticleEventFilterContext;
+
+class ParticleEmitter {
+ public:
+ virtual ~ParticleEmitter();
+ virtual void emit(ParticleEmitterContext &context) const = 0;
+};
+
+class ParticleForce {
+ public:
+ virtual ~ParticleForce();
+ virtual void add_force(ParticleForceContext &context) const = 0;
+};
+
+class ParticleAction {
+ public:
+ virtual ~ParticleAction();
+ virtual void execute(ParticleActionContext &context) const = 0;
+};
+
+class ParticleEvent {
+ public:
+ virtual ~ParticleEvent();
+ virtual void filter(ParticleEventFilterContext &context) const = 0;
+ virtual void execute(ParticleActionContext &context) const = 0;
+};
+
+struct SimulationInfluences {
+ MultiValueMap<std::string, const ParticleForce *> particle_forces;
+ MultiValueMap<std::string, const ParticleAction *> particle_birth_actions;
+ MultiValueMap<std::string, const ParticleAction *> particle_time_step_begin_actions;
+ MultiValueMap<std::string, const ParticleAction *> particle_time_step_end_actions;
+ MultiValueMap<std::string, const ParticleEvent *> particle_events;
+ Map<std::string, AttributesInfoBuilder *> particle_attributes_builder;
+ Vector<const ParticleEmitter *> particle_emitters;
+};
+
+class SimulationStateMap {
+ private:
+ Map<StringRefNull, SimulationState *> states_by_name_;
+ MultiValueMap<StringRefNull, SimulationState *> states_by_type_;
+
+ public:
+ void add(SimulationState *state)
+ {
+ states_by_name_.add_new(state->name, state);
+ states_by_type_.add(state->type, state);
+ }
+
+ template<typename StateType> StateType *lookup(StringRef name) const
+ {
+ const char *type = BKE_simulation_get_state_type_name<StateType>();
+ return (StateType *)this->lookup_name_type(name, type);
+ }
+
+ template<typename StateType> Span<StateType *> lookup() const
+ {
+ const char *type = BKE_simulation_get_state_type_name<StateType>();
+ return this->lookup_type(type).cast<StateType *>();
+ }
+
+ SimulationState *lookup_name_type(StringRef name, StringRef type) const
+ {
+ SimulationState *state = states_by_name_.lookup_default_as(name, nullptr);
+ if (state == nullptr) {
+ return nullptr;
+ }
+ if (state->type == type) {
+ return state;
+ }
+ return nullptr;
+ }
+
+ Span<SimulationState *> lookup_type(StringRef type) const
+ {
+ return states_by_type_.lookup_as(type);
+ }
+};
+
+class DependencyAnimations {
+ public:
+ ~DependencyAnimations();
+
+ virtual bool is_object_transform_changing(Object &object) const;
+ virtual void get_object_transforms(Object &object,
+ Span<float> simulation_times,
+ MutableSpan<float4x4> r_transforms) const;
+};
+
+struct SimulationSolveContext {
+ Simulation &simulation;
+ Depsgraph &depsgraph;
+ const SimulationInfluences &influences;
+ TimeInterval solve_interval;
+ const SimulationStateMap &state_map;
+ const bke::PersistentDataHandleMap &handle_map;
+ const DependencyAnimations &dependency_animations;
+};
+
+class ParticleAllocators {
+ private:
+ Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators_;
+
+ public:
+ ParticleAllocators(Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators)
+ : allocators_(allocators)
+ {
+ }
+
+ ParticleAllocator *try_get_allocator(StringRef particle_simulation_name)
+ {
+ auto *ptr = allocators_.lookup_ptr_as(particle_simulation_name);
+ if (ptr != nullptr) {
+ return ptr->get();
+ }
+ else {
+ return nullptr;
+ }
+ }
+};
+
+struct ParticleChunkIntegrationContext {
+ MutableSpan<float3> position_diffs;
+ MutableSpan<float3> velocity_diffs;
+ MutableSpan<float> durations;
+ float end_time;
+};
+
+struct ParticleChunkContext {
+ ParticleSimulationState &state;
+ IndexMask index_mask;
+ MutableAttributesRef attributes;
+ ParticleChunkIntegrationContext *integration = nullptr;
+
+ void update_diffs_after_velocity_change()
+ {
+ if (integration == nullptr) {
+ return;
+ }
+
+ Span<float> remaining_durations = integration->durations;
+ MutableSpan<float3> position_diffs = integration->position_diffs;
+ Span<float3> velocities = attributes.get<float3>("Velocity");
+
+ for (int i : index_mask) {
+ const float duration = remaining_durations[i];
+ /* This is certainly not a perfect way to "re-integrate" the velocity, but it should be good
+ * enough for most use cases. Changing the velocity in an instant is not physically correct
+ * anyway. */
+ position_diffs[i] = velocities[i] * duration;
+ }
+ }
+};
+
+struct ParticleEmitterContext {
+ SimulationSolveContext &solve_context;
+ ParticleAllocators &particle_allocators;
+ TimeInterval emit_interval;
+
+ template<typename StateType> StateType *lookup_state(StringRef name)
+ {
+ return solve_context.state_map.lookup<StateType>(name);
+ }
+
+ ParticleAllocator *try_get_particle_allocator(StringRef particle_simulation_name)
+ {
+ return particle_allocators.try_get_allocator(particle_simulation_name);
+ }
+};
+
+struct ParticleForceContext {
+ SimulationSolveContext &solve_context;
+ ParticleChunkContext &particles;
+ MutableSpan<float3> force_dst;
+};
+
+struct ParticleActionContext {
+ SimulationSolveContext &solve_context;
+ ParticleChunkContext &particles;
+};
+
+struct ParticleEventFilterContext {
+ SimulationSolveContext &solve_context;
+ ParticleChunkContext &particles;
+ MutableSpan<float> factor_dst;
+};
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_update.cc b/source/blender/simulation/intern/simulation_update.cc
new file mode 100644
index 00000000000..32b582977d0
--- /dev/null
+++ b/source/blender/simulation/intern/simulation_update.cc
@@ -0,0 +1,356 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "SIM_simulation_update.hh"
+
+#include "BKE_customdata.h"
+#include "BKE_lib_id.h"
+#include "BKE_object.h"
+#include "BKE_simulation.h"
+
+#include "DNA_modifier_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_simulation_types.h"
+
+#include "DEG_depsgraph_query.h"
+
+#include "BLI_array.hh"
+#include "BLI_float3.hh"
+#include "BLI_listbase.h"
+#include "BLI_map.hh"
+#include "BLI_rand.h"
+#include "BLI_set.hh"
+#include "BLI_vector.hh"
+
+#include "NOD_node_tree_dependencies.hh"
+
+#include "particle_function.hh"
+#include "simulation_collect_influences.hh"
+#include "simulation_solver.hh"
+
+namespace blender::sim {
+
+static void copy_states_to_cow(const Simulation *simulation_orig, Simulation *simulation_cow)
+{
+ BKE_simulation_state_remove_all(simulation_cow);
+ simulation_cow->current_frame = simulation_orig->current_frame;
+
+ LISTBASE_FOREACH (const SimulationState *, state_orig, &simulation_orig->states) {
+ SimulationState *state_cow = BKE_simulation_state_add(
+ simulation_cow, state_orig->type, state_orig->name);
+ BKE_simulation_state_copy_data(state_orig, state_cow);
+ }
+}
+
+static void remove_unused_states(Simulation *simulation, const RequiredStates &required_states)
+{
+ LISTBASE_FOREACH_MUTABLE (SimulationState *, state, &simulation->states) {
+ if (!required_states.is_required(state->name, state->type)) {
+ BKE_simulation_state_remove(simulation, state);
+ }
+ }
+}
+
+static void add_missing_states(Simulation *simulation, const RequiredStates &required_states)
+{
+ for (auto &&item : required_states.states().items()) {
+ const char *name = item.key.c_str();
+ const char *type = item.value;
+
+ SimulationState *state = BKE_simulation_state_try_find_by_name_and_type(
+ simulation, name, type);
+
+ if (state == nullptr) {
+ BKE_simulation_state_add(simulation, type, name);
+ }
+ }
+}
+
+static void reinitialize_empty_simulation_states(Simulation *simulation,
+ const RequiredStates &required_states)
+{
+ remove_unused_states(simulation, required_states);
+ BKE_simulation_state_reset_all(simulation);
+ add_missing_states(simulation, required_states);
+}
+
+static void update_simulation_state_list(Simulation *simulation,
+ const RequiredStates &required_states)
+{
+ remove_unused_states(simulation, required_states);
+ add_missing_states(simulation, required_states);
+}
+
+class SampledDependencyAnimations : public DependencyAnimations {
+ private:
+ TimeInterval simulation_time_interval_;
+ MultiValueMap<Object *, float4x4> object_transforms_cache_;
+
+ public:
+ SampledDependencyAnimations(TimeInterval simulation_time_interval)
+ : simulation_time_interval_(simulation_time_interval)
+ {
+ }
+
+ void add_object_transforms(Object &object, Span<float4x4> transforms)
+ {
+ object_transforms_cache_.add_multiple(&object, transforms);
+ }
+
+ bool is_object_transform_changing(Object &object) const
+ {
+ return object_transforms_cache_.lookup(&object).size() >= 2;
+ }
+
+ void get_object_transforms(Object &object,
+ Span<float> simulation_times,
+ MutableSpan<float4x4> r_transforms) const
+ {
+ assert_same_size(simulation_times, r_transforms);
+ Span<float4x4> cached_transforms = object_transforms_cache_.lookup(&object);
+ if (cached_transforms.size() == 0) {
+ r_transforms.fill(object.obmat);
+ return;
+ }
+ if (cached_transforms.size() == 1) {
+ r_transforms.fill(cached_transforms[0]);
+ return;
+ }
+
+ for (int i : simulation_times.index_range()) {
+ const float simulation_time = simulation_times[i];
+ if (simulation_time <= simulation_time_interval_.start()) {
+ r_transforms[i] = cached_transforms.first();
+ continue;
+ }
+ if (simulation_time >= simulation_time_interval_.stop()) {
+ r_transforms[i] = cached_transforms.last();
+ continue;
+ }
+ const float factor = simulation_time_interval_.factor_at_time(simulation_time);
+ BLI_assert(factor > 0.0f && factor < 1.0f);
+ const float scaled_factor = factor * (cached_transforms.size() - 1);
+ const int lower_sample = (int)scaled_factor;
+ const int upper_sample = lower_sample + 1;
+ const float mix_factor = scaled_factor - lower_sample;
+ r_transforms[i] = float4x4::interpolate(
+ cached_transforms[lower_sample], cached_transforms[upper_sample], mix_factor);
+ }
+ }
+};
+
+static void sample_object_transforms(Object &object,
+ Depsgraph &depsgraph,
+ Scene &scene,
+ TimeInterval scene_frame_interval,
+ MutableSpan<float4x4> r_transforms)
+{
+ if (r_transforms.size() == 0) {
+ return;
+ }
+ if (r_transforms.size() == 1) {
+ r_transforms[0] = object.obmat;
+ return;
+ }
+
+ Array<float> frames(r_transforms.size());
+ scene_frame_interval.compute_uniform_samples(frames);
+
+ for (int i : frames.index_range()) {
+ float frame = frames[i];
+ const int recursion_depth = 5;
+ BKE_object_modifier_update_subframe(
+ &depsgraph, &scene, &object, false, recursion_depth, frame, eModifierType_None);
+ r_transforms[i] = object.obmat;
+ }
+}
+
+template<typename T> static bool all_values_equal(Span<T> values)
+{
+ if (values.size() == 0) {
+ return true;
+ }
+ for (const T &value : values.drop_front(1)) {
+ if (value != values[0]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void prepare_dependency_animations(Depsgraph &depsgraph,
+ Scene &scene,
+ Simulation &simulation,
+ TimeInterval scene_frame_interval,
+ SampledDependencyAnimations &r_dependency_animations)
+{
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation.dependencies) {
+ ID *id_cow = DEG_get_evaluated_id(&depsgraph, dependency->id);
+ if (id_cow == nullptr) {
+ continue;
+ }
+ if (GS(id_cow->name) != ID_OB) {
+ continue;
+ }
+ Object &object_cow = *(Object *)id_cow;
+ constexpr int sample_count = 10;
+ Array<float4x4, sample_count> transforms(sample_count);
+ sample_object_transforms(object_cow, depsgraph, scene, scene_frame_interval, transforms);
+
+ /* If all samples are the same, only store one. */
+ Span<float4x4> transforms_to_use = (all_values_equal(transforms.as_span())) ?
+ transforms.as_span().take_front(1) :
+ transforms.as_span();
+
+ r_dependency_animations.add_object_transforms(object_cow, transforms_to_use);
+ }
+}
+
+void update_simulation_in_depsgraph(Depsgraph *depsgraph,
+ Scene *scene_cow,
+ Simulation *simulation_cow)
+{
+ int current_frame = scene_cow->r.cfra;
+ if (simulation_cow->current_frame == current_frame) {
+ return;
+ }
+
+ /* Below we modify the original state/cache. Only the active depsgraph is allowed to do that. */
+ if (!DEG_is_active(depsgraph)) {
+ return;
+ }
+
+ Simulation *simulation_orig = (Simulation *)DEG_get_original_id(&simulation_cow->id);
+
+ ResourceCollector resources;
+ SimulationInfluences influences;
+ RequiredStates required_states;
+
+ collect_simulation_influences(*simulation_cow, resources, influences, required_states);
+
+ bke::PersistentDataHandleMap handle_map;
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation_orig->dependencies) {
+ ID *id_cow = DEG_get_evaluated_id(depsgraph, dependency->id);
+ if (id_cow != nullptr) {
+ handle_map.add(dependency->handle, *id_cow);
+ }
+ }
+
+ if (current_frame == 1) {
+ reinitialize_empty_simulation_states(simulation_orig, required_states);
+
+ initialize_simulation_states(*simulation_orig, *depsgraph, influences, handle_map);
+ simulation_orig->current_frame = 1;
+
+ copy_states_to_cow(simulation_orig, simulation_cow);
+ }
+ else if (current_frame == simulation_orig->current_frame + 1) {
+ update_simulation_state_list(simulation_orig, required_states);
+
+ const float fps = scene_cow->r.frs_sec / scene_cow->r.frs_sec_base;
+ const float time_step = 1.0f / fps;
+ TimeInterval scene_frame_interval(current_frame - 1, 1);
+ TimeInterval simulation_time_interval(simulation_orig->current_simulation_time, time_step);
+ SampledDependencyAnimations dependency_animations{simulation_time_interval};
+ prepare_dependency_animations(
+ *depsgraph, *scene_cow, *simulation_orig, scene_frame_interval, dependency_animations);
+
+ solve_simulation_time_step(
+ *simulation_orig, *depsgraph, influences, handle_map, dependency_animations, time_step);
+ simulation_orig->current_frame = current_frame;
+
+ copy_states_to_cow(simulation_orig, simulation_cow);
+ }
+}
+
+/* Returns true when dependencies have changed. */
+bool update_simulation_dependencies(Simulation *simulation)
+{
+ nodes::NodeTreeDependencies dependencies = nodes::find_node_tree_dependencies(
+ *simulation->nodetree);
+
+ ListBase *dependency_list = &simulation->dependencies;
+
+ bool dependencies_changed = false;
+
+ Map<ID *, SimulationDependency *> dependency_by_id;
+ Map<SimulationDependency *, int> old_flag_by_dependency;
+ Set<int> used_handles;
+
+ /* Remove unused handle items and clear flags that are reinitialized later. */
+ LISTBASE_FOREACH_MUTABLE (SimulationDependency *, dependency, dependency_list) {
+ if (dependencies.depends_on(dependency->id)) {
+ dependency_by_id.add_new(dependency->id, dependency);
+ used_handles.add_new(dependency->handle);
+ old_flag_by_dependency.add_new(dependency, dependency->flag);
+ dependency->flag &= ~(SIM_DEPENDS_ON_TRANSFORM | SIM_DEPENDS_ON_GEOMETRY);
+ }
+ else {
+ if (dependency->id != nullptr) {
+ id_us_min(dependency->id);
+ }
+ BLI_remlink(dependency_list, dependency);
+ MEM_freeN(dependency);
+ dependencies_changed = true;
+ }
+ }
+
+ /* Add handle items for new id dependencies. */
+ int next_handle = 0;
+ for (ID *id : dependencies.id_dependencies()) {
+ dependency_by_id.lookup_or_add_cb(id, [&]() {
+ while (used_handles.contains(next_handle)) {
+ next_handle++;
+ }
+ used_handles.add_new(next_handle);
+
+ SimulationDependency *dependency = (SimulationDependency *)MEM_callocN(sizeof(*dependency),
+ AT);
+ id_us_plus(id);
+ dependency->id = id;
+ dependency->handle = next_handle;
+ BLI_addtail(dependency_list, dependency);
+
+ return dependency;
+ });
+ }
+
+ /* Set appropriate dependency flags. */
+ for (Object *object : dependencies.transform_dependencies()) {
+ SimulationDependency *dependency = dependency_by_id.lookup(&object->id);
+ dependency->flag |= SIM_DEPENDS_ON_TRANSFORM;
+ }
+ for (Object *object : dependencies.geometry_dependencies()) {
+ SimulationDependency *dependency = dependency_by_id.lookup(&object->id);
+ dependency->flag |= SIM_DEPENDS_ON_GEOMETRY;
+ }
+
+ if (!dependencies_changed) {
+ /* Check if any flags have changed. */
+ LISTBASE_FOREACH (SimulationDependency *, dependency, dependency_list) {
+ uint32_t old_flag = old_flag_by_dependency.lookup_default(dependency, 0);
+ uint32_t new_flag = dependency->flag;
+ if (old_flag != new_flag) {
+ dependencies_changed = true;
+ break;
+ }
+ }
+ }
+
+ return dependencies_changed;
+}
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/time_interval.hh b/source/blender/simulation/intern/time_interval.hh
new file mode 100644
index 00000000000..034628fa9be
--- /dev/null
+++ b/source/blender/simulation/intern/time_interval.hh
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "BLI_utildefines.h"
+
+namespace blender::sim {
+
+/**
+ * The start time is exclusive and the end time is inclusive. If the duration is zero, the interval
+ * describes a single point in time.
+ */
+class TimeInterval {
+ private:
+ float start_;
+ float duration_;
+
+ public:
+ TimeInterval(float start, float duration) : start_(start), duration_(duration)
+ {
+ BLI_assert(duration_ >= 0.0f);
+ }
+
+ float start() const
+ {
+ return start_;
+ }
+
+ float stop() const
+ {
+ return start_ + duration_;
+ }
+
+ float duration() const
+ {
+ return duration_;
+ }
+
+ float time_at_factor(float factor) const
+ {
+ return start_ + factor * duration_;
+ }
+
+ float factor_at_time(float time) const
+ {
+ BLI_assert(duration_ > 0.0f);
+ return (time - start_) / duration_;
+ }
+
+ float safe_factor_at_time(float time) const
+ {
+ if (duration_ > 0.0f) {
+ return this->factor_at_time(time);
+ }
+ return 0.0f;
+ }
+
+ void compute_uniform_samples(MutableSpan<float> r_samples) const
+ {
+ int64_t amount = r_samples.size();
+ if (amount == 0) {
+ return;
+ }
+ if (amount == 1) {
+ r_samples[0] = this->time_at_factor(0.5f);
+ return;
+ }
+
+ const float step = duration_ / (float)(amount - 1);
+ for (int64_t i : r_samples.index_range()) {
+ r_samples[i] = start_ + i * step;
+ }
+ }
+};
+
+} // namespace blender::sim
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 482589e2ccb..07746af4b60 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -16,8 +16,7 @@
* The Original Code is Copyright (C) 2007 Blender Foundation.
* All rights reserved.
*/
-#ifndef __WM_API_H__
-#define __WM_API_H__
+#pragma once
/** \file
* \ingroup wm
@@ -99,7 +98,7 @@ void WM_main(struct bContext *C) ATTR_NORETURN;
void WM_init_splash(struct bContext *C);
-void WM_init_opengl(struct Main *bmain);
+void WM_init_opengl(void);
void WM_check(struct bContext *C);
void WM_reinit_gizmomap_all(struct Main *bmain);
@@ -744,8 +743,13 @@ void *WM_jobs_customdata_get(struct wmJob *);
void WM_jobs_customdata_set(struct wmJob *, void *customdata, void (*free)(void *));
void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note, unsigned int endnote);
void WM_jobs_delay_start(struct wmJob *, double delay_time);
+
+typedef void (*wm_jobs_start_callback)(void *custom_data,
+ short *stop,
+ short *do_update,
+ float *progress);
void WM_jobs_callbacks(struct wmJob *,
- void (*startjob)(void *, short *, short *, float *),
+ wm_jobs_start_callback startjob,
void (*initjob)(void *),
void (*update)(void *),
void (*endjob)(void *));
@@ -899,5 +903,3 @@ bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr,
#ifdef __cplusplus
}
#endif
-
-#endif /* __WM_API_H__ */
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h
index 53a3fd5ebda..15be21bdbc4 100644
--- a/source/blender/windowmanager/WM_keymap.h
+++ b/source/blender/windowmanager/WM_keymap.h
@@ -17,8 +17,7 @@
* All rights reserved.
*/
-#ifndef __WM_KEYMAP_H__
-#define __WM_KEYMAP_H__
+#pragma once
/** \file
* \ingroup wm
@@ -194,5 +193,3 @@ const char *WM_bool_as_string(bool test);
#ifdef __cplusplus
}
#endif
-
-#endif /* __WM_KEYMAP_H__ */
diff --git a/source/blender/windowmanager/WM_message.h b/source/blender/windowmanager/WM_message.h
index 1527d514e9b..25d5bae392b 100644
--- a/source/blender/windowmanager/WM_message.h
+++ b/source/blender/windowmanager/WM_message.h
@@ -18,9 +18,6 @@
* \ingroup wm
*/
-#ifndef __WM_MESSAGE_H__
-#define __WM_MESSAGE_H__
+#pragma once
#include "message_bus/wm_message_bus.h"
-
-#endif /* __WM_MESSAGE_H__ */
diff --git a/source/blender/windowmanager/WM_toolsystem.h b/source/blender/windowmanager/WM_toolsystem.h
index 163f37be974..13d1666dc95 100644
--- a/source/blender/windowmanager/WM_toolsystem.h
+++ b/source/blender/windowmanager/WM_toolsystem.h
@@ -13,8 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __WM_TOOLSYSTEM_H__
-#define __WM_TOOLSYSTEM_H__
+#pragma once
/** \file
* \ingroup wm
@@ -140,5 +139,3 @@ void WM_toolsystem_refresh_screen_all(struct Main *bmain);
#ifdef __cplusplus
}
#endif
-
-#endif /* __WM_TOOLSYSTEM_API_H__ */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 4acce793707..efe600a846a 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -106,8 +106,7 @@
* \endcode
*/
-#ifndef __WM_TYPES_H__
-#define __WM_TYPES_H__
+#pragma once
struct ID;
struct ImBuf;
@@ -361,6 +360,7 @@ typedef struct wmNotifier {
#define ND_LOD (30 << 16)
#define ND_DRAW_RENDER_VIEWPORT \
(31 << 16) /* for camera & sequencer viewport update, also /w NC_SCENE */
+#define ND_SHADERFX (32 << 16)
/* NC_MATERIAL Material */
#define ND_SHADING (30 << 16)
@@ -927,5 +927,3 @@ extern struct CLG_LogRef *WM_LOG_MSGBUS_SUB;
#ifdef __cplusplus
}
#endif
-
-#endif /* __WM_TYPES_H__ */
diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_api.h b/source/blender/windowmanager/gizmo/WM_gizmo_api.h
index 07a3f0445bb..a4412ecce5c 100644
--- a/source/blender/windowmanager/gizmo/WM_gizmo_api.h
+++ b/source/blender/windowmanager/gizmo/WM_gizmo_api.h
@@ -26,8 +26,7 @@
* Only included in WM_api.h
*/
-#ifndef __WM_GIZMO_API_H__
-#define __WM_GIZMO_API_H__
+#pragma once
struct ARegion;
struct GHashIterator;
@@ -52,6 +51,10 @@ struct wmWindowManager;
#include "wm_gizmo_fn.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* -------------------------------------------------------------------- */
/* wmGizmo */
@@ -396,4 +399,6 @@ void WM_gizmo_group_tag_remove(struct wmGizmoGroup *gzgroup);
bool WM_gizmo_group_type_poll(const struct bContext *C, const struct wmGizmoGroupType *gzgt);
void WM_gizmo_group_refresh(const struct bContext *C, struct wmGizmoGroup *gzgroup);
-#endif /* __WM_GIZMO_API_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
index 3863e3bd797..bddf54b846f 100644
--- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h
+++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
@@ -26,8 +26,7 @@
* Only included in WM_types.h and lower level files.
*/
-#ifndef __WM_GIZMO_TYPES_H__
-#define __WM_GIZMO_TYPES_H__
+#pragma once
#include "BLI_compiler_attrs.h"
@@ -40,6 +39,10 @@ struct wmKeyConfig;
#include "DNA_listBase.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* -------------------------------------------------------------------- */
/* Enum Typedef's */
@@ -506,4 +509,6 @@ typedef enum eWM_GizmoFlagMapDrawStep {
} eWM_GizmoFlagMapDrawStep;
#define WM_GIZMOMAP_DRAWSTEP_MAX 2
-#endif /* __WM_GIZMO_TYPES_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c
index e687af15982..87cb4d5f584 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c
@@ -29,7 +29,6 @@
#include "BKE_context.h"
#include "GPU_batch.h"
-#include "GPU_glew.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -453,9 +452,7 @@ bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz)
wm_gizmomap_highlight_set(gzmap, C, gz, gz->highlight_part);
return true;
}
- else {
- return false;
- }
+ return false;
}
/**
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
index 67f30f0d7ee..b64d544962d 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
@@ -166,12 +166,10 @@ int WM_gizmo_cmp_temp_fl(const void *gz_a_ptr, const void *gz_b_ptr)
if (gz_a->temp.f < gz_b->temp.f) {
return -1;
}
- else if (gz_a->temp.f > gz_b->temp.f) {
+ if (gz_a->temp.f > gz_b->temp.f) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr)
@@ -181,12 +179,10 @@ int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr)
if (gz_a->temp.f < gz_b->temp.f) {
return 1;
}
- else if (gz_a->temp.f > gz_b->temp.f) {
+ if (gz_a->temp.f > gz_b->temp.f) {
return -1;
}
- else {
- return 0;
- }
+ return 0;
}
static bool wm_gizmo_keymap_uses_event_modifier(wmWindowManager *wm,
@@ -396,10 +392,9 @@ static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
return OPERATOR_FINISHED;
}
- else {
- BLI_assert(0);
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
+
+ BLI_assert(0);
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
void GIZMOGROUP_OT_gizmo_select(wmOperatorType *ot)
@@ -476,9 +471,7 @@ static bool gizmo_tweak_start_and_finish(
}
return true;
}
- else {
- return false;
- }
+ return false;
}
static void gizmo_tweak_finish(bContext *C, wmOperator *op, const bool cancel, bool clear_modal)
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
index 00df6edef22..953722f28e9 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
@@ -18,8 +18,7 @@
* \ingroup wm
*/
-#ifndef __WM_GIZMO_INTERN_H__
-#define __WM_GIZMO_INTERN_H__
+#pragma once
struct BLI_Buffer;
struct wmGizmoMap;
@@ -142,5 +141,3 @@ bool wm_gizmomap_deselect_all(struct wmGizmoMap *gzmap);
void wm_gizmomap_select_array_shrink(struct wmGizmoMap *gzmap, int len_subtract);
void wm_gizmomap_select_array_push_back(struct wmGizmoMap *gzmap, wmGizmo *gz);
void wm_gizmomap_select_array_remove(struct wmGizmoMap *gzmap, wmGizmo *gz);
-
-#endif
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index 6ed6c485e89..cecd324ff28 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -38,7 +38,6 @@
#include "ED_select_utils.h"
#include "ED_view3d.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "GPU_select.h"
#include "GPU_state.h"
@@ -264,11 +263,10 @@ bool WM_gizmomap_minmax(const wmGizmoMap *gzmap,
}
return i != 0;
}
- else {
- bool ok = false;
- BLI_assert(!"TODO");
- return ok;
- }
+
+ bool ok = false;
+ BLI_assert(!"TODO");
+ return ok;
}
/**
@@ -548,7 +546,7 @@ static void gizmo_draw_select_3d_loop(const bContext *C,
/* pass */
}
else {
- glDepthMask(!is_depth_skip);
+ GPU_depth_mask(!is_depth_skip);
is_depth_skip_prev = is_depth_skip;
}
@@ -565,7 +563,7 @@ static void gizmo_draw_select_3d_loop(const bContext *C,
GPU_depth_test(false);
}
if (is_depth_skip_prev) {
- glDepthMask(true);
+ GPU_depth_mask(true);
}
}
@@ -582,7 +580,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos,
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
rcti rect;
/* Almost certainly overkill, but allow for many custom gizmos. */
- GLuint buffer[MAXPICKBUF];
+ uint buffer[MAXPICKBUF];
short hits;
BLI_rcti_init_pt_radius(&rect, co, hotspot);
@@ -625,7 +623,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos,
GPU_matrix_unproject_with_precalc(&unproj_precalc, co_screen, co_3d_origin);
- GLuint *buf_iter = buffer;
+ uint *buf_iter = buffer;
int hit_found = -1;
float dot_best = FLT_MAX;
@@ -648,10 +646,9 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos,
}
return hit_found;
}
- else {
- const GLuint *hit_near = GPU_select_buffer_near(buffer, hits);
- return hit_near ? hit_near[3] : -1;
- }
+
+ const uint *hit_near = GPU_select_buffer_near(buffer, hits);
+ return hit_near ? hit_near[3] : -1;
}
/**
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c
index 2dc03d1419c..b056ed40943 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c
@@ -70,9 +70,7 @@ wmGizmoProperty *WM_gizmo_target_property_find(wmGizmo *gz, const char *idname)
if (index != -1) {
return WM_gizmo_target_property_at_index(gz, index);
}
- else {
- return NULL;
- }
+ return NULL;
}
void WM_gizmo_target_property_def_rna_ptr(wmGizmo *gz,
@@ -195,9 +193,7 @@ float WM_gizmo_target_property_float_get(const wmGizmo *gz, wmGizmoProperty *gz_
if (gz_prop->index == -1) {
return RNA_property_float_get(&gz_prop->ptr, gz_prop->prop);
}
- else {
- return RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index);
- }
+ return RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index);
}
void WM_gizmo_target_property_float_set(bContext *C,
@@ -255,9 +251,7 @@ bool WM_gizmo_target_property_float_range_get(const wmGizmo *gz,
gz_prop->custom_func.range_get_fn(gz, gz_prop, range);
return true;
}
- else {
- return false;
- }
+ return false;
}
float step, precision;
diff --git a/source/blender/windowmanager/gizmo/wm_gizmo_fn.h b/source/blender/windowmanager/gizmo/wm_gizmo_fn.h
index 58b58fa01d0..418e848e35b 100644
--- a/source/blender/windowmanager/gizmo/wm_gizmo_fn.h
+++ b/source/blender/windowmanager/gizmo/wm_gizmo_fn.h
@@ -20,13 +20,16 @@
* Callback function definitions, needed for both Types & API headers.
*/
-#ifndef __WM_GIZMO_FN_H__
-#define __WM_GIZMO_FN_H__
+#pragma once
#include "BLI_compiler_attrs.h"
struct wmMsgBus;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* wmGizmoGroup */
typedef bool (*wmGizmoGroupFnPoll)(const struct bContext *,
struct wmGizmoGroupType *) ATTR_WARN_UNUSED_RESULT;
@@ -85,4 +88,6 @@ typedef struct wmGizmoPropertyFnParams {
void *user_data;
} wmGizmoPropertyFnParams;
-#endif /* __WM_GIZMO_FN_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h b/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h
index cc9ccc5f4bb..18b3f40aba6 100644
--- a/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h
+++ b/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h
@@ -28,14 +28,17 @@
* Only included in wm.h and lower level files.
*/
-#ifndef __WM_GIZMO_WMAPI_H__
-#define __WM_GIZMO_WMAPI_H__
+#pragma once
struct wmEventHandler_Gizmo;
struct wmEventHandler_Op;
struct wmGizmoMap;
struct wmOperatorType;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* -------------------------------------------------------------------- */
/* wmGizmo */
@@ -92,4 +95,6 @@ struct ListBase *wm_gizmomap_groups_get(wmGizmoMap *gzmap);
void wm_gizmomaptypes_free(void);
-#endif /* __WM_GIZMO_WMAPI_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 2112477e62a..43c08a2b980 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -293,7 +293,7 @@ void WM_keyconfig_init(bContext *C)
/* initialize only after python init is done, for keymaps that
* use python operators */
- if (CTX_py_init_get(C) && (wm->initialized & WM_KEYCONFIG_IS_INITIALIZED) == 0) {
+ if (CTX_py_init_get(C) && (wm->initialized & WM_KEYCONFIG_IS_INIT) == 0) {
/* create default key config, only initialize once,
* it's persistent across sessions */
if (!(wm->defaultconf->flag & KEYCONF_INIT_DEFAULT)) {
@@ -308,7 +308,7 @@ void WM_keyconfig_init(bContext *C)
WM_keyconfig_update_tag(NULL, NULL);
WM_keyconfig_update(wm);
- wm->initialized |= WM_KEYCONFIG_IS_INITIALIZED;
+ wm->initialized |= WM_KEYCONFIG_IS_INIT;
}
}
@@ -334,7 +334,7 @@ void WM_check(bContext *C)
if (!G.background) {
/* case: fileread */
- if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) {
+ if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) {
WM_keyconfig_init(C);
WM_autosave_init(wm);
}
@@ -345,9 +345,9 @@ 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(bmain, wm);
- wm->initialized |= WM_WINDOW_IS_INITIALIZED;
+ if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) {
+ ED_screens_init(bmain, wm);
+ wm->initialized |= WM_WINDOW_IS_INIT;
}
}
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index 2af68956923..08d6df340d0 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -319,15 +319,15 @@ bool wm_cursor_arrow_move(wmWindow *win, const wmEvent *event)
wm_cursor_warp_relative(win, 0, fac);
return 1;
}
- else if (event->type == EVT_DOWNARROWKEY) {
+ if (event->type == EVT_DOWNARROWKEY) {
wm_cursor_warp_relative(win, 0, -fac);
return 1;
}
- else if (event->type == EVT_LEFTARROWKEY) {
+ if (event->type == EVT_LEFTARROWKEY) {
wm_cursor_warp_relative(win, -fac, 0);
return 1;
}
- else if (event->type == EVT_RIGHTARROWKEY) {
+ if (event->type == EVT_RIGHTARROWKEY) {
wm_cursor_warp_relative(win, fac, 0);
return 1;
}
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index ad3fc7a1302..ec18a401fa4 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -39,7 +39,6 @@
#include "BKE_context.h"
#include "BKE_idtype.h"
-#include "GPU_glew.h"
#include "GPU_shader.h"
#include "GPU_state.h"
#include "GPU_viewport.h"
@@ -297,7 +296,7 @@ void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent)
}
return;
}
- else if (GS(drag_id->id->name) != GS(id->name)) {
+ if (GS(drag_id->id->name) != GS(id->name)) {
BLI_assert(!"All dragged IDs must have the same type");
return;
}
@@ -356,7 +355,7 @@ static const char *wm_drag_name(wmDrag *drag)
if (single) {
return id->name + 2;
}
- else if (id) {
+ if (id) {
return BKE_idtype_idcode_to_name_plural(GS(id->name));
}
break;
@@ -424,9 +423,8 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
y,
drag->imb->x,
drag->imb->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
drag->imb->rect,
drag->scale,
drag->scale,
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 2b679dfefde..fe4c98394a3 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -51,7 +51,7 @@
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "GPU_draw.h"
+#include "GPU_context.h"
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@@ -106,11 +106,11 @@ static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region)
if (pc->poll == NULL || pc->poll(C)) {
/* Prevent drawing outside region. */
- glEnable(GL_SCISSOR_TEST);
- glScissor(region->winrct.xmin,
- region->winrct.ymin,
- BLI_rcti_size_x(&region->winrct) + 1,
- BLI_rcti_size_y(&region->winrct) + 1);
+ GPU_scissor_test(true);
+ GPU_scissor(region->winrct.xmin,
+ region->winrct.ymin,
+ BLI_rcti_size_x(&region->winrct) + 1,
+ BLI_rcti_size_y(&region->winrct) + 1);
if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) {
int x = 0, y = 0;
@@ -121,7 +121,7 @@ static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region)
pc->draw(C, win->eventstate->x, win->eventstate->y, pc->customdata);
}
- glDisable(GL_SCISSOR_TEST);
+ GPU_scissor_test(false);
}
}
}
@@ -135,15 +135,8 @@ static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region)
static void wm_region_draw_overlay(bContext *C, ScrArea *area, ARegion *region)
{
- wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
- /* Don't draw overlay with locked interface. Drawing could access scene data that another thread
- * may be modifying. */
- if (wm->is_interface_locked) {
- return;
- }
-
wmViewport(&region->winrct);
UI_SetTheme(area->spacetype, region->regiontype);
region->type->draw_overlay(C, region);
@@ -214,7 +207,7 @@ static bool wm_draw_region_stereo_set(Main *bmain,
if (region->regiontype == RGN_TYPE_PREVIEW) {
return true;
}
- else if (region->regiontype == RGN_TYPE_WINDOW) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
return (sseq->draw_flag & SEQ_DRAW_BACKDROP) != 0;
}
}
@@ -403,14 +396,8 @@ static void wm_draw_offscreen_texture_parameters(GPUOffScreen *offscreen)
/* We don't support multisample textures here. */
BLI_assert(GPU_texture_target(texture) == GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
-
/* No mipmaps or filtering. */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
- /* GL_TEXTURE_BASE_LEVEL = 0 by default */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glBindTexture(GL_TEXTURE_2D, 0);
+ GPU_texture_mipmap_mode(texture, false, false);
}
static void wm_draw_region_buffer_create(ARegion *region, bool stereo, bool use_viewport)
@@ -473,8 +460,8 @@ static void wm_draw_region_bind(ARegion *region, int view)
/* For now scissor is expected by region drawing, we could disable it
* and do the enable/disable in the specific cases that setup scissor. */
- glEnable(GL_SCISSOR_TEST);
- glScissor(0, 0, region->winx, region->winy);
+ GPU_scissor_test(true);
+ GPU_scissor(0, 0, region->winx, region->winy);
}
region->draw_buffer->bound_view = view;
@@ -492,7 +479,7 @@ static void wm_draw_region_unbind(ARegion *region)
GPU_viewport_unbind(region->draw_buffer->viewport);
}
else {
- glDisable(GL_SCISSOR_TEST);
+ GPU_scissor_test(false);
GPU_offscreen_unbind(region->draw_buffer->offscreen, false);
}
}
@@ -533,9 +520,7 @@ GPUTexture *wm_draw_region_texture(ARegion *region, int view)
if (viewport) {
return GPU_viewport_color_texture(viewport, view);
}
- else {
- return GPU_offscreen_color_texture(region->draw_buffer->offscreen);
- }
+ return GPU_offscreen_color_texture(region->draw_buffer->offscreen);
}
void wm_draw_region_blend(ARegion *region, int view, bool blend)
@@ -554,24 +539,10 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend)
alpha = 1.0f;
}
- /* setup actual texture */
- GPUTexture *texture = wm_draw_region_texture(region, view);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
-
/* wmOrtho for the screen has this same offset */
const float halfx = GLA_PIXEL_OFS / (BLI_rcti_size_x(&region->winrct) + 1);
const float halfy = GLA_PIXEL_OFS / (BLI_rcti_size_y(&region->winrct) + 1);
- if (blend) {
- /* GL_ONE because regions drawn offscreen have premultiplied alpha. */
- GPU_blend(true);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
- GPU_shader_bind(shader);
-
rcti rect_geo = region->winrct;
rect_geo.xmax += 1;
rect_geo.ymax += 1;
@@ -598,26 +569,39 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend)
alpha = 1.0f;
}
- glUniform1i(GPU_shader_get_uniform(shader, "image"), 0);
- glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"),
- rect_tex.xmin,
- rect_tex.ymin,
- rect_tex.xmax,
- rect_tex.ymax);
- glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"),
- rect_geo.xmin,
- rect_geo.ymin,
- rect_geo.xmax,
- rect_geo.ymax);
- glUniform4f(
- GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
+ /* Not the same layout as rectf/recti. */
+ float rectt[4] = {rect_tex.xmin, rect_tex.ymin, rect_tex.xmax, rect_tex.ymax};
+ float rectg[4] = {rect_geo.xmin, rect_geo.ymin, rect_geo.xmax, rect_geo.ymax};
+
+ if (blend) {
+ /* GL_ONE because regions drawn offscreen have premultiplied alpha. */
+ GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+ }
+
+ /* setup actual texture */
+ GPUTexture *texture = wm_draw_region_texture(region, view);
+
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
+ GPU_shader_bind(shader);
+
+ int color_loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR);
+ int rect_tex_loc = GPU_shader_get_uniform(shader, "rect_icon");
+ int rect_geo_loc = GPU_shader_get_uniform(shader, "rect_geom");
+ int texture_bind_loc = GPU_shader_get_texture_binding(shader, "image");
+
+ GPU_texture_bind(texture, texture_bind_loc);
+
+ GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, rectt);
+ GPU_shader_uniform_vector(shader, rect_geo_loc, 4, 1, rectg);
+ GPU_shader_uniform_vector(shader, color_loc, 4, 1, (const float[4]){1, 1, 1, 1});
GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4);
- glBindTexture(GL_TEXTURE_2D, 0);
+ GPU_texture_unbind(texture);
if (blend) {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(false);
}
}
@@ -736,8 +720,8 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
wm_draw_region_buffer_create(region, false, false);
wm_draw_region_bind(region, 0);
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear_color(0, 0, 0, 0);
+ GPU_clear(GPU_COLOR_BIT);
ED_region_do_draw(C, region);
wm_draw_region_unbind(region);
@@ -759,8 +743,8 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
* Actually this is only a problem when resizing the window.
* If it becomes a problem we should clear only when window size changes. */
#if 0
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear_color(0, 0, 0, 0);
+ GPU_clear(GPU_COLOR_BIT);
#endif
/* Blit non-overlapping area regions. */
@@ -844,11 +828,13 @@ static void wm_draw_window(bContext *C, wmWindow *win)
}
else if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) {
/* For pageflip we simply draw to both back buffers. */
- glDrawBuffer(GL_BACK_LEFT);
+ GPU_backbuffer_bind(GPU_BACKBUFFER_LEFT);
wm_draw_window_onscreen(C, win, 0);
- glDrawBuffer(GL_BACK_RIGHT);
+
+ GPU_backbuffer_bind(GPU_BACKBUFFER_RIGHT);
wm_draw_window_onscreen(C, win, 1);
- glDrawBuffer(GL_BACK);
+
+ GPU_backbuffer_bind(GPU_BACKBUFFER);
}
else if (ELEM(win->stereo3d_format->display_mode, S3D_DISPLAY_ANAGLYPH, S3D_DISPLAY_INTERLACE)) {
/* For anaglyph and interlace, we draw individual regions with
@@ -874,8 +860,7 @@ static void wm_draw_window(bContext *C, wmWindow *win)
GPU_offscreen_unbind(offscreen, false);
/* Draw offscreen buffer to screen. */
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
+ GPU_texture_bind(texture, 0);
wmWindowViewport(win);
if (win->stereo3d_format->display_mode == S3D_DISPLAY_SIDEBYSIDE) {
@@ -885,7 +870,7 @@ static void wm_draw_window(bContext *C, wmWindow *win)
wm_stereo3d_draw_topbottom(win, view);
}
- glBindTexture(GL_TEXTURE_2D, 0);
+ GPU_texture_unbind(texture);
}
GPU_offscreen_free(offscreen);
@@ -1012,7 +997,8 @@ void wm_draw_update(bContext *C)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win;
- GPU_free_unused_buffers();
+ GPU_context_main_lock();
+ BKE_image_free_unused_gpu_textures();
for (win = wm->windows.first; win; win = win->next) {
#ifdef WIN32
@@ -1049,6 +1035,8 @@ void wm_draw_update(bContext *C)
/* Draw non-windows (surfaces) */
wm_surfaces_iter(C, wm_draw_surface);
+
+ GPU_context_main_unlock();
}
void wm_draw_region_clear(wmWindow *win, ARegion *UNUSED(region))
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 53d6df915d6..0941dd49d23 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -591,13 +591,13 @@ static int wm_handler_ui_call(bContext *C,
return WM_HANDLER_CONTINUE;
}
- /* UI is quite aggressive with swallowing events, like scrollwheel */
+ /* UI is quite aggressive with swallowing events, like scroll-wheel. */
/* I realize this is not extremely nice code... when UI gets keymaps it can be maybe smarter */
if (do_wheel_ui == false) {
if (is_wheel) {
return WM_HANDLER_CONTINUE;
}
- else if (wm_event_always_pass(event) == 0) {
+ if (wm_event_always_pass(event) == 0) {
do_wheel_ui = true;
}
}
@@ -608,7 +608,7 @@ static int wm_handler_ui_call(bContext *C,
return WM_UI_HANDLER_CONTINUE;
}
- /* we set context to where ui handler came from */
+ /* We set context to where UI handler came from. */
if (handler->context.area) {
CTX_wm_area_set(C, handler->context.area);
}
@@ -783,7 +783,7 @@ bool WM_operator_poll(bContext *C, wmOperatorType *ot)
if (ot->pyop_poll) {
return ot->pyop_poll(C, ot);
}
- else if (ot->poll) {
+ if (ot->poll) {
return ot->poll(C);
}
@@ -810,7 +810,7 @@ bool WM_operator_check_ui_empty(wmOperatorType *ot)
return true;
}
- /* Assume a ui callback will draw something. */
+ /* Assume a UI callback will draw something. */
if (ot->ui) {
return false;
}
@@ -1095,7 +1095,7 @@ bool WM_operator_repeat_check(const bContext *UNUSED(C), wmOperator *op)
if (op->type->exec != NULL) {
return true;
}
- else if (op->opm) {
+ if (op->opm) {
/* for macros, check all have exec() we can call */
wmOperatorTypeMacro *otmacro;
for (otmacro = op->opm->type->macro.first; otmacro; otmacro = otmacro->next) {
@@ -1816,10 +1816,10 @@ static bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi)
/* tablet events can occur on hover + keypress */
return false;
}
- else if ((kmitype == TABLET_STYLUS) && (wmtab->active != EVT_TABLET_STYLUS)) {
+ if ((kmitype == TABLET_STYLUS) && (wmtab->active != EVT_TABLET_STYLUS)) {
return false;
}
- else if ((kmitype == TABLET_ERASER) && (wmtab->active != EVT_TABLET_ERASER)) {
+ if ((kmitype == TABLET_ERASER) && (wmtab->active != EVT_TABLET_ERASER)) {
return false;
}
}
@@ -2434,13 +2434,11 @@ static int wm_handlers_do_keymap_with_keymap_handler(
}
break;
}
+ if (action & WM_HANDLER_HANDLED) {
+ CLOG_INFO(WM_LOG_HANDLERS, 2, "handled - and pass on! '%s'", kmi->idname);
+ }
else {
- if (action & WM_HANDLER_HANDLED) {
- CLOG_INFO(WM_LOG_HANDLERS, 2, "handled - and pass on! '%s'", kmi->idname);
- }
- else {
- CLOG_INFO(WM_LOG_HANDLERS, 2, "un-handled '%s'", kmi->idname);
- }
+ CLOG_INFO(WM_LOG_HANDLERS, 2, "un-handled '%s'", kmi->idname);
}
}
}
@@ -2492,16 +2490,14 @@ static int wm_handlers_do_keymap_with_gizmo_handler(
}
break;
}
- else {
- if (action & WM_HANDLER_HANDLED) {
- if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) {
- printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname);
- }
- }
- else {
- PRINT("%s: un-handled '%s'\n", __func__, kmi->idname);
+ if (action & WM_HANDLER_HANDLED) {
+ if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) {
+ printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname);
}
}
+ else {
+ PRINT("%s: un-handled '%s'\n", __func__, kmi->idname);
+ }
}
}
}
@@ -2707,7 +2703,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
handler_base = handler_base_next) {
handler_base_next = handler_base->next;
- /* during this loop, ui handlers for nested menus can tag multiple handlers free */
+ /* During this loop, UI handlers for nested menus can tag multiple handlers free. */
if (handler_base->flag & WM_HANDLER_DO_FREE) {
/* pass */
}
@@ -2829,7 +2825,7 @@ 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_base) !=
-1) { /* could be freed already by regular modal ops */
if (handler_base->flag & WM_HANDLER_DO_FREE) {
@@ -3126,13 +3122,9 @@ static bool wm_event_pie_filter(wmWindow *win, const wmEvent *event)
win->lock_pie_event = EVENT_NONE;
return false;
}
- else {
- return true;
- }
- }
- else {
- return false;
+ return true;
}
+ return false;
}
/**
@@ -3692,10 +3684,8 @@ wmKeyMap *WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm,
handler->keymap_tool = area->runtime.tool;
return km;
}
- else {
- printf(
- "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname);
- }
+ printf(
+ "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname);
}
}
return NULL;
@@ -3716,10 +3706,8 @@ wmKeyMap *WM_event_get_keymap_from_toolsystem(wmWindowManager *wm, wmEventHandle
handler->keymap_tool = area->runtime.tool;
return km;
}
- else {
- printf(
- "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname);
- }
+ printf(
+ "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname);
}
}
return NULL;
@@ -3775,12 +3763,10 @@ static bool event_or_prev_in_rect(const wmEvent *event, const rcti *rect)
if (BLI_rcti_isect_pt(rect, event->x, event->y)) {
return true;
}
- else if (event->type == MOUSEMOVE && BLI_rcti_isect_pt(rect, event->prevx, event->prevy)) {
+ if (event->type == MOUSEMOVE && BLI_rcti_isect_pt(rect, event->prevx, event->prevy)) {
return true;
}
- else {
- return false;
- }
+ return false;
}
static bool handler_region_v2d_mask_test(const ARegion *region, const wmEvent *event)
@@ -3966,138 +3952,137 @@ static int convert_key(GHOST_TKey key)
if (key >= GHOST_kKeyA && key <= GHOST_kKeyZ) {
return (EVT_AKEY + ((int)key - GHOST_kKeyA));
}
- else if (key >= GHOST_kKey0 && key <= GHOST_kKey9) {
+ if (key >= GHOST_kKey0 && key <= GHOST_kKey9) {
return (EVT_ZEROKEY + ((int)key - GHOST_kKey0));
}
- else if (key >= GHOST_kKeyNumpad0 && key <= GHOST_kKeyNumpad9) {
+ if (key >= GHOST_kKeyNumpad0 && key <= GHOST_kKeyNumpad9) {
return (EVT_PAD0 + ((int)key - GHOST_kKeyNumpad0));
}
- else if (key >= GHOST_kKeyF1 && key <= GHOST_kKeyF24) {
+ if (key >= GHOST_kKeyF1 && key <= GHOST_kKeyF24) {
return (EVT_F1KEY + ((int)key - GHOST_kKeyF1));
}
- else {
- switch (key) {
- case GHOST_kKeyBackSpace:
- return EVT_BACKSPACEKEY;
- case GHOST_kKeyTab:
- return EVT_TABKEY;
- case GHOST_kKeyLinefeed:
- return EVT_LINEFEEDKEY;
- case GHOST_kKeyClear:
- return 0;
- case GHOST_kKeyEnter:
- return EVT_RETKEY;
-
- case GHOST_kKeyEsc:
- return EVT_ESCKEY;
- case GHOST_kKeySpace:
- return EVT_SPACEKEY;
- case GHOST_kKeyQuote:
- return EVT_QUOTEKEY;
- case GHOST_kKeyComma:
- return EVT_COMMAKEY;
- case GHOST_kKeyMinus:
- return EVT_MINUSKEY;
- case GHOST_kKeyPlus:
- return EVT_PLUSKEY;
- case GHOST_kKeyPeriod:
- return EVT_PERIODKEY;
- case GHOST_kKeySlash:
- return EVT_SLASHKEY;
-
- case GHOST_kKeySemicolon:
- return EVT_SEMICOLONKEY;
- case GHOST_kKeyEqual:
- return EVT_EQUALKEY;
-
- case GHOST_kKeyLeftBracket:
- return EVT_LEFTBRACKETKEY;
- case GHOST_kKeyRightBracket:
- return EVT_RIGHTBRACKETKEY;
- case GHOST_kKeyBackslash:
- return EVT_BACKSLASHKEY;
- case GHOST_kKeyAccentGrave:
- return EVT_ACCENTGRAVEKEY;
-
- case GHOST_kKeyLeftShift:
- return EVT_LEFTSHIFTKEY;
- case GHOST_kKeyRightShift:
- return EVT_RIGHTSHIFTKEY;
- case GHOST_kKeyLeftControl:
- return EVT_LEFTCTRLKEY;
- case GHOST_kKeyRightControl:
- return EVT_RIGHTCTRLKEY;
- case GHOST_kKeyOS:
- return EVT_OSKEY;
- case GHOST_kKeyLeftAlt:
- return EVT_LEFTALTKEY;
- case GHOST_kKeyRightAlt:
- return EVT_RIGHTALTKEY;
- case GHOST_kKeyApp:
- return EVT_APPKEY;
-
- case GHOST_kKeyCapsLock:
- return EVT_CAPSLOCKKEY;
- case GHOST_kKeyNumLock:
- return 0;
- case GHOST_kKeyScrollLock:
- return 0;
-
- case GHOST_kKeyLeftArrow:
- return EVT_LEFTARROWKEY;
- case GHOST_kKeyRightArrow:
- return EVT_RIGHTARROWKEY;
- case GHOST_kKeyUpArrow:
- return EVT_UPARROWKEY;
- case GHOST_kKeyDownArrow:
- return EVT_DOWNARROWKEY;
-
- case GHOST_kKeyPrintScreen:
- return 0;
- case GHOST_kKeyPause:
- return EVT_PAUSEKEY;
-
- case GHOST_kKeyInsert:
- return EVT_INSERTKEY;
- case GHOST_kKeyDelete:
- return EVT_DELKEY;
- case GHOST_kKeyHome:
- return EVT_HOMEKEY;
- case GHOST_kKeyEnd:
- return EVT_ENDKEY;
- case GHOST_kKeyUpPage:
- return EVT_PAGEUPKEY;
- case GHOST_kKeyDownPage:
- return EVT_PAGEDOWNKEY;
-
- case GHOST_kKeyNumpadPeriod:
- return EVT_PADPERIOD;
- case GHOST_kKeyNumpadEnter:
- return EVT_PADENTER;
- case GHOST_kKeyNumpadPlus:
- return EVT_PADPLUSKEY;
- case GHOST_kKeyNumpadMinus:
- return EVT_PADMINUS;
- case GHOST_kKeyNumpadAsterisk:
- return EVT_PADASTERKEY;
- case GHOST_kKeyNumpadSlash:
- return EVT_PADSLASHKEY;
-
- case GHOST_kKeyGrLess:
- return EVT_GRLESSKEY;
-
- case GHOST_kKeyMediaPlay:
- return EVT_MEDIAPLAY;
- case GHOST_kKeyMediaStop:
- return EVT_MEDIASTOP;
- case GHOST_kKeyMediaFirst:
- return EVT_MEDIAFIRST;
- case GHOST_kKeyMediaLast:
- return EVT_MEDIALAST;
-
- default:
- return EVT_UNKNOWNKEY; /* GHOST_kKeyUnknown */
- }
+
+ switch (key) {
+ case GHOST_kKeyBackSpace:
+ return EVT_BACKSPACEKEY;
+ case GHOST_kKeyTab:
+ return EVT_TABKEY;
+ case GHOST_kKeyLinefeed:
+ return EVT_LINEFEEDKEY;
+ case GHOST_kKeyClear:
+ return 0;
+ case GHOST_kKeyEnter:
+ return EVT_RETKEY;
+
+ case GHOST_kKeyEsc:
+ return EVT_ESCKEY;
+ case GHOST_kKeySpace:
+ return EVT_SPACEKEY;
+ case GHOST_kKeyQuote:
+ return EVT_QUOTEKEY;
+ case GHOST_kKeyComma:
+ return EVT_COMMAKEY;
+ case GHOST_kKeyMinus:
+ return EVT_MINUSKEY;
+ case GHOST_kKeyPlus:
+ return EVT_PLUSKEY;
+ case GHOST_kKeyPeriod:
+ return EVT_PERIODKEY;
+ case GHOST_kKeySlash:
+ return EVT_SLASHKEY;
+
+ case GHOST_kKeySemicolon:
+ return EVT_SEMICOLONKEY;
+ case GHOST_kKeyEqual:
+ return EVT_EQUALKEY;
+
+ case GHOST_kKeyLeftBracket:
+ return EVT_LEFTBRACKETKEY;
+ case GHOST_kKeyRightBracket:
+ return EVT_RIGHTBRACKETKEY;
+ case GHOST_kKeyBackslash:
+ return EVT_BACKSLASHKEY;
+ case GHOST_kKeyAccentGrave:
+ return EVT_ACCENTGRAVEKEY;
+
+ case GHOST_kKeyLeftShift:
+ return EVT_LEFTSHIFTKEY;
+ case GHOST_kKeyRightShift:
+ return EVT_RIGHTSHIFTKEY;
+ case GHOST_kKeyLeftControl:
+ return EVT_LEFTCTRLKEY;
+ case GHOST_kKeyRightControl:
+ return EVT_RIGHTCTRLKEY;
+ case GHOST_kKeyOS:
+ return EVT_OSKEY;
+ case GHOST_kKeyLeftAlt:
+ return EVT_LEFTALTKEY;
+ case GHOST_kKeyRightAlt:
+ return EVT_RIGHTALTKEY;
+ case GHOST_kKeyApp:
+ return EVT_APPKEY;
+
+ case GHOST_kKeyCapsLock:
+ return EVT_CAPSLOCKKEY;
+ case GHOST_kKeyNumLock:
+ return 0;
+ case GHOST_kKeyScrollLock:
+ return 0;
+
+ case GHOST_kKeyLeftArrow:
+ return EVT_LEFTARROWKEY;
+ case GHOST_kKeyRightArrow:
+ return EVT_RIGHTARROWKEY;
+ case GHOST_kKeyUpArrow:
+ return EVT_UPARROWKEY;
+ case GHOST_kKeyDownArrow:
+ return EVT_DOWNARROWKEY;
+
+ case GHOST_kKeyPrintScreen:
+ return 0;
+ case GHOST_kKeyPause:
+ return EVT_PAUSEKEY;
+
+ case GHOST_kKeyInsert:
+ return EVT_INSERTKEY;
+ case GHOST_kKeyDelete:
+ return EVT_DELKEY;
+ case GHOST_kKeyHome:
+ return EVT_HOMEKEY;
+ case GHOST_kKeyEnd:
+ return EVT_ENDKEY;
+ case GHOST_kKeyUpPage:
+ return EVT_PAGEUPKEY;
+ case GHOST_kKeyDownPage:
+ return EVT_PAGEDOWNKEY;
+
+ case GHOST_kKeyNumpadPeriod:
+ return EVT_PADPERIOD;
+ case GHOST_kKeyNumpadEnter:
+ return EVT_PADENTER;
+ case GHOST_kKeyNumpadPlus:
+ return EVT_PADPLUSKEY;
+ case GHOST_kKeyNumpadMinus:
+ return EVT_PADMINUS;
+ case GHOST_kKeyNumpadAsterisk:
+ return EVT_PADASTERKEY;
+ case GHOST_kKeyNumpadSlash:
+ return EVT_PADSLASHKEY;
+
+ case GHOST_kKeyGrLess:
+ return EVT_GRLESSKEY;
+
+ case GHOST_kKeyMediaPlay:
+ return EVT_MEDIAPLAY;
+ case GHOST_kKeyMediaStop:
+ return EVT_MEDIASTOP;
+ case GHOST_kKeyMediaFirst:
+ return EVT_MEDIAFIRST;
+ case GHOST_kKeyMediaLast:
+ return EVT_MEDIALAST;
+
+ default:
+ return EVT_UNKNOWNKEY; /* GHOST_kKeyUnknown */
}
}
@@ -4834,7 +4819,7 @@ wmKeyMapItem *WM_event_match_keymap_item_from_handlers(bContext *C,
const wmEvent *event)
{
LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
- /* during this loop, ui handlers for nested menus can tag multiple handlers free */
+ /* During this loop, UI handlers for nested menus can tag multiple handlers free. */
if (handler_base->flag & WM_HANDLER_DO_FREE) {
/* pass */
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index d5a240a358e..ef4f2b4a62a 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -258,7 +258,7 @@ static void wm_window_match_keep_current_wm(const bContext *C,
bScreen *screen = NULL;
/* match oldwm to new dbase, only old files */
- wm->initialized &= ~WM_WINDOW_IS_INITIALIZED;
+ wm->initialized &= ~WM_WINDOW_IS_INIT;
/* when loading without UI, no matching needed */
if (load_ui && (screen = CTX_wm_screen(C))) {
@@ -1027,13 +1027,6 @@ void wm_homefile_read(bContext *C,
},
NULL);
}
- if (BLI_listbase_is_empty(&U.themes)) {
- if (G.debug & G_DEBUG) {
- printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n",
- filepath_startup);
- }
- success = false;
- }
if (success) {
if (update_defaults) {
if (use_data) {
@@ -1411,10 +1404,8 @@ bool write_crash_blend(void)
printf("written: %s\n", path);
return 1;
}
- else {
- printf("failed: %s\n", path);
- return 0;
- }
+ printf("failed: %s\n", path);
+ return 0;
}
/**
@@ -2098,9 +2089,7 @@ static int wm_homefile_read_invoke(bContext *C, wmOperator *op, const wmEvent *U
wm_close_file_dialog(C, callback);
return OPERATOR_INTERFACE;
}
- else {
- return wm_homefile_read_exec(C, op);
- }
+ return wm_homefile_read_exec(C, op);
}
static void read_homefile_props(wmOperatorType *ot)
@@ -2262,9 +2251,7 @@ static int wm_open_mainfile__discard_changes(bContext *C, wmOperator *op)
wm_close_file_dialog(C, callback);
return OPERATOR_INTERFACE;
}
- else {
- return wm_open_mainfile_dispatch(C, op);
- }
+ return wm_open_mainfile_dispatch(C, op);
}
static int wm_open_mainfile__select_file_path(bContext *C, wmOperator *op)
@@ -2335,9 +2322,7 @@ static int wm_open_mainfile__open(bContext *C, wmOperator *op)
ED_view3d_local_collections_reset(C, (G.fileflags & G_FILE_NO_UI) != 0);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static OperatorDispatchTarget wm_open_mainfile_dispatch_targets[] = {
@@ -2482,9 +2467,7 @@ static int wm_revert_mainfile_exec(bContext *C, wmOperator *op)
if (success) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static bool wm_revert_mainfile_poll(bContext *UNUSED(C))
@@ -2579,9 +2562,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
if (success) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index c8574a5a7fb..6ccc5d79962 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -34,6 +34,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_ID.h"
+#include "DNA_key_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
@@ -50,8 +51,10 @@
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_key.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_override.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -354,11 +357,11 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_ERROR, "'%s': not a library", path);
return OPERATOR_CANCELLED;
}
- else if (!group) {
+ if (!group) {
BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path);
return OPERATOR_CANCELLED;
}
- else if (BLI_path_cmp(BKE_main_blendfile_path(bmain), libname) == 0) {
+ 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;
}
@@ -694,6 +697,92 @@ static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UN
return OPERATOR_CANCELLED;
}
+static void lib_relocate_do_remap(Main *bmain,
+ ID *old_id,
+ ID *new_id,
+ ReportList *reports,
+ const bool do_reload,
+ const short remap_flags)
+{
+ BLI_assert(old_id);
+ if (do_reload) {
+ /* Since we asked for placeholders in case of missing IDs,
+ * we expect to always get a valid one. */
+ BLI_assert(new_id);
+ }
+ if (new_id) {
+#ifdef PRINT_DEBUG
+ printf("before remap of %s, old_id users: %d, new_id users: %d\n",
+ old_id->name,
+ old_id->us,
+ new_id->us);
+#endif
+ BKE_libblock_remap_locked(bmain, old_id, new_id, remap_flags);
+
+ if (old_id->flag & LIB_FAKEUSER) {
+ id_fake_user_clear(old_id);
+ id_fake_user_set(new_id);
+ }
+
+#ifdef PRINT_DEBUG
+ printf("after remap of %s, old_id users: %d, new_id users: %d\n",
+ old_id->name,
+ old_id->us,
+ new_id->us);
+#endif
+
+ /* In some cases, new_id might become direct link, remove parent of library in this case. */
+ if (new_id->lib->parent && (new_id->tag & LIB_TAG_INDIRECT) == 0) {
+ if (do_reload) {
+ BLI_assert(0); /* Should not happen in 'pure' reload case... */
+ }
+ new_id->lib->parent = NULL;
+ }
+ }
+
+ if (old_id->us > 0 && new_id && old_id->lib == new_id->lib) {
+ /* Note that this *should* not happen - but better be safe than sorry in this area,
+ * at least until we are 100% sure this cannot ever happen.
+ * Also, we can safely assume names were unique so far,
+ * so just replacing '.' by '~' should work,
+ * but this does not totally rules out the possibility of name collision. */
+ size_t len = strlen(old_id->name);
+ size_t dot_pos;
+ bool has_num = false;
+
+ for (dot_pos = len; dot_pos--;) {
+ char c = old_id->name[dot_pos];
+ if (c == '.') {
+ break;
+ }
+ if (c < '0' || c > '9') {
+ has_num = false;
+ break;
+ }
+ has_num = true;
+ }
+
+ if (has_num) {
+ old_id->name[dot_pos] = '~';
+ }
+ else {
+ len = MIN2(len, MAX_ID_NAME - 7);
+ BLI_strncpy(&old_id->name[len], "~000", 7);
+ }
+
+ id_sort_by_name(which_libbase(bmain, GS(old_id->name)), old_id, NULL);
+
+ BKE_reportf(
+ reports,
+ RPT_WARNING,
+ "Lib Reload: Replacing all references to old data-block '%s' by reloaded one failed, "
+ "old one (%d remaining users) had to be kept and was renamed to '%s'",
+ new_id->name,
+ old_id->us,
+ old_id->name);
+ }
+}
+
static void lib_relocate_do(Main *bmain,
Library *library,
WMLinkAppendData *lapp_data,
@@ -725,6 +814,12 @@ static void lib_relocate_do(Main *bmain,
/* We remove it from current Main, and add it to items to link... */
/* Note that non-linkable IDs (like e.g. shapekeys) are also explicitly linked here... */
BLI_remlink(lbarray[lba_idx], id);
+ /* Usual special code for ShapeKeys snowflakes... */
+ Key *old_key = BKE_key_from_id(id);
+ if (old_key != NULL) {
+ BLI_remlink(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
+ }
+
item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id);
BLI_bitmap_set_all(item->libraries, true, lapp_data->num_libraries);
@@ -757,6 +852,12 @@ static void lib_relocate_do(Main *bmain,
BLI_assert(old_id);
BLI_addtail(which_libbase(bmain, GS(old_id->name)), old_id);
+
+ /* Usual special code for ShapeKeys snowflakes... */
+ Key *old_key = BKE_key_from_id(old_id);
+ if (old_key != NULL) {
+ BLI_addtail(which_libbase(bmain, GS(old_key->id.name)), &old_key->id);
+ }
}
/* Since our (old) reloaded IDs were removed from main, the user count done for them in linking
@@ -773,82 +874,20 @@ static void lib_relocate_do(Main *bmain,
ID *old_id = item->customdata;
ID *new_id = item->new_id;
- BLI_assert(old_id);
- if (do_reload) {
- /* Since we asked for placeholders in case of missing IDs,
- * we expect to always get a valid one. */
- BLI_assert(new_id);
- }
- if (new_id) {
-#ifdef PRINT_DEBUG
- printf("before remap of %s, old_id users: %d, new_id users: %d\n",
- old_id->name,
- old_id->us,
- new_id->us);
-#endif
- BKE_libblock_remap_locked(bmain, old_id, new_id, remap_flags);
-
- if (old_id->flag & LIB_FAKEUSER) {
- id_fake_user_clear(old_id);
- id_fake_user_set(new_id);
- }
-
-#ifdef PRINT_DEBUG
- printf("after remap of %s, old_id users: %d, new_id users: %d\n",
- old_id->name,
- old_id->us,
- new_id->us);
-#endif
-
- /* In some cases, new_id might become direct link, remove parent of library in this case. */
- if (new_id->lib->parent && (new_id->tag & LIB_TAG_INDIRECT) == 0) {
- if (do_reload) {
- BLI_assert(0); /* Should not happen in 'pure' reload case... */
- }
- new_id->lib->parent = NULL;
- }
+ lib_relocate_do_remap(bmain, old_id, new_id, reports, do_reload, remap_flags);
+ /* Usual special code for ShapeKeys snowflakes... */
+ Key **old_key_p = BKE_key_from_id_p(old_id);
+ if (old_key_p == NULL) {
+ continue;
}
-
- if (old_id->us > 0 && new_id && old_id->lib == new_id->lib) {
- /* Note that this *should* not happen - but better be safe than sorry in this area,
- * at least until we are 100% sure this cannot ever happen.
- * Also, we can safely assume names were unique so far,
- * so just replacing '.' by '~' should work,
- * but this does not totally rules out the possibility of name collision. */
- size_t len = strlen(old_id->name);
- size_t dot_pos;
- bool has_num = false;
-
- for (dot_pos = len; dot_pos--;) {
- char c = old_id->name[dot_pos];
- if (c == '.') {
- break;
- }
- else if (c < '0' || c > '9') {
- has_num = false;
- break;
- }
- has_num = true;
- }
-
- if (has_num) {
- old_id->name[dot_pos] = '~';
- }
- else {
- len = MIN2(len, MAX_ID_NAME - 7);
- BLI_strncpy(&old_id->name[len], "~000", 7);
- }
-
- id_sort_by_name(which_libbase(bmain, GS(old_id->name)), old_id, NULL);
-
- BKE_reportf(
- reports,
- RPT_WARNING,
- "Lib Reload: Replacing all references to old data-block '%s' by reloaded one failed, "
- "old one (%d remaining users) had to be kept and was renamed to '%s'",
- new_id->name,
- old_id->us,
- old_id->name);
+ Key *old_key = *old_key_p;
+ Key *new_key = BKE_key_from_id(new_id);
+ if (old_key != NULL) {
+ *old_key_p = NULL;
+ id_us_min(&old_key->id);
+ lib_relocate_do_remap(bmain, &old_key->id, &new_key->id, reports, do_reload, remap_flags);
+ *old_key_p = old_key;
+ id_us_plus_no_lib(&old_key->id);
}
}
@@ -900,6 +939,23 @@ static void lib_relocate_do(Main *bmain,
}
}
+ /* Update overrides of reloaded linked data-blocks.
+ * Note that this will not necessarily fully update the override, it might need to be manually
+ * 're-generated' depending on changes in linked data. */
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ if (ID_IS_LINKED(id) || !ID_IS_OVERRIDE_LIBRARY_REAL(id) ||
+ (id->tag & LIB_TAG_PRE_EXISTING) == 0) {
+ continue;
+ }
+ if (id->override_library->reference->lib == library) {
+ BKE_lib_override_library_update(bmain, id);
+ }
+ }
+ FOREACH_MAIN_ID_END;
+
+ BKE_main_collection_sync(bmain);
+
BKE_main_lib_objects_recalc_all(bmain);
IMB_colormanagement_check_file_config(bmain);
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 6b2a74138c9..5a66cbd10eb 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -209,7 +209,7 @@ static void wm_gesture_draw_line(wmGesture *gt)
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
- glGetFloatv(GL_VIEWPORT, viewport_size);
+ GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
immUniform1i("colors_len", 2); /* "advanced" mode */
@@ -252,7 +252,7 @@ static void wm_gesture_draw_rect(wmGesture *gt)
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
- glGetFloatv(GL_VIEWPORT, viewport_size);
+ GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
immUniform1i("colors_len", 2); /* "advanced" mode */
@@ -291,7 +291,7 @@ static void wm_gesture_draw_circle(wmGesture *gt)
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
- glGetFloatv(GL_VIEWPORT, viewport_size);
+ GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
immUniform1i("colors_len", 2); /* "advanced" mode */
@@ -355,39 +355,22 @@ static void draw_filled_lasso(wmGesture *gt)
/* Additive Blending */
GPU_blend(true);
- glBlendFunc(GL_ONE, GL_ONE);
-
- GLint unpack_alignment;
- glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment);
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ GPU_blend_set_func(GPU_ONE, GPU_ONE);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_bind(state.shader);
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(&state,
- rect.xmin,
- rect.ymin,
- w,
- h,
- GL_RED,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
- pixel_buf,
- 1.0f,
- 1.0f,
- NULL);
+ immDrawPixelsTex(
+ &state, rect.xmin, rect.ymin, w, h, GL_R8, false, pixel_buf, 1.0f, 1.0f, NULL);
GPU_shader_unbind();
- glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment);
-
MEM_freeN(pixel_buf);
GPU_blend(false);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
}
MEM_freeN(mcoords);
@@ -415,7 +398,7 @@ static void wm_gesture_draw_lasso(wmGesture *gt, bool filled)
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
- glGetFloatv(GL_VIEWPORT, viewport_size);
+ GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
immUniform1i("colors_len", 2); /* "advanced" mode */
@@ -449,7 +432,7 @@ static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
float viewport_size[4];
- glGetFloatv(GL_VIEWPORT, viewport_size);
+ GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
immUniform1i("colors_len", 2); /* "advanced" mode */
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index cb5a039765a..85694dec9c8 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -59,6 +59,7 @@
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_icons.h"
+#include "BKE_image.h"
#include "BKE_keyconfig.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
@@ -120,7 +121,6 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "GPU_draw.h"
#include "GPU_init_exit.h"
#include "GPU_material.h"
@@ -171,7 +171,7 @@ void WM_init_state_start_with_console_set(bool value)
*/
static bool opengl_is_init = false;
-void WM_init_opengl(Main *bmain)
+void WM_init_opengl(void)
{
/* must be called only once */
BLI_assert(opengl_is_init == false);
@@ -185,9 +185,6 @@ void WM_init_opengl(Main *bmain)
DRW_opengl_context_create();
GPU_init();
- GPU_set_mipmap(bmain, true);
- GPU_set_linear_mipmap(true);
- GPU_set_anisotropic(U.anisotropic_filter);
GPU_pass_cache_init();
@@ -315,7 +312,7 @@ void WM_init(bContext *C, int argc, const char **argv)
/* sets 3D mouse deadzone */
WM_ndof_deadzone_set(U.ndof_deadzone);
#endif
- WM_init_opengl(G_MAIN);
+ WM_init_opengl();
if (!WM_platform_support_perform_checks()) {
exit(-1);
@@ -351,7 +348,7 @@ void WM_init(bContext *C, int argc, const char **argv)
BKE_material_copybuf_clear();
ED_render_clear_mtex_copybuf();
- // glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ // GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
wm_history_file_read();
@@ -578,7 +575,7 @@ void WM_exit_ex(bContext *C, const bool do_python)
BKE_subdiv_exit();
if (opengl_is_init) {
- GPU_free_unused_buffers();
+ BKE_image_free_unused_gpu_textures();
}
BKE_blender_free(); /* blender.c, does entire library and spacetypes */
@@ -656,13 +653,6 @@ void WM_exit_ex(bContext *C, const bool do_python)
BKE_blender_atexit();
- if (MEM_get_memory_blocks_in_use() != 0) {
- size_t mem_in_use = MEM_get_memory_in_use() + MEM_get_memory_in_use();
- printf("Error: Not freed memory blocks: %u, total unfreed memory %f MB\n",
- MEM_get_memory_blocks_in_use(),
- (double)mem_in_use / 1024 / 1024);
- MEM_printmemlist();
- }
wm_autosave_delete();
BKE_tempdir_session_purge();
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index c10f03f3dab..c9b125901e7 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -86,7 +86,7 @@ struct wmJob {
* This performs the actual parallel work.
* Executed in worker thread(s).
*/
- void (*startjob)(void *, short *stop, short *do_update, float *progress);
+ wm_jobs_start_callback startjob;
/**
* Called if thread defines so (see `do_update` flag), and max once per timer step.
* Executed in main thread.
@@ -344,9 +344,7 @@ void *WM_jobs_customdata_get(wmJob *wm_job)
if (!wm_job->customdata) {
return wm_job->run_customdata;
}
- else {
- return wm_job->customdata;
- }
+ return wm_job->customdata;
}
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void (*free)(void *))
@@ -378,7 +376,7 @@ void WM_jobs_delay_start(wmJob *wm_job, double delay_time)
}
void WM_jobs_callbacks(wmJob *wm_job,
- void (*startjob)(void *, short *, short *, float *),
+ wm_jobs_start_callback startjob,
void (*initjob)(void *),
void (*update)(void *),
void (*endjob)(void *))
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index d7102a1e8af..d7ff2689a86 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -321,9 +321,7 @@ bool WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
return true;
}
- else {
- return false;
- }
+ return false;
}
void WM_keyconfig_clear(wmKeyConfig *keyconf)
@@ -363,7 +361,7 @@ void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname)
WM_keyconfig_update(wm);
BLI_strncpy(U.keyconfigstr, idname, sizeof(U.keyconfigstr));
- if (wm->initialized & WM_KEYCONFIG_IS_INITIALIZED) {
+ if (wm->initialized & WM_KEYCONFIG_IS_INIT) {
U.runtime.is_dirty = true;
}
@@ -448,9 +446,7 @@ bool WM_keymap_remove(wmKeyConfig *keyconf, wmKeyMap *keymap)
return true;
}
- else {
- return false;
- }
+ return false;
}
bool WM_keymap_poll(bContext *C, wmKeyMap *keymap)
@@ -551,9 +547,7 @@ bool WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
WM_keyconfig_update_tag(keymap, NULL);
return true;
}
- else {
- return false;
- }
+ return false;
}
/** \} */
@@ -1122,7 +1116,7 @@ const char *WM_key_event_string(const short type, const bool compact)
if (platform == MACOS) {
return key_event_glyph_or_text(font_id, IFACE_("Cmd"), "\xe2\x8c\x98");
}
- else if (platform == MSWIN) {
+ if (platform == MSWIN) {
return key_event_glyph_or_text(font_id, IFACE_("Win"), "\xe2\x9d\x96");
}
return IFACE_("OS");
diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c
index 650d5bbe015..457cd0f16be 100644
--- a/source/blender/windowmanager/intern/wm_operator_type.c
+++ b/source/blender/windowmanager/intern/wm_operator_type.c
@@ -606,9 +606,7 @@ char *WM_operatortype_description(struct bContext *C,
if (description[0]) {
return description;
}
- else {
- MEM_freeN(description);
- }
+ MEM_freeN(description);
}
}
@@ -621,9 +619,7 @@ char *WM_operatortype_description(struct bContext *C,
if (info && info[0]) {
return BLI_strdup(info);
}
- else {
- return NULL;
- }
+ return NULL;
}
/** \} */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 525f96329b7..6a3f4f6a364 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -864,19 +864,17 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
return ret_value | OPERATOR_PASS_THROUGH;
}
- else {
- /* If we are in init phase, and cannot validate init of modal operations,
- * just fall back to basic exec.
- */
- RNA_property_boolean_set(op->ptr, wait_to_deselect_prop, false);
+ /* If we are in init phase, and cannot validate init of modal operations,
+ * just fall back to basic exec.
+ */
+ RNA_property_boolean_set(op->ptr, wait_to_deselect_prop, false);
- ret_value = op->type->exec(C, op);
- OPERATOR_RETVAL_CHECK(ret_value);
+ ret_value = op->type->exec(C, op);
+ OPERATOR_RETVAL_CHECK(ret_value);
- return ret_value | OPERATOR_PASS_THROUGH;
- }
+ return ret_value | OPERATOR_PASS_THROUGH;
}
- else if (event->type == init_event_type && event->val == KM_RELEASE) {
+ if (event->type == init_event_type && event->val == KM_RELEASE) {
RNA_property_boolean_set(op->ptr, wait_to_deselect_prop, false);
ret_value = op->type->exec(C, op);
@@ -884,7 +882,7 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
return ret_value | OPERATOR_PASS_THROUGH;
}
- else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
const int drag_delta[2] = {
mval[0] - event->mval[0],
mval[1] - event->mval[1],
@@ -895,11 +893,9 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (WM_event_drag_test_with_delta(event, drag_delta)) {
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
- else {
- /* Important not to return anything other than PASS_THROUGH here,
- * otherwise it prevents underlying tweak detection code to work properly. */
- return OPERATOR_PASS_THROUGH;
- }
+ /* Important not to return anything other than PASS_THROUGH here,
+ * otherwise it prevents underlying tweak detection code to work properly. */
+ return OPERATOR_PASS_THROUGH;
}
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
@@ -1151,9 +1147,7 @@ int WM_operator_confirm_or_exec(bContext *C, wmOperator *op, const wmEvent *UNUS
if (confirm) {
return WM_operator_confirm_message(C, op, NULL);
}
- else {
- return op->type->exec(C, op);
- }
+ return op->type->exec(C, op);
}
/* op->invoke, opens fileselect if path property not set, otherwise executes */
@@ -1162,10 +1156,8 @@ int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return WM_operator_call_notest(C, op); /* call exec direct */
}
- else {
- WM_event_add_fileselect(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ WM_event_add_fileselect(C, op);
+ return OPERATOR_RUNNING_MODAL;
}
bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
@@ -2120,7 +2112,7 @@ typedef struct {
int slow_mouse[2];
bool slow_mode;
Dial *dial;
- unsigned int gltex;
+ GPUTexture *texture;
ListBase orig_paintcursors;
bool use_secondary_tex;
void *cursor;
@@ -2224,11 +2216,15 @@ static void radial_control_set_tex(RadialControl *rc)
rc->image_id_ptr.data,
rc->use_secondary_tex,
!ELEM(rc->subtype, PROP_NONE, PROP_PIXEL, PROP_DISTANCE)))) {
- glGenTextures(1, &rc->gltex);
- glBindTexture(GL_TEXTURE_2D, rc->gltex);
- glTexImage2D(
- GL_TEXTURE_2D, 0, GL_R8, ibuf->x, ibuf->y, 0, GL_RED, GL_FLOAT, ibuf->rect_float);
- glBindTexture(GL_TEXTURE_2D, 0);
+
+ rc->texture = GPU_texture_create_nD(
+ ibuf->x, ibuf->y, 0, 2, ibuf->rect_float, GPU_R8, GPU_DATA_FLOAT, 0, false, NULL);
+ GPU_texture_filter_mode(rc->texture, true);
+
+ GPU_texture_bind(rc->texture, 0);
+ GPU_texture_swizzle_set(rc->texture, "111r");
+ GPU_texture_unbind(rc->texture);
+
MEM_freeN(ibuf->rect_float);
MEM_freeN(ibuf);
}
@@ -2264,19 +2260,9 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- if (rc->gltex) {
-
+ if (rc->texture) {
uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, rc->gltex);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- GLint swizzleMask[] = {GL_ZERO, GL_ZERO, GL_ZERO, GL_RED};
- glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
-
/* set up rotation if available */
if (rc->rot_prop) {
rot = RNA_property_float_get(&rc->rot_ptr, rc->rot_prop);
@@ -2284,10 +2270,10 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph
GPU_matrix_rotate_2d(RAD2DEGF(rot));
}
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
immUniformColor3fvAlpha(col, alpha);
- immUniform1i("image", 0);
+ immBindTexture("image", rc->texture);
/* draw textured quad */
immBegin(GPU_PRIM_TRI_FAN, 4);
@@ -2306,6 +2292,8 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph
immEnd();
+ GPU_texture_unbind(rc->texture);
+
/* undo rotation */
if (rc->rot_prop) {
GPU_matrix_pop();
@@ -2326,7 +2314,7 @@ static void radial_control_paint_curve(uint pos, Brush *br, float radius, int li
GPU_line_width(2.0f);
immUniformColor4f(0.8f, 0.8f, 0.8f, 0.85f);
float step = (radius * 2.0f) / (float)line_segments;
- BKE_curvemapping_initialize(br->curve);
+ BKE_curvemapping_init(br->curve);
immBegin(GPU_PRIM_LINES, line_segments * 2);
for (int i = 0; i < line_segments; i++) {
float h1 = BKE_brush_curve_strength_clamped(br, fabsf((i * step) - radius), radius);
@@ -2540,10 +2528,8 @@ static int radial_control_get_path(PointerRNA *ctx_ptr,
if (flags & RC_PROP_ALLOW_MISSING) {
return 1;
}
- else {
- BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name);
- return 0;
- }
+ BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name);
+ return 0;
}
/* check property type */
@@ -2595,13 +2581,12 @@ static int radial_control_get_properties(bContext *C, wmOperator *op)
(RC_PROP_ALLOW_MISSING | RC_PROP_REQUIRE_BOOL))) {
return 0;
}
+
+ if (use_secondary_prop && RNA_property_boolean_get(&use_secondary_ptr, use_secondary_prop)) {
+ data_path = "data_path_secondary";
+ }
else {
- if (use_secondary_prop && RNA_property_boolean_get(&use_secondary_ptr, use_secondary_prop)) {
- data_path = "data_path_secondary";
- }
- else {
- data_path = "data_path_primary";
- }
+ data_path = "data_path_primary";
}
if (!radial_control_get_path(&ctx_ptr, op, data_path, &rc->ptr, &rc->prop, 0, 0)) {
@@ -2668,7 +2653,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op)
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) {
+ if (rc->image_id_ptr.data) {
/* extra check, pointer must be to an ID */
if (!RNA_struct_is_ID(rc->image_id_ptr.type)) {
BKE_report(op->reports, RPT_ERROR, "Pointer from path image_id is not an ID");
@@ -2803,7 +2788,9 @@ static void radial_control_cancel(bContext *C, wmOperator *op)
* new value is displayed in sliders/numfields */
WM_event_add_notifier(C, NC_WINDOW, NULL);
- glDeleteTextures(1, &rc->gltex);
+ if (rc->texture != NULL) {
+ GPU_texture_free(rc->texture);
+ }
MEM_freeN(rc);
}
@@ -2843,171 +2830,169 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even
radial_control_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
- else {
- handled = false;
- switch (event->type) {
- case EVT_ESCKEY:
- case RIGHTMOUSE:
- /* canceled; restore original value */
- radial_control_set_value(rc, rc->initial_value);
- ret = OPERATOR_CANCELLED;
- break;
-
- case LEFTMOUSE:
- case EVT_PADENTER:
- case EVT_RETKEY:
- /* done; value already set */
- RNA_property_update(C, &rc->ptr, rc->prop);
- ret = OPERATOR_FINISHED;
- break;
-
- case MOUSEMOVE:
- if (!has_numInput) {
- if (rc->slow_mode) {
- if (rc->subtype == PROP_ANGLE) {
- float position[2] = {event->x, event->y};
-
- /* calculate the initial angle here first */
- delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
- delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1];
-
- /* precision angle gets calculated from dial and gets added later */
- angle_precision = -0.1f * BLI_dial_angle(rc->dial, position);
- }
- else {
- delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
- delta[1] = 0.0f;
- if (rc->zoom_prop) {
- RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
- delta[0] /= zoom[0];
- }
+ handled = false;
+ switch (event->type) {
+ case EVT_ESCKEY:
+ case RIGHTMOUSE:
+ /* canceled; restore original value */
+ radial_control_set_value(rc, rc->initial_value);
+ ret = OPERATOR_CANCELLED;
+ break;
- dist = len_v2(delta);
+ case LEFTMOUSE:
+ case EVT_PADENTER:
+ case EVT_RETKEY:
+ /* done; value already set */
+ RNA_property_update(C, &rc->ptr, rc->prop);
+ ret = OPERATOR_FINISHED;
+ break;
- delta[0] = event->x - rc->slow_mouse[0];
+ case MOUSEMOVE:
+ if (!has_numInput) {
+ if (rc->slow_mode) {
+ if (rc->subtype == PROP_ANGLE) {
+ float position[2] = {event->x, event->y};
- if (rc->zoom_prop) {
- delta[0] /= zoom[0];
- }
+ /* calculate the initial angle here first */
+ delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
+ delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1];
- dist = dist + 0.1f * (delta[0]);
- }
+ /* precision angle gets calculated from dial and gets added later */
+ angle_precision = -0.1f * BLI_dial_angle(rc->dial, position);
}
else {
- delta[0] = rc->initial_mouse[0] - event->x;
- delta[1] = rc->initial_mouse[1] - event->y;
+ delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
+ delta[1] = 0.0f;
+
if (rc->zoom_prop) {
RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
delta[0] /= zoom[0];
- delta[1] /= zoom[1];
}
- if (rc->subtype == PROP_ANGLE) {
- dist = len_v2(delta);
- }
- else {
- dist = clamp_f(-delta[0], 0.0f, FLT_MAX);
+
+ dist = len_v2(delta);
+
+ delta[0] = event->x - rc->slow_mouse[0];
+
+ if (rc->zoom_prop) {
+ delta[0] /= zoom[0];
}
- }
- /* calculate new value and apply snapping */
- switch (rc->subtype) {
- case PROP_NONE:
- case PROP_DISTANCE:
- case PROP_PIXEL:
- new_value = dist;
- if (snap) {
- new_value = ((int)new_value + 5) / 10 * 10;
- }
- break;
- case PROP_PERCENTAGE:
- new_value = ((dist - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE) /
- WM_RADIAL_CONTROL_DISPLAY_WIDTH) *
- 100.0f;
- if (snap) {
- new_value = ((int)(new_value + 2.5f)) / 5 * 5;
- }
- break;
- case PROP_FACTOR:
- new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) /
- WM_RADIAL_CONTROL_DISPLAY_WIDTH;
- if (snap) {
- new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
- }
- /* Invert new value to increase the factor moving the mouse to the right */
- new_value = 1 - new_value;
- break;
- case PROP_ANGLE:
- new_value = atan2f(delta[1], delta[0]) + (float)M_PI + angle_precision;
- new_value = fmod(new_value, 2.0f * (float)M_PI);
- if (new_value < 0.0f) {
- new_value += 2.0f * (float)M_PI;
- }
- if (snap) {
- new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10);
- }
- break;
- default:
- new_value = dist; /* dummy value, should this ever happen? - campbell */
- break;
+ dist = dist + 0.1f * (delta[0]);
}
-
- /* clamp and update */
- CLAMP(new_value, rc->min_value, rc->max_value);
- radial_control_set_value(rc, new_value);
- rc->current_value = new_value;
- handled = true;
- break;
}
- break;
-
- case EVT_LEFTSHIFTKEY:
- case EVT_RIGHTSHIFTKEY: {
- if (event->val == KM_PRESS) {
- rc->slow_mouse[0] = event->x;
- rc->slow_mouse[1] = event->y;
- rc->slow_mode = true;
+ else {
+ delta[0] = rc->initial_mouse[0] - event->x;
+ delta[1] = rc->initial_mouse[1] - event->y;
+ if (rc->zoom_prop) {
+ RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
+ delta[0] /= zoom[0];
+ delta[1] /= zoom[1];
+ }
if (rc->subtype == PROP_ANGLE) {
- float initial_position[2] = {UNPACK2(rc->initial_mouse)};
- float current_position[2] = {UNPACK2(rc->slow_mouse)};
- rc->dial = BLI_dial_initialize(initial_position, 0.0f);
- /* immediately set the position to get a an initial direction */
- BLI_dial_angle(rc->dial, current_position);
+ dist = len_v2(delta);
}
- handled = true;
- }
- if (event->val == KM_RELEASE) {
- rc->slow_mode = false;
- handled = true;
- if (rc->dial) {
- MEM_freeN(rc->dial);
- rc->dial = NULL;
+ else {
+ dist = clamp_f(-delta[0], 0.0f, FLT_MAX);
}
}
+
+ /* calculate new value and apply snapping */
+ switch (rc->subtype) {
+ case PROP_NONE:
+ case PROP_DISTANCE:
+ case PROP_PIXEL:
+ new_value = dist;
+ if (snap) {
+ new_value = ((int)new_value + 5) / 10 * 10;
+ }
+ break;
+ case PROP_PERCENTAGE:
+ new_value = ((dist - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE) /
+ WM_RADIAL_CONTROL_DISPLAY_WIDTH) *
+ 100.0f;
+ if (snap) {
+ new_value = ((int)(new_value + 2.5f)) / 5 * 5;
+ }
+ break;
+ case PROP_FACTOR:
+ new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / WM_RADIAL_CONTROL_DISPLAY_WIDTH;
+ if (snap) {
+ new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
+ }
+ /* Invert new value to increase the factor moving the mouse to the right */
+ new_value = 1 - new_value;
+ break;
+ case PROP_ANGLE:
+ new_value = atan2f(delta[1], delta[0]) + (float)M_PI + angle_precision;
+ new_value = fmod(new_value, 2.0f * (float)M_PI);
+ if (new_value < 0.0f) {
+ new_value += 2.0f * (float)M_PI;
+ }
+ if (snap) {
+ new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10);
+ }
+ break;
+ default:
+ new_value = dist; /* dummy value, should this ever happen? - campbell */
+ break;
+ }
+
+ /* clamp and update */
+ CLAMP(new_value, rc->min_value, rc->max_value);
+ radial_control_set_value(rc, new_value);
+ rc->current_value = new_value;
+ handled = true;
break;
}
+ break;
+
+ case EVT_LEFTSHIFTKEY:
+ case EVT_RIGHTSHIFTKEY: {
+ if (event->val == KM_PRESS) {
+ rc->slow_mouse[0] = event->x;
+ rc->slow_mouse[1] = event->y;
+ rc->slow_mode = true;
+ if (rc->subtype == PROP_ANGLE) {
+ float initial_position[2] = {UNPACK2(rc->initial_mouse)};
+ float current_position[2] = {UNPACK2(rc->slow_mouse)};
+ rc->dial = BLI_dial_init(initial_position, 0.0f);
+ /* immediately set the position to get a an initial direction */
+ BLI_dial_angle(rc->dial, current_position);
+ }
+ handled = true;
+ }
+ if (event->val == KM_RELEASE) {
+ rc->slow_mode = false;
+ handled = true;
+ if (rc->dial) {
+ MEM_freeN(rc->dial);
+ rc->dial = NULL;
+ }
+ }
+ break;
}
+ }
- /* Modal numinput inactive, try to handle numeric inputs last... */
- if (!handled && event->val == KM_PRESS && handleNumInput(C, &rc->num_input, event)) {
- applyNumInput(&rc->num_input, &numValue);
+ /* Modal numinput inactive, try to handle numeric inputs last... */
+ if (!handled && event->val == KM_PRESS && handleNumInput(C, &rc->num_input, event)) {
+ applyNumInput(&rc->num_input, &numValue);
- if (rc->subtype == PROP_ANGLE) {
- numValue = fmod(numValue, 2.0f * (float)M_PI);
- if (numValue < 0.0f) {
- numValue += 2.0f * (float)M_PI;
- }
+ if (rc->subtype == PROP_ANGLE) {
+ numValue = fmod(numValue, 2.0f * (float)M_PI);
+ if (numValue < 0.0f) {
+ numValue += 2.0f * (float)M_PI;
}
+ }
- CLAMP(numValue, rc->min_value, rc->max_value);
- new_value = numValue;
+ CLAMP(numValue, rc->min_value, rc->max_value);
+ new_value = numValue;
- radial_control_set_value(rc, new_value);
+ radial_control_set_value(rc, new_value);
- rc->current_value = new_value;
- radial_control_update_header(op, C);
- return OPERATOR_RUNNING_MODAL;
- }
+ rc->current_value = new_value;
+ radial_control_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
}
ED_region_tag_redraw(CTX_wm_region(C));
@@ -3919,6 +3904,7 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "CLIP_OT_select_box");
WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_box");
WM_modalkeymap_assign(keymap, "MASK_OT_select_box");
+ WM_modalkeymap_assign(keymap, "PAINT_OT_mask_box_gesture");
WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border");
WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border");
WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border");
diff --git a/source/blender/windowmanager/intern/wm_platform_support.h b/source/blender/windowmanager/intern/wm_platform_support.h
index a8e20f6bcdf..6346f517343 100644
--- a/source/blender/windowmanager/intern/wm_platform_support.h
+++ b/source/blender/windowmanager/intern/wm_platform_support.h
@@ -20,11 +20,8 @@
/** \file
* \ingroup wm
*/
-#ifndef __WM_PLATFORM_SUPPORT_H__
-#define __WM_PLATFORM_SUPPORT_H__
+#pragma once
#include "BLI_sys_types.h"
bool WM_platform_support_perform_checks(void);
-
-#endif
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 948e8d9fb74..d0a70596957 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -58,6 +58,7 @@
#include "BIF_glutil.h"
#include "GPU_context.h"
+#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_init_exit.h"
@@ -309,13 +310,14 @@ static void playanim_toscreen(
CLAMP(offs_x, 0.0f, 1.0f);
CLAMP(offs_y, 0.0f, 1.0f);
- glClearColor(0.1, 0.1, 0.1, 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear_color(0.1, 0.1, 0.1, 0.0);
+ GPU_clear(GPU_COLOR_BIT);
/* checkerboard for case alpha */
if (ibuf->planes == 32) {
GPU_blend(true);
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
imm_draw_box_checker_2d_ex(offs_x,
offs_y,
@@ -333,9 +335,8 @@ static void playanim_toscreen(
offs_y + (ps->draw_flip[1] ? span_y : 0.0f),
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
ibuf->rect,
((ps->draw_flip[0] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_x),
((ps->draw_flip[1] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_y),
@@ -542,7 +543,6 @@ static void build_pict_list_ex(
totframes--;
}
}
- return;
}
static void build_pict_list(PlayState *ps, const char *first, int totframes, int fstep, int fontid)
@@ -1059,8 +1059,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
/* zoom always show entire image */
ps->zoom = MIN2(zoomx, zoomy);
- glViewport(0, 0, ps->win_x, ps->win_y);
- glScissor(0, 0, ps->win_x, ps->win_y);
+ GPU_viewport(0, 0, ps->win_x, ps->win_y);
+ GPU_scissor(0, 0, ps->win_x, ps->win_y);
playanim_gl_matrix();
@@ -1316,13 +1316,13 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
maxwiny = ibuf->y * (1 + (maxwiny / ibuf->y));
}
- glClearColor(0.1, 0.1, 0.1, 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear_color(0.1, 0.1, 0.1, 0.0);
+ GPU_clear(GPU_COLOR_BIT);
int win_x, win_y;
playanim_window_get_size(&win_x, &win_y);
- glViewport(0, 0, win_x, win_y);
- glScissor(0, 0, win_x, win_y);
+ GPU_viewport(0, 0, win_x, win_y);
+ GPU_scissor(0, 0, win_x, win_y);
playanim_gl_matrix();
GHOST_SwapWindowBuffers(g_WS.ghost_window);
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index 8ae343d5eb5..9667ed5b631 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -40,6 +40,7 @@
#include "ED_screen.h"
+#include "GPU_extensions.h"
#include "GPU_immediate.h"
#include "GPU_texture.h"
#include "GPU_viewport.h"
@@ -147,13 +148,6 @@ void wm_stereo3d_draw_topbottom(wmWindow *win, int view)
immUnbindProgram();
}
-static bool wm_stereo3d_quadbuffer_supported(void)
-{
- GLboolean stereo = GL_FALSE;
- glGetBooleanv(GL_STEREO, &stereo);
- return stereo == GL_TRUE;
-}
-
static bool wm_stereo3d_is_fullscreen_required(eStereoDisplayMode stereo_display)
{
return ELEM(stereo_display, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM);
@@ -325,7 +319,7 @@ int wm_stereo3d_set_exec(bContext *C, wmOperator *op)
}
/* pageflip requires a new window to be created with the proper OS flags */
else if ((win_dst = wm_window_copy_test(C, win_src, false, false))) {
- if (wm_stereo3d_quadbuffer_supported()) {
+ if (GPU_stereo_quadbuffer_support()) {
BKE_report(op->reports, RPT_INFO, "Quad-buffer window successfully created");
}
else {
@@ -359,12 +353,11 @@ int wm_stereo3d_set_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
}
- else {
- /* without this, the popup won't be freed freed properly T44688 */
- CTX_wm_window_set(C, win_src);
- win_src->stereo3d_format->display_mode = prev_display_mode;
- return OPERATOR_CANCELLED;
- }
+
+ /* without this, the popup won't be freed freed properly T44688 */
+ CTX_wm_window_set(C, win_src);
+ win_src->stereo3d_format->display_mode = prev_display_mode;
+ return OPERATOR_CANCELLED;
}
int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@@ -374,9 +367,7 @@ int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev
if (wm_stereo3d_set_properties(C, op)) {
return wm_stereo3d_set_exec(C, op);
}
- else {
- return WM_operator_props_dialog_popup(C, op, 250);
- }
+ return WM_operator_props_dialog_popup(C, op, 250);
}
void wm_stereo3d_set_draw(bContext *UNUSED(C), wmOperator *op)
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 5483d79c075..0cb76404258 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -29,7 +29,6 @@
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "GPU_viewport.h"
@@ -40,8 +39,8 @@ void wmViewport(const rcti *winrct)
int width = BLI_rcti_size_x(winrct) + 1;
int height = BLI_rcti_size_y(winrct) + 1;
- glViewport(winrct->xmin, winrct->ymin, width, height);
- glScissor(winrct->xmin, winrct->ymin, width, height);
+ GPU_viewport(winrct->xmin, winrct->ymin, width, height);
+ GPU_scissor(winrct->xmin, winrct->ymin, width, height);
wmOrtho2_pixelspace(width, height);
GPU_matrix_identity_set();
@@ -79,8 +78,8 @@ void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct
scissor_height += 1;
}
- glViewport(0, 0, width, height);
- glScissor(x, y, scissor_width, scissor_height);
+ GPU_viewport(0, 0, width, height);
+ GPU_scissor(x, y, scissor_width, scissor_height);
wmOrtho2_pixelspace(width, height);
GPU_matrix_identity_set();
@@ -91,8 +90,8 @@ void wmWindowViewport(wmWindow *win)
int width = WM_window_pixels_x(win);
int height = WM_window_pixels_y(win);
- glViewport(0, 0, width, height);
- glScissor(0, 0, width, height);
+ GPU_viewport(0, 0, width, height);
+ GPU_scissor(0, 0, width, height);
wmOrtho2_pixelspace(width, height);
GPU_matrix_identity_set();
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index e1b2285313c..e0dcd746aea 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -89,6 +89,7 @@
#include "GPU_init_exit.h"
#include "GPU_platform.h"
#include "GPU_state.h"
+#include "GPU_texture.h"
#include "UI_resources.h"
@@ -354,10 +355,8 @@ wmWindow *wm_window_copy_test(bContext *C,
WM_event_add_notifier_ex(wm, CTX_wm_window(C), NC_WINDOW | NA_ADDED, NULL);
return win_dst;
}
- else {
- wm_window_close(C, wm, win_dst);
- return NULL;
- }
+ wm_window_close(C, wm, win_dst);
+ return NULL;
}
/** \} */
@@ -648,10 +647,10 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
}
#endif
/* until screens get drawn, make it nice gray */
- glClearColor(0.55, 0.55, 0.55, 0.0);
+ GPU_clear_color(0.55, 0.55, 0.55, 1.0f);
/* Crash on OSS ATI: bugs.launchpad.net/ubuntu/+source/mesa/+bug/656100 */
if (!GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) {
- glClear(GL_COLOR_BUFFER_BIT);
+ GPU_clear(GPU_COLOR_BIT);
}
/* needed here, because it's used before it reads userdef */
@@ -812,9 +811,7 @@ static bool wm_window_update_size_position(wmWindow *win)
win->posy = posy;
return true;
}
- else {
- return false;
- }
+ return false;
}
/**
@@ -839,11 +836,10 @@ wmWindow *WM_window_open(bContext *C, const rcti *rect)
if (win->ghostwin) {
return win;
}
- else {
- wm_window_close(C, wm, win);
- CTX_wm_window_set(C, win_prev);
- return NULL;
- }
+
+ wm_window_close(C, wm, win);
+ CTX_wm_window_set(C, win_prev);
+ return NULL;
}
/**
@@ -968,13 +964,12 @@ wmWindow *WM_window_open_temp(bContext *C,
GHOST_SetTitle(win->ghostwin, title);
return win;
}
- else {
- /* very unlikely! but opening a new window can fail */
- wm_window_close(C, wm, win);
- CTX_wm_window_set(C, win_prev);
- return NULL;
- }
+ /* very unlikely! but opening a new window can fail */
+ wm_window_close(C, wm, win);
+ CTX_wm_window_set(C, win_prev);
+
+ return NULL;
}
/* ****************** Operators ****************** */
@@ -1205,7 +1200,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
/* 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) {
+ if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) {
return 1;
}
if (!ghostwin) {
@@ -1214,15 +1209,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
puts("<!> event has no window");
return 1;
}
- else if (!GHOST_ValidWindow(g_system, ghostwin)) {
+ if (!GHOST_ValidWindow(g_system, ghostwin)) {
/* XXX - should be checked, why are we getting an event here, and */
/* what is it? */
puts("<!> event has invalid window");
return 1;
}
- else {
- win = GHOST_GetWindowUserData(ghostwin);
- }
+ win = GHOST_GetWindowUserData(ghostwin);
switch (type) {
case GHOST_kEventWindowDeactivate:
@@ -2054,9 +2047,7 @@ void WM_window_pixel_sample_read(const wmWindowManager *wm,
GPU_context_active_set(win->gpuctx);
}
- glReadBuffer(GL_FRONT);
- glReadPixels(pos[0], pos[1], 1, 1, GL_RGB, GL_FLOAT, r_col);
- glReadBuffer(GL_BACK);
+ GPU_frontbuffer_read_pixels(pos[0], pos[1], 1, 1, 3, GPU_DATA_FLOAT, r_col);
if (setup_context) {
if (wm->windrawable) {
@@ -2089,10 +2080,7 @@ uint *WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2])
const uint rect_len = r_size[0] * r_size[1];
uint *rect = MEM_mallocN(sizeof(*rect) * rect_len, __func__);
- glReadBuffer(GL_FRONT);
- glReadPixels(0, 0, r_size[0], r_size[1], GL_RGBA, GL_UNSIGNED_BYTE, rect);
- glFinish();
- glReadBuffer(GL_BACK);
+ GPU_frontbuffer_read_pixels(0, 0, r_size[0], r_size[1], 4, GPU_DATA_UNSIGNED_BYTE, rect);
if (setup_context) {
if (wm->windrawable) {
diff --git a/source/blender/windowmanager/intern/wm_window_private.h b/source/blender/windowmanager/intern/wm_window_private.h
index 115539861d7..c208d07ee37 100644
--- a/source/blender/windowmanager/intern/wm_window_private.h
+++ b/source/blender/windowmanager/intern/wm_window_private.h
@@ -20,8 +20,7 @@
/** \file
* \ingroup wm
*/
-#ifndef __WM_WINDOW_PRIVATE_H__
-#define __WM_WINDOW_PRIVATE_H__
+#pragma once
#include "BLI_sys_types.h"
#include "GHOST_Types.h"
@@ -38,5 +37,3 @@ void WM_ghost_show_message_box(const char *title,
const char *continue_label,
const char *link,
GHOST_DialogOptions dialog_options);
-
-#endif
diff --git a/source/blender/windowmanager/message_bus/intern/wm_message_bus_intern.h b/source/blender/windowmanager/message_bus/intern/wm_message_bus_intern.h
index ccf7034e3e0..24c0192fe14 100644
--- a/source/blender/windowmanager/message_bus/intern/wm_message_bus_intern.h
+++ b/source/blender/windowmanager/message_bus/intern/wm_message_bus_intern.h
@@ -18,8 +18,7 @@
* \ingroup wm
*/
-#ifndef __WM_MESSAGE_BUS_INTERN_H__
-#define __WM_MESSAGE_BUS_INTERN_H__
+#pragma once
#include "../wm_message_bus.h"
@@ -47,5 +46,3 @@ BLI_INLINE wmMsg *wm_msg_subscribe_value_msg_cast_mut(wmMsgSubscribeKey *key)
{
return &((wmMsgSubscribeKey_Generic *)key)->msg;
}
-
-#endif /* __WM_MESSAGE_BUS_INTERN_H__ */
diff --git a/source/blender/windowmanager/message_bus/wm_message_bus.h b/source/blender/windowmanager/message_bus/wm_message_bus.h
index 8020be3017a..23a53eace52 100644
--- a/source/blender/windowmanager/message_bus/wm_message_bus.h
+++ b/source/blender/windowmanager/message_bus/wm_message_bus.h
@@ -18,8 +18,7 @@
* \ingroup wm
*/
-#ifndef __WM_MESSAGE_BUS_H__
-#define __WM_MESSAGE_BUS_H__
+#pragma once
#include "RNA_types.h"
#include <stdio.h>
@@ -34,6 +33,10 @@ struct wmMsgSubscribeKey;
struct wmMsgSubscribeValue;
struct wmMsgSubscribeValueLink;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef void (*wmMsgNotifyFn)(struct bContext *C,
struct wmMsgSubscribeKey *msg_key,
struct wmMsgSubscribeValue *msg_val);
@@ -287,4 +290,6 @@ void WM_msg_publish_ID(struct wmMsgBus *mbus, struct ID *id);
} \
((void)0)
-#endif /* __WM_MESSAGE_BUS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 16aa5cb44db..baa47098bd3 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -21,8 +21,7 @@
* \ingroup wm
*/
-#ifndef __WM_H__
-#define __WM_H__
+#pragma once
struct ARegion;
struct ReportList;
@@ -30,6 +29,10 @@ struct wmWindow;
#include "gizmo/wm_gizmo_wmapi.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct wmPaintCursor {
struct wmPaintCursor *next, *prev;
@@ -97,4 +100,6 @@ void wm_stereo3d_set_cancel(bContext *C, wmOperator *op);
void wm_open_init_load_ui(wmOperator *op, bool use_prefs);
void wm_open_init_use_scripts(wmOperator *op, bool use_prefs);
+#ifdef __cplusplus
+}
#endif
diff --git a/source/blender/windowmanager/wm_cursors.h b/source/blender/windowmanager/wm_cursors.h
index 7a28aeb3c70..b85616deda5 100644
--- a/source/blender/windowmanager/wm_cursors.h
+++ b/source/blender/windowmanager/wm_cursors.h
@@ -21,12 +21,15 @@
* \ingroup wm
*/
-#ifndef __WM_CURSORS_H__
-#define __WM_CURSORS_H__
+#pragma once
struct wmEvent;
struct wmWindow;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef enum WMCursorType {
WM_CURSOR_DEFAULT = 1,
WM_CURSOR_TEXT_EDIT,
@@ -77,4 +80,6 @@ typedef enum WMCursorType {
void wm_init_cursor_data(void);
bool wm_cursor_arrow_move(struct wmWindow *win, const struct wmEvent *event);
-#endif /* __WM_CURSORS_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h
index ff2fc25333a..4997361b485 100644
--- a/source/blender/windowmanager/wm_draw.h
+++ b/source/blender/windowmanager/wm_draw.h
@@ -21,15 +21,16 @@
* \ingroup wm
*/
-#ifndef __WM_DRAW_H__
-#define __WM_DRAW_H__
-
-#include "GPU_glew.h"
+#pragma once
struct GPUOffScreen;
struct GPUTexture;
struct GPUViewport;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct wmDrawBuffer {
struct GPUOffScreen *offscreen;
struct GPUViewport *viewport;
@@ -50,4 +51,6 @@ void wm_draw_region_test(struct bContext *C, struct ScrArea *area, struct ARegio
struct GPUTexture *wm_draw_region_texture(struct ARegion *region, int view);
-#endif /* __WM_DRAW_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index efcf40d03eb..787c840de8a 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -21,8 +21,7 @@
* \ingroup wm
*/
-#ifndef __WM_EVENT_SYSTEM_H__
-#define __WM_EVENT_SYSTEM_H__
+#pragma once
/* return value of handler-operator call */
#define WM_HANDLER_CONTINUE 0
@@ -34,6 +33,10 @@ struct ARegion;
struct GHOST_TabletData;
struct ScrArea;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* wmKeyMap is in DNA_windowmanager.h, it's saveable */
/** Custom types for handlers, for signaling, freeing */
@@ -165,4 +168,6 @@ void wm_dropbox_free(void);
void wm_drags_check_ops(bContext *C, const wmEvent *event);
void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect);
-#endif /* __WM_EVENT_SYSTEM_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index ffed86abfe7..ed8f39fea48 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -23,8 +23,11 @@
* Blender copied the conventions quite some, and expanded it with internal new defines (ton)
*/
-#ifndef __WM_EVENT_TYPES_H__
-#define __WM_EVENT_TYPES_H__
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
/* customdata type */
enum {
@@ -489,4 +492,6 @@ enum {
GESTURE_MODAL_CIRCLE_SIZE = 11,
};
-#endif /* __WM_EVENT_TYPES_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h
index 42eab35cdb9..d54090a6025 100644
--- a/source/blender/windowmanager/wm_files.h
+++ b/source/blender/windowmanager/wm_files.h
@@ -21,13 +21,16 @@
* \ingroup wm
*/
-#ifndef __WM_FILES_H__
-#define __WM_FILES_H__
+#pragma once
struct Main;
struct wmGenericCallback;
struct wmOperatorType;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* wm_files.c */
void wm_history_file_read(void);
void wm_homefile_read(struct bContext *C,
@@ -68,4 +71,6 @@ void WM_OT_append(struct wmOperatorType *ot);
void WM_OT_lib_relocate(struct wmOperatorType *ot);
void WM_OT_lib_reload(struct wmOperatorType *ot);
-#endif /* __WM_FILES_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/wm_surface.h b/source/blender/windowmanager/wm_surface.h
index bc1cc825e4b..06c29231361 100644
--- a/source/blender/windowmanager/wm_surface.h
+++ b/source/blender/windowmanager/wm_surface.h
@@ -22,11 +22,14 @@
* Container to manage painting in an offscreen context.
*/
-#ifndef __WM_SURFACE_H__
-#define __WM_SURFACE_H__
+#pragma once
struct bContext;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct wmSurface {
struct wmSurface *next, *prev;
@@ -59,4 +62,6 @@ void wm_surface_clear_drawable(void);
void wm_surface_set_drawable(wmSurface *surface, bool activate);
void wm_surface_reset_drawable(void);
-#endif /* __WM_SURFACE_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 5ca5711b4f2..336db7edb50 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -21,11 +21,14 @@
* \ingroup wm
*/
-#ifndef __WM_WINDOW_H__
-#define __WM_WINDOW_H__
+#pragma once
struct wmOperator;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* *************** internal api ************** */
void wm_ghost_init(bContext *C);
void wm_ghost_exit(void);
@@ -85,4 +88,6 @@ int wm_window_new_main_exec(bContext *C, struct wmOperator *op);
void wm_test_autorun_warning(bContext *C);
-#endif /* __WM_WINDOW_H__ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_intern.h b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
index 9b7e9a15948..9b7b81f769a 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_intern.h
+++ b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
@@ -18,8 +18,7 @@
* \ingroup wm
*/
-#ifndef __WM_XR_INTERN_H__
-#define __WM_XR_INTERN_H__
+#pragma once
#include "CLG_log.h"
@@ -92,5 +91,3 @@ void wm_xr_session_gpu_binding_context_destroy(GHOST_ContextHandle context);
void wm_xr_pose_to_viewmat(const GHOST_XrPose *pose, float r_viewmat[4][4]);
void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata);
-
-#endif
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index 1baac10dbd8..b44f006cde8 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -41,8 +41,8 @@
#include "wm_window.h"
#include "wm_xr_intern.h"
-wmSurface *g_xr_surface = NULL;
-CLG_LogRef LOG = {"wm.xr"};
+static wmSurface *g_xr_surface = NULL;
+static CLG_LogRef LOG = {"wm.xr"};
/* -------------------------------------------------------------------- */
@@ -159,6 +159,13 @@ static void wm_xr_session_draw_data_populate(wmXrData *xr_data,
wm_xr_session_base_pose_calc(r_draw_data->scene, settings, &r_draw_data->base_pose);
}
+typedef enum wmXrSessionStateEvent {
+ SESSION_STATE_EVENT_NONE = 0,
+ SESSION_STATE_EVENT_START,
+ SESSION_STATE_EVENT_RESET_TO_BASE_POSE,
+ SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE,
+} wmXrSessionStateEvent;
+
static bool wm_xr_session_draw_data_needs_reset_to_base_pose(const wmXrSessionState *state,
const XrSessionSettings *settings)
{
@@ -170,36 +177,63 @@ static bool wm_xr_session_draw_data_needs_reset_to_base_pose(const wmXrSessionSt
(state->prev_base_pose_object != settings->base_pose_object));
}
+static wmXrSessionStateEvent wm_xr_session_state_to_event(const wmXrSessionState *state,
+ const XrSessionSettings *settings)
+{
+ if (!state->is_view_data_set) {
+ return SESSION_STATE_EVENT_START;
+ }
+ if (wm_xr_session_draw_data_needs_reset_to_base_pose(state, settings)) {
+ return SESSION_STATE_EVENT_RESET_TO_BASE_POSE;
+ }
+
+ const bool position_tracking_toggled = ((state->prev_settings_flag &
+ XR_SESSION_USE_POSITION_TRACKING) !=
+ (settings->flag & XR_SESSION_USE_POSITION_TRACKING));
+ if (position_tracking_toggled) {
+ return SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE;
+ }
+
+ return SESSION_STATE_EVENT_NONE;
+}
+
void wm_xr_session_draw_data_update(const wmXrSessionState *state,
const XrSessionSettings *settings,
const GHOST_XrDrawViewInfo *draw_view,
wmXrDrawData *draw_data)
{
- const bool position_tracking_toggled = ((state->prev_settings_flag &
- XR_SESSION_USE_POSITION_TRACKING) !=
- (settings->flag & XR_SESSION_USE_POSITION_TRACKING));
- const bool use_position_tracking = settings->flag & XR_SESSION_USE_POSITION_TRACKING;
+ const wmXrSessionStateEvent event = wm_xr_session_state_to_event(state, settings);
+ const bool use_position_tracking = (settings->flag & XR_SESSION_USE_POSITION_TRACKING);
- /* Set the eye position offset, it's used to offset the base pose when changing positional
- * tracking. */
- if (!state->is_view_data_set ||
- wm_xr_session_draw_data_needs_reset_to_base_pose(state, settings)) {
- /* Always use the exact base pose with no offset when starting the session. */
- copy_v3_fl(draw_data->eye_position_ofs, 0.0f);
- }
- else if (position_tracking_toggled) {
- if (use_position_tracking) {
+ switch (event) {
+ case SESSION_STATE_EVENT_START:
+ /* Always use the exact base pose with no offset when starting the session. */
copy_v3_fl(draw_data->eye_position_ofs, 0.0f);
- }
- else {
- /* Store the current local offset (local pose) so that we can apply that to the eyes. This
- * way the eyes stay exactly where they are when disabling positional tracking. */
- copy_v3_v3(draw_data->eye_position_ofs, draw_view->local_pose.position);
- }
- }
- else if (!use_position_tracking) {
- /* Keep previous offset when positional tracking is disabled. */
- copy_v3_v3(draw_data->eye_position_ofs, state->prev_eye_position_ofs);
+ break;
+ /* This should be triggered by the VR add-on if a landmark changes. */
+ case SESSION_STATE_EVENT_RESET_TO_BASE_POSE:
+ if (use_position_tracking) {
+ /* Switch exactly to base pose, so use eye offset to cancel out current position delta. */
+ copy_v3_v3(draw_data->eye_position_ofs, draw_view->local_pose.position);
+ }
+ else {
+ copy_v3_fl(draw_data->eye_position_ofs, 0.0f);
+ }
+ break;
+ case SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE:
+ if (use_position_tracking) {
+ /* Keep the current position, and let the user move from there. */
+ copy_v3_v3(draw_data->eye_position_ofs, state->prev_eye_position_ofs);
+ }
+ else {
+ /* Back to the exact base-pose position. */
+ copy_v3_fl(draw_data->eye_position_ofs, 0.0f);
+ }
+ break;
+ case SESSION_STATE_EVENT_NONE:
+ /* Keep previous offset when positional tracking is disabled. */
+ copy_v3_v3(draw_data->eye_position_ofs, state->prev_eye_position_ofs);
+ break;
}
}
@@ -243,6 +277,8 @@ void wm_xr_session_state_update(const XrSessionSettings *settings,
state->prev_base_pose_type = settings->base_pose_type;
state->prev_base_pose_object = settings->base_pose_object;
state->is_view_data_set = true;
+ /* Assume this was already done through wm_xr_session_draw_data_update(). */
+ state->force_reset_to_base_pose = false;
}
wmXrSessionState *WM_xr_session_state_handle_get(const wmXrData *xr)
@@ -299,9 +335,9 @@ bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr,
/**
* \brief Call Ghost-XR to draw a frame
*
- * Draw callback for the XR-session surface. It's expected to be called on each main loop iteration
- * and tells Ghost-XR to submit a new frame by drawing its views. Note that for drawing each view,
- * #wm_xr_draw_view() will be called through Ghost-XR (see GHOST_XrDrawViewFunc()).
+ * Draw callback for the XR-session surface. It's expected to be called on each main loop
+ * iteration and tells Ghost-XR to submit a new frame by drawing its views. Note that for drawing
+ * each view, #wm_xr_draw_view() will be called through Ghost-XR (see GHOST_XrDrawViewFunc()).
*/
static void wm_xr_session_surface_draw(bContext *C)
{
diff --git a/source/blender/windowmanager/xr/wm_xr.h b/source/blender/windowmanager/xr/wm_xr.h
index 33f79bc75b2..886f1315e8c 100644
--- a/source/blender/windowmanager/xr/wm_xr.h
+++ b/source/blender/windowmanager/xr/wm_xr.h
@@ -18,8 +18,7 @@
* \ingroup wm
*/
-#ifndef __WM_XR_H__
-#define __WM_XR_H__
+#pragma once
struct wmWindowManager;
struct wmXrData;
@@ -31,5 +30,3 @@ bool wm_xr_init(wmWindowManager *wm);
void wm_xr_exit(wmWindowManager *wm);
void wm_xr_session_toggle(wmWindowManager *wm, wmXrSessionExitFn session_exit_fn);
bool wm_xr_events_handle(wmWindowManager *wm);
-
-#endif